SmartMap2.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 SMARTMAP2_H
32 #define SMARTMAP2_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 "Castable.h"
45 #include "Sprinter.h"
46 #include "String.h"
47 
48 //#include "SmartMapTools.h"
49 
50 
51 
52 // TODO: use SmartMapTools for assignments
53 
54 namespace drain {
55 
57 
66 template<class T>
67 class SmartMapFoo : public std::map<std::string, T> {
68 
69 public:
70 
71  typedef SmartMapFoo<T> smap_t;
72 
73  typedef std::map<std::string, T> map_t;
74  typedef typename map_t::key_type key_t;
75  typedef typename map_t::mapped_type value_t; // == T
76  typedef typename map_t::value_type entry_t; // pair<key_t,value_t>
77 
78  typedef std::list<std::string> keylist_t;
79 
81  typedef typename map_t::iterator iterator;
82  typedef typename map_t::const_iterator const_iterator;
83 
84 
86  char separator;
87 
90 
95  inline
97 
98  // Copy constructor. Does not copy items.
101  inline
103 
104 
105  virtual
106  inline
107  ~SmartMapFoo(){};
108 
109 
110  virtual inline
111  void clear(){
112  map_t::clear();
113  keyList.clear();
114  }
115 
116  inline
117  bool hasKey(const std::string &key) const {
118  return (this->find(key) != this->end());
119  }
120 
122 
127  inline
128  std::string get(const std::string &key, const std::string & defaultValue) const {
129  const_iterator it = this->find(key);
130  if (it == this->end())
131  return defaultValue;
132  else {
133  // return static_cast<std::string>(it->second); DOES NOT WORK, http://stackoverflow.com/questions/7741531/conversion-operator-template-specialization
134  return it->second;
135  }
136  }
137 
138 
139  inline
140  std::string get(const std::string & key, const char *defaultValue) const {
141  return get(key, std::string(defaultValue));
142  }
143 
144 
146 
151  template <class T2>
152  T2 get(const std::string &key, T2 defaultValue) const {
153  const_iterator it = this->find(key);
154  if (it == this->end())
155  return defaultValue;
156  else
157  return static_cast<T2>(it->second);
158  }
159 
161 
166  inline
167  virtual
168  T & operator[](const std::string &key){
169 
170  iterator it = this->find(key);
171  if (it != this->end()) {
172  return it->second;
173  }
174  else {
175  // Create:
176  keyList.push_back(key);
177  T & element = map_t::operator[](key);
178  //element.setSeparator(arraySeparator);
179  return element;
180  }
181  }
182 
184  inline
185  virtual
186  const T & operator[](const std::string &key) const {
187 
188  const_iterator it = this->find(key);
189  if (it != this->end()) {
190  return it->second;
191  }
192  else {
193  static const T empty;
194  return empty;
195  }
196  }
197 
198 
200  virtual inline
201  const keylist_t & getKeyList() const {
202  return keyList;
203  }
204 
205 
206  inline
207  const map_t & getMap() const {
208  return *this;
209  };
210 
212  template <class T2>
213  void exportMap(std::map<std::string,T2> & m) const {
214  for (const_iterator it = this->begin(); it != this->end(); ++it)
215  m[it->first] = it->second;
216  }
217 
219 
222  /*
223  template <class V,bool STRICT=false> // TODO: true...
224  //void importEntry(const std::string & key, const T2 & value, bool updateOnly = true){
225  void importEntry(const std::string & key, const V & value){ //, bool updateOnly = true) { //, unsigned int criticality = LOG_DEBUG){
226  */
227 
231  template <bool STRICT=true>
232  void importEntries(const std::string & entries, char assignmentSymbol='=', char separatorSymbol=0); //, bool updateOnly = false);
233  //, unsigned int criticality = LOG_ERR);
234 
235 
240  template <bool STRICT=true>
241  void importEntries(const std::list<std::string> & entries, char assignmentSymbol='='){ //; //, bool updateOnly = false);
242  //SmartMapTools::setValues<T,STRICT>(*this, getKeyList(), entries, assignmentSymbol);
243  SmartMapTools::setValues<smap_t,STRICT>(*this, getKeyList(), entries, assignmentSymbol);
244  }
245 
247 
252  template <class S,bool STRICT=true>
253  void importMap(const std::map<std::string,S> & m){ //, bool updateOnly = false){ //, unsigned int criticality = LOG_ERR){
254  // SmartMapTools::setValues<map_t,S,STRICT>(*this, m);
255  // SmartMapTools::setValues(*this, m);
256  SmartMapTools::setValues<smap_t,S,STRICT>(*this, m);
257  //new
258  //for (typename std::map<std::string,S>::const_iterator it = m.begin(); it != m.end(); ++it)
259  // importEntry(it->first, it->second); //, updateOnly); //, criticality); // false);
260 
261  }
262 
264 
271  template <class T2,bool STRICT=true>
272  void importCastableMap(const drain::SmartMap<T2> & m){ //, bool updateOnly = false, unsigned int criticality = LOG_ERR){
273  // NUOEVO:
274  SmartMapTools::setCastableValues<smap_t,T2,STRICT>(*this, m);
275  // SmartMapTools::setValues<smap_t,T2,STRICT>(*this, m);
276  //SmartMapTools::setValues<map_t,T2,STRICT>(*this, m);
277  /*
278  for (const typename SmartMap<T2>::keylist_t::value_type &key : m.getKeyList()){
279  importEntry(key, (const Castable &)m[key]); //, updateOnly);
280  }
281  */
282  // for (typename SmartMap<T2>::const_iterator it = m.begin(); it != m.end(); ++it)
283  // importEntry(it->first, (const Castable &)it->second, updateOnly); //, criticality); // false);
284  }
285 
286 
287 
289 
293  template <class T2>
294  inline
295  void updateFromMap(const std::map<std::string,T2> & m){
296  importMap<T2,false>(m); //, LOG_DEBUG);
297  }
298 
300  template <class T2>
301  inline
303  importCastableMap<T2,false>(m); //, true);
304  // for (typename SmartMap<T2>::const_iterator it = m.begin(); it != m.end(); ++it)
305  // importEntry(it->first, (const Castable &)it->second, LOG_DEBUG); //true);
306  }
307 
308 
310  // TODO: consider: std::string assignmentSymbols="=:", std::string separatorSymbols=", ", std::string trimSymbols=" \t\n\r",
311  inline
312  void setValues(const std::string & entries, char assignmentSymbol='=', char separatorSymbol=0){ // char separatorSymbol=','
313  importEntries<true>(entries, assignmentSymbol, separatorSymbol); //, false); //, LOG_ERR);
314  }
315 
316  inline
317  void setValues(const char * entries, char assignmentSymbol='=', char separatorSymbol=0){
318  importEntries<true>(entries, assignmentSymbol, separatorSymbol); //, false); //, LOG_ERR);
319  }
320 
321  // status?
322  template <class S>
323  void setValuesSEQ(const S & sequence);
324 
326  inline
327  void updateValues(const std::string & entries, char assignmentSymbol='=', char separatorSymbol=0){// char separatorSymbol=','
328  importEntries<false>(entries, assignmentSymbol, separatorSymbol); //, true); //, LOG_DEBUG);
329  }
330 
331 
332  inline
333  void getKeys(std::ostream &ostr) const {
334 
335  const keylist_t & l = getKeyList();
336  for (keylist_t::const_iterator it = l.begin(); it != l.end(); ++it ){
337  if (it != l.begin())
338  ostr << ',';
339  ostr << *it;
340  }
341 
342  }
343 
345  inline
346  std::string getKeys() const {
347  std::stringstream s;
348  getKeys((std::ostream &)s);
349  return s.str();
350  };
351 
353  inline
354  void getValues(std::ostream &ostr) const {
355 
356  const keylist_t & l = getKeyList();
357  for (keylist_t::const_iterator it = l.begin(); it != l.end(); ++it ){
358  if (it != l.begin())
359  ostr << ',';
360  if (this->find(*it) != this->end())
361  ostr << (*this)[*it]; // << this->find(*it).getType();
362  else {
363  ostr << "*SMARTMAP::FAIL* " << __FUNCTION__;
364  }
365  }
366 
367  }
368 
370  inline
371  std::string getValues() const {
372  std::stringstream s;
373  getValues(s);
374  return s.str();
375  };
376 
377 
379  /*
380  * \param equal - typically =, :, or -
381  * \param start - typically hyphen or leading parenthesis (, {, [
382  * \param end - typically hyphen or trailing parenthesis ), }, [
383  * \param separator - typically comma or semicolon
384  */
385  // template <class S>
386  // S & toStream(S & ostr, char equal='=', char startChar=0, char endChar=0, char separatorChar=0) const;
387  std::ostream & toStream(std::ostream & ostr, char equal='=', char startChar='{', char endChar='}', char separatorChar=',') const {
388  //drain::TypeLayout pairLayout(equal);
389  drain::TypeLayout mainLayout(startChar, separatorChar, endChar);
391  //layout.pairChars.separator = equal;
392  layout.pairChars.separator = equal;
393  //layout.arrayChars.setLayout();
394  return Sprinter::sequenceToStream(ostr, getMap(), mainLayout, layout);
395  //return Sprinter::sequenceToStream(ostr, vmap.getMap(), layout.mapChars, layout);
396  //return Sprinter::mapToStream(ostr, *this, Sprinter::jsonLayout, this->getKeyList());
397  }
398 
399  //std::string toStr(char equal='=', char start='{', char end='}', char separator=0) const {
400  std::string toStr(char equal='=', char start=0, char end=0, char separator=0) const {
401  std::stringstream sstr;
402  toStream(sstr, equal, start, end, separator);
403  return sstr.str();
404  }
405 
407  //void toJSON(std::ostream & ostr = std::cout, size_t indent = 0) const;
408 
410  // void valuesToJSON(std::ostream & ostr = std::cout) const;
411 
413  void dump(std::ostream & ostr = std::cout) const;
414 
415 
416 
418  // ?? If specific, allows also "key=value,key1=value2,...".
430  // \param updateOnly - if true, skip non-existing entries silently
431  //void assignEntries2(const std::string & entries, bool updateOnly = false, char assignmentSymbol='=', char separatorSymbol=0){
432 
433 protected:
434 
435 
437  // std::list<std::string> orderedKeyList;
438 
439  mutable std::list<std::string> keyList;
440 
441 };
442 
443 template <class T>
444 template <bool STRICT>
445 void SmartMapFoo<T>::importEntries(const std::string & entries, char assignmentSymbol, char separatorSymbol){ //, bool updateOnly){
446 
447  Logger mout(__FILE__, __FUNCTION__);
448  //mout.debug(10) << entries << mout.endl;
449 
450  if (entries.empty()){ //old
451  return;
452  }
453 
454  separatorSymbol = separatorSymbol ? separatorSymbol : separator;
455 
456  // Input parameter assignments, separated by the separator: "a=1", "b=2", "c=3", ...
457  std::list<std::string> p;
458  // separatorSymbol = separatorSymbol ? separatorSymbol : separator;
459  if (separatorSymbol)
460  drain::StringTools::split(entries, p, std::string(1, separatorSymbol)); // separators);
461  else {
462  // no separator => single-param cmd, BUT explicit key=value possible
463  // mout.warn("push back entries:" , entries );
464  p.push_back(entries);
465  }
466  importEntries<STRICT>(p, assignmentSymbol);
467 
468 }
469 
470 /*
471 
472 template <class T>
473 template <bool STRICT>
474 void SmartMapFoo<T>::importEntries(const std::list<std::string> & p, char assignmentSymbol){ // , bool updateOnly){
475 
476  Logger mout(__FILE__, __FUNCTION__);
477 
478  // NUEVO3 SmartMapTools::setValues<T,STRICT>(*this, p, assignmentSymbol);
479 
480  //SmartMapTools::setValues<T,STRICT>(*this, getKeyList(), p, assignmentSymbol);
481 
482  const std::string assignmentSymbols(1, assignmentSymbol);
483 
484  const std::list<std::string> & keys = getKeyList();
485  std::list<std::string>::const_iterator kit = keys.begin();
486 
487 
488  bool acceptOrderedParams = true;
489 
490  // mout.warn(" assignmentSymbol: " , assignmentSymbol );
491  // mout.warn(" size: " , this->size() );
492 
493  for (std::list<std::string>::const_iterator pit = p.begin(); pit != p.end(); ++pit){
494 
495  //mout.warn(" entry: " , *pit );
496 
497  // Check specific assignment, ie. check if the key=value is given explicitly.
498  if (assignmentSymbol){ // typically '='
499  std::string key;
500  std::string value;
501  if (StringTools::split2(*pit, key, value, assignmentSymbols)){
502  // mout.warn(" specified " , key , "=\t" , value );
503  if (this->size()==1){
504  iterator it = this->begin();
505  if (key == it->first)
506  it->second = value;
507  else
508  it->second = *pit;
509  return;
510  }
511 
512  importEntry<std::string,STRICT>(key, value); //, criticality);
513  acceptOrderedParams = false;
514  continue;
515  }
516  else {
517  // mout.warn(" could not split: " , *pit );
518  }
519  }
520 
521  // Key and assignment symbol not given.
522 
523  if (kit != keys.end()){
524  // Assignment-by-order
525  if (!acceptOrderedParams){
526  mout.warn("positional arg '" , *pit , "' for [", *kit , "] given after explicit args" );
527  }
528  //mout.warn(" ordered " , );
529  (*this)[*kit] = *pit; // does not need to call import() because *kit exists.
530  ++kit; // NUEVO
531  }
532  else {
533  //mout.log(criticality)
534  // << "too many (over "<< this->size() << ") params, run out of keys with entry=" << *pit << mout.endl;
535  if (STRICT){
536  mout.error("too many (over ", this->size() , ") params, run out of keys with entry=" , *pit );
537  }
538 
539  }
540 
541  }
542 
543 }
544 */
545 
546 
547 template <class T>
548 template <class S>
549 void SmartMapFoo<T>::setValuesSEQ(const S & sequence){
550 
551  Logger log(__FILE__, __FUNCTION__);
552 
553  const std::list<std::string> & keys = getKeyList();
554  std::list<std::string>::const_iterator kit = keys.begin();
555 
556  for (typename S::const_iterator it = sequence.begin(); it != sequence.end(); ++it){
557 
558  if (kit != keys.end()){
559  // Assignment-by-order
560  (*this)[*kit] = *it; // does not need to call import() because *kit exists.
561  ++kit; // NUEVO
562  }
563  else {
564  log.error() << "too many ("<< sequence.size() << ") params for map of size ("<< this->size() << "), run out of keys with entry=" << *it << log.endl;
565  }
566 
567  }
568 
569 }
570 
571 /*
572 template <class T>
573 std::ostream & SmartMap<T>::toStream(std::ostream & ostr, char equal, char startChar, char endChar, char separatorChar) const {
574 
575  // Otherways ok, but key order not used: Sprinter::sequenceToStream(ostr, *this, Sprinter::jsonLayout);
576  //return Sprinter::mapToStream(ostr, *this, Sprinter::jsonLayout, this->getKeyList());
577 
578 
579  const std::list<std::string> & keys = this->getKeyList();
580 
581  separatorChar = separatorChar ? separatorChar : this->separator;
582  //separatorChar = separatorChar ? separatorChar : ','; // needed?
583  char sep = 0;
584 
585  for (std::list<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it){
586 
587  if (sep){
588  //if (it != keys.begin())
589  ostr << sep;
590  }
591  else {
592  sep = separator;
593  }
594 
595  ostr << *it << equal;
596  if (startChar)
597  ostr << startChar;
598  ostr << (*this)[*it];
599  if (endChar)
600  ostr << endChar;
601 
602  }
603 }
604  */
605 
606 /*
607 template <class T>
608 void SmartMap<T>::toJSON(std::ostream & ostr, size_t indent) const {
609 
610  const std::string space(indent, ' ');
611 
612  char sep = 0;
613  ostr << "{\n";
614 
615  // NOTE: alphabetic order. Should JSON dump have orig. order?
616  for (const_iterator it = this->begin(); it != this->end(); ++it){
617 
618  const std::string & key = it->first;
619  const T & item = it->second; //(*this)[key];
620 
621  if (sep){
622  ostr << sep;
623  ostr << '\n';
624  }
625  else {
626  sep = ',';
627  }
628  //ostr << '\n';
629  ostr << space << "\"" << key << "\" : ";
630 
631  //if (item.getType() == typeid(std::string)){
632  if (item.T::isString()){
633  //
634  ostr << '"';
635  // ostr << '"' << item.getCharArray() << '"';
636  const char *c = item.getCharArray();
637  while (*c != '\0'){
638  if (*c == '"')
639  ostr << '\\'; // TODO; implement also \n \t ...
640  ostr << *c;
641  ++c;
642  }
643  ostr << '"';
644  //ostr << '"' << item << '"';
645  }
646  else {
647  switch (item.T::getElementCount()) {
648  case 0:
649  ostr << '[' << ']'; // or NaN?
650  break;
651  case 1:
652  ostr << item;
653  break;
654  default:
655  Sprinter::toStream(ostr, item, Sprinter::plainLayout);
656  // JSONwriter::toStream(item, ostr); // Better! Forces commas.
657  // ostr << '[' << item << ']';
658  }
659  }
660  }
661  // ostr << "{\n \"value\":" << *this << ",\n";
662  // ostr << " \"type\":" << drain::Type::getTypeChar(getType()) << ",\n";
663  ostr << "\n" << space << "}\n"; // \n needed?
664 }
665 
666 template <class T>
667 void SmartMap<T>::valuesToJSON(std::ostream & ostr) const {
668 
669 
670  char sep = 0;
671 
672  if (this->size() > 1)
673  ostr << "[";
674 
675  // NOTE: alphabetic order. Should JSON dump have orig. order?
676  for (const_iterator it = this->begin(); it != this->end(); ++it){
677 
678  //const std::string & key = it->first;
679  const T & item = it->second; //(*this)[key];
680 
681  if (sep){
682  ostr << sep;
683  ostr << ' ';
684  }
685  else {
686  sep = ',';
687  }
688 
689  if (item.T::isString()){
690  ostr << '"';
691  const char *c = item.getCharArray();
692  while (*c != '\0'){
693  if (*c == '"')
694  ostr << '\\'; // TODO; implement also \n \t ...
695  ostr << *c;
696  ++c;
697  }
698  ostr << '"';
699  //ostr << '"' << item << '"';
700  }
701  else {
702  switch (item.T::getElementCount()) {
703  case 0:
704  ostr << '[' << ']'; // or NaN?
705  break;
706  case 1:
707  ostr << item;
708  break;
709  default:
710  ostr << '[' << item << ']';
711  }
712  }
713 
714  }
715 
716  if (this->size() > 1)
717  ostr << "]";
718 
719 }
720 */
721 
722 
723 template <class T>
724 void SmartMapFoo<T>::dump(std::ostream & ostr) const {
725 
726  //const std::string space(indent, ' ');
727  for (const_iterator it = this->begin(); it != this->end(); ++it){
728  ostr << it->first << ':' << ' ';
729  it->second.info(ostr);
730  ostr << '\n';
731  }
732 
733 }
734 
735 template<class T>
736 std::ostream &operator<<(std::ostream &ostr, const SmartMapFoo<T> & m){
737  m.toStream(ostr, '=', 0, 0, m.separator);
738  return ostr;
739 }
740 
741 /*
742 template <class T>
743 //template <>
744 inline
745 std::ostream & Sprinter::toStream(std::ostream & ostr, const SmartMapFoo<T> & smap, const SprinterLayout & layout){
746  return Sprinter::mapToStream(ostr, smap.getMap(), layout, smap.getKeys());
747 }
748 */
749 
750 } // drain
751 
752 
753 #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: SmartMap2.h:67
map_t::iterator iterator
Needed?
Definition: SmartMap2.h:81
virtual T & operator[](const std::string &key)
Returns an element. Creates one, conditionally.
Definition: SmartMap2.h:168
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: SmartMap2.h:445
char arraySeparator
Default separator character for array elements (std::vector's)
Definition: SmartMap2.h:89
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: SmartMap2.h:186
std::string getKeys() const
Convenience function for std::string output.
Definition: SmartMap2.h:346
std::list< std::string > keyList
Assigns values from std::string of type "value,value2,...valueN".
Definition: SmartMap2.h:439
SmartMapFoo(char separator='\0', char arraySeparator=':')
Definition: SmartMap2.h:96
void updateFromCastableMap(const drain::SmartMapFoo< T2 > &m)
Convenience.
Definition: SmartMap2.h:302
void importEntries(const std::list< std::string > &entries, char assignmentSymbol='=')
Definition: SmartMap2.h:241
std::ostream & toStream(std::ostream &ostr, char equal='=', char startChar='{', char endChar='}', char separatorChar=',') const
Note: parameters discarded.
Definition: SmartMap2.h:387
char separator
Default character used for splitting input and output. See setValues.
Definition: SmartMap2.h:86
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: SmartMap2.h:312
virtual const keylist_t & getKeyList() const
Derived versions may produce an ordered set of keys.
Definition: SmartMap2.h:201
void importCastableMap(const drain::SmartMap< T2 > &m)
Assign values from a map, possibly extending the map.
Definition: SmartMap2.h:272
std::string getValues() const
Convenience function for std::string output.
Definition: SmartMap2.h:371
void exportMap(std::map< std::string, T2 > &m) const
Copies the contents to another map.
Definition: SmartMap2.h:213
void getValues(std::ostream &ostr) const
Dumps the values.
Definition: SmartMap2.h:354
void updateFromMap(const std::map< std::string, T2 > &m)
Assign values from a map. Updates existing entries only.
Definition: SmartMap2.h:295
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: SmartMap2.h:327
std::string get(const std::string &key, const std::string &defaultValue) const
Retrieves a value, or default value if value is unset.
Definition: SmartMap2.h:128
void dump(std::ostream &ostr=std::cout) const
Write map as a JSON code.
Definition: SmartMap2.h:724
T2 get(const std::string &key, T2 defaultValue) const
Retrieves a value, if set, else returns the given default value.
Definition: SmartMap2.h:152
const map_t & getMap() const
Definition: SmartMap2.h:207
void importMap(const std::map< std::string, S > &m)
Assign values from a map, overriding existing entries.
Definition: SmartMap2.h:253
A base class for smart maps providing methods for importing and exporting values, among others.
Definition: SmartMap.h:66
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