Loading...
Searching...
No Matches
SmartMap2.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood 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
54namespace drain {
55
57
66template<class T>
67class SmartMapFoo : public std::map<std::string, T> {
68
69public:
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
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
433protected:
434
435
437 // std::list<std::string> orderedKeyList;
438
439 mutable std::list<std::string> keyList;
440
441};
442
443template <class T>
444template <bool STRICT>
445void 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
472template <class T>
473template <bool STRICT>
474void 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
547template <class T>
548template <class S>
549void 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/*
572template <class T>
573std::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/*
607template <class T>
608void 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
666template <class T>
667void 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
723template <class T>
724void 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
735template<class T>
736std::ostream &operator<<(std::ostream &ostr, const SmartMapFoo<T> & m){
737 m.toStream(ostr, '=', 0, 0, m.separator);
738 return ostr;
739}
740
741/*
742template <class T>
743//template <>
744inline
745std::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:312
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
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
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
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
void importEntries(const std::list< std::string > &entries, char assignmentSymbol='=')
Definition SmartMap2.h:241
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
virtual T & operator[](const std::string &key)
Returns an element. Creates one, conditionally.
Definition SmartMap2.h:168
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
const map_t & getMap() const
Definition SmartMap2.h:207
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
std::ostream & toStream(std::ostream &ostr, char equal='=', char startChar='{', char endChar='}', char separatorChar=',') const
Note: parameters discarded.
Definition SmartMap2.h:387
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:380
Definition DataSelector.cpp:1277
Definition Sprinter.h:137
Definition Sprinter.h:80