SmartMap.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 #ifndef SMARTMAP_H
32 #define SMARTMAP_H
33 
34 #include <drain/Log.h>
35 #include <iostream>
36 #include <string>
37 #include <set>
38 #include <list>
39 #include <vector>
40 #include <map>
41 #include <sys/syslog.h>
42 #include <syslog.h>
43 
44 #include <drain/Castable.h>
45 #include <drain/SmartMapTools.h>
46 #include <drain/Sprinter.h>
47 #include <drain/String.h>
48 
49 
50 
51 // TODO: use SmartMapTools for assignments
52 
53 namespace drain {
54 
56 
65 template<class T>
66 class SmartMap : public std::map<std::string, T> {
67 
68 public:
69 
70  typedef SmartMap<T> smap_t;
71 
72  typedef std::map<std::string, T> map_t;
73  typedef typename map_t::key_type key_t;
74  typedef typename map_t::mapped_type value_t; // == T
75  typedef typename map_t::value_type entry_t; // pair<key_t,value_t>
76 
77  typedef std::list<std::string> keylist_t;
78 
80  typedef typename map_t::iterator iterator;
81  typedef typename map_t::const_iterator const_iterator;
82 
83 
85  char separator;
86 
89 
94  inline
96 
97  // Copy constructor. Does not copy items.
100  inline
101  SmartMap(const SmartMap & smap) : separator(smap.separator), arraySeparator(smap.arraySeparator){};
102 
103 
104  virtual
105  inline
106  ~SmartMap(){};
107 
108 
109  virtual inline
110  void clear(){
111  map_t::clear();
112  keyList.clear();
113  }
114 
115  inline
116  bool hasKey(const std::string &key) const {
117  return (this->find(key) != this->end());
118  }
119 
121 
126  inline
127  std::string get(const std::string &key, const std::string & defaultValue) const {
128  const_iterator it = this->find(key);
129  if (it == this->end())
130  return defaultValue;
131  else {
132  // return static_cast<std::string>(it->second); DOES NOT WORK, http://stackoverflow.com/questions/7741531/conversion-operator-template-specialization
133  return it->second;
134  }
135  }
136 
137 
138  inline
139  std::string get(const std::string & key, const char *defaultValue) const {
140  return get(key, std::string(defaultValue));
141  }
142 
143 
145 
150  template <class T2>
151  T2 get(const std::string &key, const T2 &defaultValue) const { //T2 defaultValue) const {
152  const_iterator it = this->find(key);
153  if (it == this->end())
154  return defaultValue;
155  else
156  return static_cast<T2>(it->second);
157  }
158 
160 
165  inline
166  virtual
167  T & operator[](const std::string &key){
168 
169  iterator it = this->find(key);
170  if (it != this->end()) {
171  return it->second;
172  }
173  else {
174  // Create:
175  keyList.push_back(key);
176  T & element = map_t::operator[](key);
177  //element.setSeparator(arraySeparator);
178  return element;
179  }
180  }
181 
183  inline
184  virtual
185  const T & operator[](const std::string &key) const {
186 
187  const_iterator it = this->find(key);
188  if (it != this->end()) {
189  return it->second;
190  }
191  else {
192  static const T empty;
193  return empty;
194  }
195  }
196 
197 
199  virtual inline
200  const keylist_t & getKeyList() const {
201  return keyList;
202  }
203 
204 
205  inline
206  const map_t & getMap() const {
207  return *this;
208  };
209 
211  template <class T2>
212  void exportMap(std::map<std::string,T2> & m) const {
213  for (const_iterator it = this->begin(); it != this->end(); ++it)
214  m[it->first] = it->second;
215  }
216 
218 
221  /*
222  template <class V,bool STRICT=false> // TODO: true...
223  //void importEntry(const std::string & key, const T2 & value, bool updateOnly = true){
224  void importEntry(const std::string & key, const V & value){ //, bool updateOnly = true) { //, unsigned int criticality = LOG_DEBUG){
225  */
226 
230  template <bool STRICT=true>
231  void importEntries(const std::string & entries, char assignmentSymbol='=', char separatorSymbol=0); //, bool updateOnly = false);
232  //, unsigned int criticality = LOG_ERR);
233 
234 
239  template <bool STRICT=true>
240  void importEntries(const std::list<std::string> & entries, char assignmentSymbol='='){ //; //, bool updateOnly = false);
241  //SmartMapTools::setValues<T,STRICT>(*this, getKeyList(), entries, assignmentSymbol);
242  SmartMapTools::setValues<smap_t,STRICT>(*this, getKeyList(), entries, assignmentSymbol);
243  }
244 
246 
251  template <class S,bool STRICT=true>
252  void importMap(const std::map<std::string,S> & m){ //, bool updateOnly = false){ //, unsigned int criticality = LOG_ERR){
253  // SmartMapTools::setValues<map_t,S,STRICT>(*this, m);
254  // SmartMapTools::setValues(*this, m);
255  SmartMapTools::setValues<smap_t,S,STRICT>(*this, m);
256  //new
257  //for (typename std::map<std::string,S>::const_iterator it = m.begin(); it != m.end(); ++it)
258  // importEntry(it->first, it->second); //, updateOnly); //, criticality); // false);
259 
260  }
261 
263 
270  template <class T2,bool STRICT=true>
271  void importCastableMap(const drain::SmartMap<T2> & m){ //, bool updateOnly = false, unsigned int criticality = LOG_ERR){
272  // NUOEVO:
273  SmartMapTools::setCastableValues<smap_t,T2,STRICT>(*this, m);
274  // SmartMapTools::setValues<smap_t,T2,STRICT>(*this, m);
275  //SmartMapTools::setValues<map_t,T2,STRICT>(*this, m);
276  /*
277  for (const typename SmartMap<T2>::keylist_t::value_type &key : m.getKeyList()){
278  importEntry(key, (const Castable &)m[key]); //, updateOnly);
279  }
280  */
281  // for (typename SmartMap<T2>::const_iterator it = m.begin(); it != m.end(); ++it)
282  // importEntry(it->first, (const Castable &)it->second, updateOnly); //, criticality); // false);
283  }
284 
285 
286 
288 
292  template <class T2>
293  inline
294  void updateFromMap(const std::map<std::string,T2> & m){
295  importMap<T2,false>(m); //, LOG_DEBUG);
296  }
297 
299  template <class T2>
300  inline
302  importCastableMap<T2,false>(m); //, true);
303  // for (typename SmartMap<T2>::const_iterator it = m.begin(); it != m.end(); ++it)
304  // importEntry(it->first, (const Castable &)it->second, LOG_DEBUG); //true);
305  }
306 
307 
309  // TODO: consider: std::string assignmentSymbols="=:", std::string separatorSymbols=", ", std::string trimSymbols=" \t\n\r",
310  inline
311  void setValues(const std::string & entries, char assignmentSymbol='=', char separatorSymbol=0){ // char separatorSymbol=','
312  importEntries<true>(entries, assignmentSymbol, separatorSymbol); //, false); //, LOG_ERR);
313  }
314 
315  inline
316  void setValues(const char * entries, char assignmentSymbol='=', char separatorSymbol=0){
317  importEntries<true>(entries, assignmentSymbol, separatorSymbol); //, false); //, LOG_ERR);
318  }
319 
320  // status?
321  template <class S>
322  void setValuesSEQ(const S & sequence);
323 
325  inline
326  void updateValues(const std::string & entries, char assignmentSymbol='=', char separatorSymbol=0){// char separatorSymbol=','
327  importEntries<false>(entries, assignmentSymbol, separatorSymbol); //, true); //, LOG_DEBUG);
328  }
329 
330 
331  inline
332  void getKeys(std::ostream &ostr) const {
333 
334  const keylist_t & l = getKeyList();
335  for (keylist_t::const_iterator it = l.begin(); it != l.end(); ++it ){
336  if (it != l.begin())
337  ostr << ',';
338  ostr << *it;
339  }
340 
341  }
342 
344  inline
345  std::string getKeys() const {
346  std::stringstream s;
347  getKeys((std::ostream &)s);
348  return s.str();
349  };
350 
352  inline
353  void getValues(std::ostream &ostr) const {
354 
355  const keylist_t & l = getKeyList();
356  for (keylist_t::const_iterator it = l.begin(); it != l.end(); ++it ){
357  if (it != l.begin())
358  ostr << ',';
359  if (this->find(*it) != this->end())
360  ostr << (*this)[*it]; // << this->find(*it).getType();
361  else {
362  ostr << "*SMARTMAP::FAIL* " << __FUNCTION__;
363  }
364  }
365 
366  }
367 
369  inline
370  std::string getValues() const {
371  std::stringstream s;
372  getValues(s);
373  return s.str();
374  };
375 
376 
378  /*
379  * \param equal - typically =, :, or -
380  * \param start - typically hyphen or leading parenthesis (, {, [
381  * \param end - typically hyphen or trailing parenthesis ), }, [
382  * \param separator - typically comma or semicolon
383  */
384  // template <class S>
385  // S & toStream(S & ostr, char equal='=', char startChar=0, char endChar=0, char separatorChar=0) const;
386  std::ostream & toStream(std::ostream & ostr, char equal='=', char startChar='{', char endChar='}', char separatorChar=',') const {
387  //drain::TypeLayout pairLayout(equal);
388  drain::TypeLayout mainLayout(startChar, separatorChar, endChar);
390  //layout.pairChars.separator = equal;
391  layout.pairChars.separator = equal;
392  //layout.arrayChars.setLayout();
393  return Sprinter::sequenceToStream(ostr, getMap(), mainLayout, layout);
394  //return Sprinter::sequenceToStream(ostr, vmap.getMap(), layout.mapChars, layout);
395  //return Sprinter::mapToStream(ostr, *this, Sprinter::jsonLayout, this->getKeyList());
396  }
397 
398  //std::string toStr(char equal='=', char start='{', char end='}', char separator=0) const {
399  std::string toStr(char equal='=', char start=0, char end=0, char separator=0) const {
400  std::stringstream sstr;
401  toStream(sstr, equal, start, end, separator);
402  return sstr.str();
403  }
404 
406  //void toJSON(std::ostream & ostr = std::cout, size_t indent = 0) const;
407 
409  // void valuesToJSON(std::ostream & ostr = std::cout) const;
410 
412  void dump(std::ostream & ostr = std::cout) const;
413 
414 
415 
417  // ?? If specific, allows also "key=value,key1=value2,...".
429  // \param updateOnly - if true, skip non-existing entries silently
430  //void assignEntries2(const std::string & entries, bool updateOnly = false, char assignmentSymbol='=', char separatorSymbol=0){
431 
432 protected:
433 
434 
436  // std::list<std::string> orderedKeyList;
437 
438  mutable std::list<std::string> keyList;
439 
440 };
441 
442 template <class T>
443 template <bool STRICT>
444 void SmartMap<T>::importEntries(const std::string & entries, char assignmentSymbol, char separatorSymbol){ //, bool updateOnly){
445 
446  Logger mout(__FILE__, __FUNCTION__);
447  //mout.debug(10) << entries << mout.endl;
448 
449  if (entries.empty()){ //old
450  return;
451  }
452 
453  separatorSymbol = separatorSymbol ? separatorSymbol : separator;
454 
455  // Input parameter assignments, separated by the separator: "a=1", "b=2", "c=3", ...
456  std::list<std::string> p;
457  // separatorSymbol = separatorSymbol ? separatorSymbol : separator;
458  if (separatorSymbol)
459  drain::StringTools::split(entries, p, std::string(1, separatorSymbol)); // separators);
460  else {
461  // no separator => single-param cmd, BUT explicit key=value possible
462  // mout.warn("push back entries:" , entries );
463  p.push_back(entries);
464  }
465  importEntries<STRICT>(p, assignmentSymbol);
466 
467 }
468 
469 /*
470 
471 template <class T>
472 template <bool STRICT>
473 void SmartMap<T>::importEntries(const std::list<std::string> & p, char assignmentSymbol){ // , bool updateOnly){
474 
475  Logger mout(__FILE__, __FUNCTION__);
476 
477  // NUEVO3 SmartMapTools::setValues<T,STRICT>(*this, p, assignmentSymbol);
478 
479  //SmartMapTools::setValues<T,STRICT>(*this, getKeyList(), p, assignmentSymbol);
480 
481  const std::string assignmentSymbols(1, assignmentSymbol);
482 
483  const std::list<std::string> & keys = getKeyList();
484  std::list<std::string>::const_iterator kit = keys.begin();
485 
486 
487  bool acceptOrderedParams = true;
488 
489  // mout.warn(" assignmentSymbol: " , assignmentSymbol );
490  // mout.warn(" size: " , this->size() );
491 
492  for (std::list<std::string>::const_iterator pit = p.begin(); pit != p.end(); ++pit){
493 
494  //mout.warn(" entry: " , *pit );
495 
496  // Check specific assignment, ie. check if the key=value is given explicitly.
497  if (assignmentSymbol){ // typically '='
498  std::string key;
499  std::string value;
500  if (StringTools::split2(*pit, key, value, assignmentSymbols)){
501  // mout.warn(" specified " , key , "=\t" , value );
502  if (this->size()==1){
503  iterator it = this->begin();
504  if (key == it->first)
505  it->second = value;
506  else
507  it->second = *pit;
508  return;
509  }
510 
511  importEntry<std::string,STRICT>(key, value); //, criticality);
512  acceptOrderedParams = false;
513  continue;
514  }
515  else {
516  // mout.warn(" could not split: " , *pit );
517  }
518  }
519 
520  // Key and assignment symbol not given.
521 
522  if (kit != keys.end()){
523  // Assignment-by-order
524  if (!acceptOrderedParams){
525  mout.warn("positional arg '" , *pit , "' for [", *kit , "] given after explicit args" );
526  }
527  //mout.warn(" ordered " , );
528  (*this)[*kit] = *pit; // does not need to call import() because *kit exists.
529  ++kit; // NUEVO
530  }
531  else {
532  //mout.log(criticality)
533  // << "too many (over "<< this->size() << ") params, run out of keys with entry=" << *pit << mout.endl;
534  if (STRICT){
535  mout.error("too many (over ", this->size() , ") params, run out of keys with entry=" , *pit );
536  }
537 
538  }
539 
540  }
541 
542 }
543 */
544 
545 
546 template <class T>
547 template <class S>
548 void SmartMap<T>::setValuesSEQ(const S & sequence){
549 
550  Logger log(__FILE__, __FUNCTION__);
551 
552  const std::list<std::string> & keys = getKeyList();
553  std::list<std::string>::const_iterator kit = keys.begin();
554 
555  for (typename S::const_iterator it = sequence.begin(); it != sequence.end(); ++it){
556 
557  if (kit != keys.end()){
558  // Assignment-by-order
559  (*this)[*kit] = *it; // does not need to call import() because *kit exists.
560  ++kit; // NUEVO
561  }
562  else {
563  log.error() << "too many ("<< sequence.size() << ") params for map of size ("<< this->size() << "), run out of keys with entry=" << *it << log.endl;
564  }
565 
566  }
567 
568 }
569 
570 /*
571 template <class T>
572 std::ostream & SmartMap<T>::toStream(std::ostream & ostr, char equal, char startChar, char endChar, char separatorChar) const {
573 
574  // Otherways ok, but key order not used: Sprinter::sequenceToStream(ostr, *this, Sprinter::jsonLayout);
575  //return Sprinter::mapToStream(ostr, *this, Sprinter::jsonLayout, this->getKeyList());
576 
577 
578  const std::list<std::string> & keys = this->getKeyList();
579 
580  separatorChar = separatorChar ? separatorChar : this->separator;
581  //separatorChar = separatorChar ? separatorChar : ','; // needed?
582  char sep = 0;
583 
584  for (std::list<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it){
585 
586  if (sep){
587  //if (it != keys.begin())
588  ostr << sep;
589  }
590  else {
591  sep = separator;
592  }
593 
594  ostr << *it << equal;
595  if (startChar)
596  ostr << startChar;
597  ostr << (*this)[*it];
598  if (endChar)
599  ostr << endChar;
600 
601  }
602 }
603  */
604 
605 /*
606 template <class T>
607 void SmartMap<T>::toJSON(std::ostream & ostr, size_t indent) const {
608 
609  const std::string space(indent, ' ');
610 
611  char sep = 0;
612  ostr << "{\n";
613 
614  // NOTE: alphabetic order. Should JSON dump have orig. order?
615  for (const_iterator it = this->begin(); it != this->end(); ++it){
616 
617  const std::string & key = it->first;
618  const T & item = it->second; //(*this)[key];
619 
620  if (sep){
621  ostr << sep;
622  ostr << '\n';
623  }
624  else {
625  sep = ',';
626  }
627  //ostr << '\n';
628  ostr << space << "\"" << key << "\" : ";
629 
630  //if (item.getType() == typeid(std::string)){
631  if (item.T::isString()){
632  //
633  ostr << '"';
634  // ostr << '"' << item.getCharArray() << '"';
635  const char *c = item.getCharArray();
636  while (*c != '\0'){
637  if (*c == '"')
638  ostr << '\\'; // TODO; implement also \n \t ...
639  ostr << *c;
640  ++c;
641  }
642  ostr << '"';
643  //ostr << '"' << item << '"';
644  }
645  else {
646  switch (item.T::getElementCount()) {
647  case 0:
648  ostr << '[' << ']'; // or NaN?
649  break;
650  case 1:
651  ostr << item;
652  break;
653  default:
654  Sprinter::toStream(ostr, item, Sprinter::plainLayout);
655  // JSONwriter::toStream(item, ostr); // Better! Forces commas.
656  // ostr << '[' << item << ']';
657  }
658  }
659  }
660  // ostr << "{\n \"value\":" << *this << ",\n";
661  // ostr << " \"type\":" << drain::Type::getTypeChar(getType()) << ",\n";
662  ostr << "\n" << space << "}\n"; // \n needed?
663 }
664 
665 template <class T>
666 void SmartMap<T>::valuesToJSON(std::ostream & ostr) const {
667 
668 
669  char sep = 0;
670 
671  if (this->size() > 1)
672  ostr << "[";
673 
674  // NOTE: alphabetic order. Should JSON dump have orig. order?
675  for (const_iterator it = this->begin(); it != this->end(); ++it){
676 
677  //const std::string & key = it->first;
678  const T & item = it->second; //(*this)[key];
679 
680  if (sep){
681  ostr << sep;
682  ostr << ' ';
683  }
684  else {
685  sep = ',';
686  }
687 
688  if (item.T::isString()){
689  ostr << '"';
690  const char *c = item.getCharArray();
691  while (*c != '\0'){
692  if (*c == '"')
693  ostr << '\\'; // TODO; implement also \n \t ...
694  ostr << *c;
695  ++c;
696  }
697  ostr << '"';
698  //ostr << '"' << item << '"';
699  }
700  else {
701  switch (item.T::getElementCount()) {
702  case 0:
703  ostr << '[' << ']'; // or NaN?
704  break;
705  case 1:
706  ostr << item;
707  break;
708  default:
709  ostr << '[' << item << ']';
710  }
711  }
712 
713  }
714 
715  if (this->size() > 1)
716  ostr << "]";
717 
718 }
719 */
720 
721 
722 template <class T>
723 void SmartMap<T>::dump(std::ostream & ostr) const {
724 
725  //const std::string space(indent, ' ');
726  for (const_iterator it = this->begin(); it != this->end(); ++it){
727  ostr << it->first << ':' << ' ';
728  it->second.info(ostr);
729  ostr << '\n';
730  }
731 
732 }
733 
734 template<class T>
735 std::ostream &operator<<(std::ostream &ostr, const SmartMap<T> & m){
736  m.toStream(ostr, '=', 0, 0, m.separator);
737  return ostr;
738 }
739 
740 /*
741 template <class T>
742 //template <>
743 inline
744 std::ostream & Sprinter::toStream(std::ostream & ostr, const SmartMap<T> & smap, const SprinterLayout & layout){
745  return Sprinter::mapToStream(ostr, smap.getMap(), layout, smap.getKeys());
746 }
747 */
748 
749 } // drain
750 
751 
752 #endif // Drain
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
A base class for smart maps providing methods for importing and exporting values, among others.
Definition: SmartMap.h:66
map_t::iterator iterator
Needed?
Definition: SmartMap.h:80
virtual T & operator[](const std::string &key)
Returns an element. Creates one, conditionally.
Definition: SmartMap.h:167
void importEntries(const std::string &entries, char assignmentSymbol='=', char separatorSymbol=0)
Assigns a value to given key; if the entry does not exist, tries to create it with directly with oper...
Definition: SmartMap.h:444
char arraySeparator
Default separator character for array elements (std::vector's)
Definition: SmartMap.h:88
virtual const T & operator[](const std::string &key) const
Unlike with std::map, operator[] const is defined, returning reference to a static empty instance.
Definition: SmartMap.h:185
std::string getKeys() const
Convenience function for std::string output.
Definition: SmartMap.h:345
std::list< std::string > keyList
Assigns values from std::string of type "value,value2,...valueN".
Definition: SmartMap.h:438
void importEntries(const std::list< std::string > &entries, char assignmentSymbol='=')
Definition: SmartMap.h:240
std::ostream & toStream(std::ostream &ostr, char equal='=', char startChar='{', char endChar='}', char separatorChar=',') const
Note: parameters discarded.
Definition: SmartMap.h:386
char separator
Default character used for splitting input and output. See setValues.
Definition: SmartMap.h:85
void setValues(const std::string &entries, char assignmentSymbol='=', char separatorSymbol=0)
Sets values. If strictness==STRICTLY_CLOSED, throws exception if tries to assign a non-existing entry...
Definition: SmartMap.h:311
virtual const keylist_t & getKeyList() const
Derived versions may produce an ordered set of keys.
Definition: SmartMap.h:200
void importCastableMap(const drain::SmartMap< T2 > &m)
Assign values from a map, possibly extending the map.
Definition: SmartMap.h:271
std::string getValues() const
Convenience function for std::string output.
Definition: SmartMap.h:370
void exportMap(std::map< std::string, T2 > &m) const
Copies the contents to another map.
Definition: SmartMap.h:212
void getValues(std::ostream &ostr) const
Dumps the values.
Definition: SmartMap.h:353
void updateFromMap(const std::map< std::string, T2 > &m)
Assign values from a map. Updates existing entries only.
Definition: SmartMap.h:294
void updateFromCastableMap(const drain::SmartMap< T2 > &m)
Convenience.
Definition: SmartMap.h:301
void updateValues(const std::string &entries, char assignmentSymbol='=', char separatorSymbol=0)
Sets applicable values ie. modifies existing entries only. In ordered maps, skips extra entries silen...
Definition: SmartMap.h:326
std::string get(const std::string &key, const std::string &defaultValue) const
Retrieves a value, or default value if value is unset.
Definition: SmartMap.h:127
void dump(std::ostream &ostr=std::cout) const
Write map as a JSON code.
Definition: SmartMap.h:723
T2 get(const std::string &key, const T2 &defaultValue) const
Retrieves a value, if set, else returns the given default value.
Definition: SmartMap.h:151
SmartMap(char separator='\0', char arraySeparator=':')
Definition: SmartMap.h:95
const map_t & getMap() const
Definition: SmartMap.h:206
void importMap(const std::map< std::string, S > &m)
Assign values from a map, overriding existing entries.
Definition: SmartMap.h:252
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 jsonLayout
Resembles JSON structure: {"a":1,"b":22,"c":3}.
Definition: Sprinter.h:221
static void split(const std::string &s, T &sequence, const C &separators, const std::string &trimChars=" \t\n")
Splits and trims a given std::string to a std Sequence.
Definition: String.h:309
Definition: DataSelector.cpp:1277
Definition: Sprinter.h:137
Definition: Sprinter.h:80