31#ifndef DRAIN_DICTIONARY
32#define DRAIN_DICTIONARY "Dictionary v2.0"
41#include <drain/Sprinter.h>
62template <
class K,
class V>
70 typedef std::pair<K, V> entry_t;
71 typedef std::list<entry_t> container_t;
73 typedef std::list<key_t> keylist_t;
74 typedef std::list<value_t> valuelist_t;
81 Dictionary(std::initializer_list<entry_t> d) : std::list<entry_t>(d), separator(
','){
89 const container_t & getContainer()
const {
93 entry_t & add(
const K & key,
const V & value){
94 this->push_back(entry_t(key, value));
99 entry_t &
set(
const K & key,
const V & value){
100 for (entry_t & entry: *
this){
101 if (entry.first == key){
102 entry.second = value;
106 this->push_back(entry_t(key, value));
110 const V & operator[](
const K & key)
const {
114 const V & operator()(
const V & value)
const {
119 typename container_t::const_iterator findByKey(
const K & key)
const {
120 for (
typename container_t::const_iterator it = this->begin(); it != this->end(); ++it){
121 if (it->first == key)
127 typename container_t::const_iterator findByValue(
const V & value)
const {
128 for (
typename container_t::const_iterator it = this->begin(); it != this->end(); ++it){
129 if (it->second == value)
137 bool hasKey(
const K & key)
const {
138 return (findByKey(key) != this->end());
144 return (findByValue(value) != this->end());
149 const V &
getValue(
const K & key,
bool lenient=
true)
const {
150 typename container_t::const_iterator it = findByKey(key);
151 if (it != this->end())
172 const K &
getKey(
const V & value,
bool lenient=
true)
const {
173 typename container_t::const_iterator it = findByValue(value);
174 if (it != this->end())
181 for (
const auto & entry: *
this){
182 std::cerr <<
"'" << entry.first <<
"' = '" << entry.second <<
"'\n";
190 const keylist_t & getKeys()
const {
195 for (
const entry_t & entry: *this){
196 keyList.push_back(entry.first);
202 void getKeys(keylist_t & l)
const {
203 for (
const entry_t & entry: *this){
204 l.push_back(entry.first);
209 const valuelist_t & getValues()
const {
214 for (
const entry_t & entry: *this){
215 valueList.push_back(entry.second);
221 void getValues(keylist_t & l)
const {
222 for (
const entry_t & entry: *this){
223 l.push_back(entry.second);
235 valuelist_t valueList;
249template <
class K,
class V>
251std::ostream & operator<<(std::ostream & ostr,
const Dictionary<K,V> & dict) {
254 static const SprinterLayout cmdArgLayout = {
",",
"?",
"=",
""};
257 ostr << drain::sprinter(dict.getContainer(), cmdArgLayout);
273template <
class K,
class V>
286 void add(
const K & key,
const V & value){
290 typename parent_t::container_t::const_iterator findByValue(
const V & value)
const {
291 return parent_t::findByValue(& value);
295 const V & getValue(
const K & key)
const {
300 const K & getKey(
const V & value)
const {
Associates type info.
Definition Dictionary.h:274
Two-way mapping between strings and objects of template class T.
Definition Dictionary.h:63
const K & getKey(const V &value, bool lenient=true) const
Identity mapping useful for type deduction of template arguments in functions.
Definition Dictionary.h:172
const V & getValue(const K &key, bool lenient=true) const
Given a key, return the first value associated with it.
Definition Dictionary.h:149
bool hasValue(const V &value) const
Given a key, return the first value associated with it.
Definition Dictionary.h:143
entry_t & set(const K &key, const V &value)
Replaces existing or adds.
Definition Dictionary.h:99
static std::ostream & sequenceToStream(std::ostream &ostr, const T &x, const SprinterLayout &layout)
Convenience: if sequence type (array, list, set, map) not given, assume array.
Definition Sprinter.h:321
static const SprinterLayout lineLayout
Put each array and object element on a separate line.
Definition Sprinter.h:212
Definition StringBuilder.h:58
Definition DataSelector.cpp:1277