Loading...
Searching...
No Matches
SmartMapTools.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 DRAIN_SMARTMAP_TOOLS_H
32#define DRAIN_SMARTMAP_TOOLS_H
33
34#include <drain/Log.h>
35#include <drain/Reference.h>
36#include <iostream>
37#include <string>
38#include <set>
39#include <list>
40#include <vector>
41#include <map>
42//#include <stdlib.h>
43#include <sys/syslog.h>
44#include <syslog.h>
45
46#include "Castable.h"
47#include "Reference.h"
48#include "Sprinter.h"
49#include "String.h"
50#include "Variable.h"
51
52
53namespace drain {
54
56class MapTools {
57
58public:
59
61
67 template <class M>
68 static
69 const typename M::mapped_type & get(const M & m, const typename M::key_type & key){
70 typename M::const_iterator it = m.find(key);
71 if (it != m.end()){
72 return it->second;
73 }
74 else {
75 static const typename M::mapped_type empty;
76 return empty;
77 }
78 }
79
80
82
88 template <class M,class F>
89 static
90 void get(const M & m, const typename M::key_type & key, F & value){
91 typename M::const_iterator it = m.find(key);
92 if (it != m.end()){
93 drain::Reference r(value);
94 r = it->second;
95 return; // false; // it->second;
96 }
97 else { //
98 return; // true; // defaultValue;
99 }
100 }
101
102};
103
105// Note: some update()'s may still be buggy
106class SmartMapTools : public MapTools {
107
108public:
109
110 typedef std::list<std::string> keylist_t;
111
113 /*
114 template <class T>
115 static
116 void getKeyList(const std::map<std::string,T> & src, keylist_t & keys) {
117 keys.clear();
118 for (const std::pair<std::string,T> & entry : src){
119 keys.push_back(entry.first);
120 }
121 }
122 */
123
124
125
127
131 template <class M,class V,bool STRICT=true>
132 static
133 void setValue(M & dst, const std::string & key, const V & value) {
134 if (STRICT){
135 dst[key] = value; // throws exception in derived classes!
136 }
137 else {
138 //typename std::map<std::string,T>::iterator it = dst.find(key);
139 typename M::iterator it = dst.find(key);
140 if (it != dst.end()){
141 it->second = value;
142 }
143 else {
144 //std::cerr << __FILE__ << ':' << __FUNCTION__ << ": key '" << key << "' not found\n";
145 }
146 }
147 }
148
149 template <class M,class V>
150 static inline
151 void setValue(M & dst, const std::string & key, const V & value, bool STRICT) {
152 if (STRICT)
153 setValue<M,V,true>(dst, key, value);
154 else
155 setValue<M,V,false>(dst, key, value);
156 }
157
158
160
164 template <class M,class V>
165 static inline
166 void updateValue(M & dst, const std::string & key, const V & value) {
167 setValue<M,V,false>(dst, key, value);
168 }
169
170
174 template <class M,class S,bool STRICT=true>
175 static
176 void setValues(M & dst, const std::map<std::string,S> & srcMap) {
177 // std::cerr << __FUNCTION__ << ':' << typeid(M).name() << " <= map<str," << typeid(S).name() << ">\n";
178 for (const typename std::map<std::string,S>::value_type & entry: srcMap){
179 setValue<M,S,STRICT>(dst, entry.first, entry.second);
180 }
181 }
182
183 template <class M,class S,bool STRICT=true>
184 static
185 void setCastableValues(M & dst, const std::map<std::string,S> & srcMap) {
186 //std::cerr << __FUNCTION__ << ':' << typeid(M).name() << " <= map<str," << typeid(S).name() << ">\n";
187 for (const typename std::map<std::string,S>::value_type & entry: srcMap){
188 setValue<M,drain::Castable,STRICT>(dst, entry.first, (const drain::Castable &) entry.second);
189 }
190 /*
191 for (typename std::map<std::string,S>::const_iterator it = srcMap.begin(); it != srcMap.end(); ++it){
192 setValue<M,S,STRICT>(dst, it->first, (const drain::Castable &) it->second);
193 }
194 */
195 }
196
197
198
203 template <class M,class S>
204 static inline
205 void updateValues(M & dst, const std::map<std::string,S> & src) {
206 setValues<M,S,false>(dst, src);
207 }
208
213 template <class M,class S>
214 static inline
215 void updateCastableValues(M & dst, const std::map<std::string,S> & src) {
216 setCastableValues<M,S,false>(dst, src);
217 }
218
220
227 template <class M, bool STRICT=true>
228 static
229 void setValues(M & dst, const std::list<std::string> & values, char equalSign='=', const std::string & trimChars = "") {
230
231 const bool TRIM = !trimChars.empty();
232
233 for (const std::string & entry: values){
234
235 if (entry.empty()){
236
237 Logger mout(__FILE__, __FUNCTION__);
238 if (values.size()==1){
239 //std::cerr << __FILE__ << ':' << __
240 mout.experimental("clearing a map of ", dst.size(), " elements");
241 dst.clear();
242 return;
243 }
244 else {
245 mout.debug("parameter list contained an empty value (ok)");
246 continue;
247 }
248
249 }
250
251 const size_t i = entry.find(equalSign);
252 if (i != std::string::npos){
253 if (i == (entry.length()-1)){
254 if (TRIM){
255 setValue<M,std::string,STRICT>(dst, StringTools::trim(entry, trimChars), ""); // todo: touch
256 }
257 else {
258 setValue<M,std::string,STRICT>(dst, entry, ""); // todo: touch
259 }
260 }
261 else {
262 if (TRIM){
263 setValue<M,std::string,STRICT>(dst, StringTools::trim(entry.substr(0, i)), StringTools::trim(entry.substr(i+1)));
264 }
265 else {
266 setValue<M,std::string,STRICT>(dst, entry.substr(0, i), entry.substr(i+1));
267 }
268 }
269 }
270 else {
271 for (const std::string & e: values){
272 std::cerr << '"' << e << '"' << std::endl;
273 }
274 // TODO: warn dump
275 throw std::runtime_error(entry + ": positional args without keys");
276 }
277 }
278 }
279
280
281 template <class M, bool STRICT=true>
282 static
283 void setValues(M & dst, const std::initializer_list<Variable::init_pair_t > &l){
284 for (const auto & entry: l){
285 drain::SmartMapTools::setValue<M,Variable,STRICT>(dst, entry.first, entry.second);
286 }
287 }
288
290
295 template <class M>
296 static inline
297 void updateValues(M & dst, const std::list<std::string> & values, char equals='=') {
298 setValues<M,false>(dst, values, equals);
299 }
300
302
308 // Potential for allowed-keys-only policy (hidden/read-only entries)
309 template <class M, bool STRICT=true>
310 static
311 void setValues(M & dst, const std::list<std::string> & keys, const std::list<std::string> & entries, char assignmentSymbol='=') {
312
313 Logger mout(__FILE__, __FUNCTION__);
314
315
316 const std::string assignmentSymbols(1, assignmentSymbol);
317
318 //const std::list<std::string> & keys = getKeyList();
319 std::list<std::string>::const_iterator kit = keys.begin();
320
321
322 bool acceptOrderedParams = true;
323
324 // mout.warn(" assignmentSymbol: " , assignmentSymbol );
325 // mout.warn(" size: " , this->size() );
326 for (const std::string & entry: entries){
327
328 //for (std::list<std::string>::const_iterator pit = p.begin(); pit != p.end(); ++pit){
329 //mout.warn(" entry: " , *pit );
330
331 // Check specific assignment, ie. check if the key=value is given explicitly.
332 if (assignmentSymbol){ // typically '='
333
334 std::string key, value;
335
336 if (StringTools::split2(entry, key, value, assignmentSymbols)){
337
338 // mout.warn(" specified " , key , "=\t" , value );
339
340 if (dst.size()==1){
341 /*
342 * This special handling is for single-element maps
343 * "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
344 */
345 typename M::iterator it = dst.begin();
346 if (key == it->first)
347 it->second = value;
348 else {
349 it->second = entry;
350 // mout.warn("is this in use?" , it->first , " <= '" , entry , "'" );
351 }
352 return;
353 }
354
355 setValue<M,std::string,STRICT>(dst, key, value); //, criticality);
356 acceptOrderedParams = false;
357 continue;
358 }
359 else {
360 // mout.warn(" could not split: " , *pit );
361 }
362 }
363
364 // Key and assignment symbol not given.
365
366 if (kit != keys.end()){
367 // Assignment-by-order
368 if (!acceptOrderedParams){
369 mout.warn("positional arg '" , entry , "' for [", *kit , "] given after explicit args" );
370 }
371 //mout.warn(" ordered " , );
372 dst[*kit] = entry; // does not need to call import() because *kit exists.
373 ++kit; // NUEVO
374 }
375 else {
376 //mout.log(criticality)
377 // << "too many (over "<< this->size() << ") params, run out of keys with entry=" << *pit << mout.endl;
378 if (STRICT){
379 mout.error("too many (over ", dst.size() , ") params, run out of keys with entry=" , entry );
380 }
381
382 }
383
384
385 }
386
387 /* OLTTI
388 bool acceptOrderedParams = true;
389 std::list<std::string>::const_iterator kit = keys.begin();
390
391 for (const std::string & entry: entries){
392 size_t i=entry.find(equals);
393 if (i != std::string::npos){
394 setValue<std::map<std::string,T>, std::string, STRICT>(dst, entry.substr(0, i), entry.substr(i+1));
395 acceptOrderedParams = false;
396 }
397 else if (kit != keys.end()){
398 // Assignment-by-order
399 if (!acceptOrderedParams){
400 mout.warn("positional arg '" , entry , "' for [", *kit , "] given after explicit args" );
401 }
402 setValue<std::map<std::string,T>, std::string, STRICT>(dst, *kit, entry);
403 ++kit;
404 }
405 else {
406 //throw std::runtime_error(values + ": run out of positional args at '" + entry + "'");
407 }
408 }
409 */
410
411 }
412
419 template <class M>
420 static inline
421 void updateValues(M & dst, const std::list<std::string> & keys, const std::list<std::string> & entries, char equals='=') {
422 setValues<false>(dst, keys, entries, equals);
423 }
424
425
427
437 template <class M, bool STRICT=true>
438 static
439 void setValues(M & dst, const std::string & values, char split=',', char equals='=', const std::string & trimChars = "") {
440 std::list<std::string> l;
441 drain::StringTools::split(values, l, split);
442 setValues(dst, l, equals, trimChars);
443 }
444
451 template <class M>
452 static inline
453 void updateValues(M & dst, const std::string & values, char split=',', char equals='=') {
454 setValues<false>(dst, values, split, equals);
455 }
456
458
465 template <class M, bool STRICT=true>
466 static
467 void setValues(M & dst, const std::list<std::string> & keys, const std::string & values, char split=',', char equals='=') {
468 std::list<std::string> l;
469 drain::StringTools::split(values, l, split);
470 setValues(dst, keys, l, equals);
471 }
472
473
481 template <class M>
482 static inline
483 void updateValues(M & dst, const std::list<std::string> & keys, const std::string & values, char split=',', char equals='=') {
484 setValues<false>(dst, keys, values, split, equals);
485 }
486
488
496 template <class M, class V, bool STRICT=true>
497 static
498 void setValues(M & dst, const std::list<std::string> & keys, std::initializer_list<V> values) {
499
500 std::list<std::string>::const_iterator kit = keys.begin();
501
502 for (const V & value: values){
503 if (kit == keys.end()){
504 throw std::runtime_error(std::string(__FILE__) + " run out of keys");
505 }
506 setValue(dst, *kit, value);
507 ++kit;
508 }
509 }
510
517 template <class M, class V>
518 static
519 void setValues(M & dst, std::initializer_list<V> values) {
520
521 //typename std::map<std::string,T>::const_iterator it = dst.begin();
522 typename M::const_iterator it = dst.begin();
523
524 for (const V & value: values){
525 if (it == dst.end()){
526 throw std::runtime_error(std::string(__FILE__) + " run out of keys");
527 }
528 setValue(dst, it->first, value);
529 ++it;
530 }
531 }
532
534 // Designed for: const std::initializer_list<std::pair<const char *,const char *> >
535 template <class M, typename K, typename V>
536 static
537 void setValues(M & dst, std::initializer_list<std::pair<K,V> > values) {
538 for (const auto & entry: values){
539 setValue(dst, entry.first, entry.second);
540 }
541 }
542
543
544 /*
545 template <class T, class T2>
546 static inline
547 void updateValues(std::map<std::string,T> & dst, const std::list<std::string> & keys, std::initializer_list<T2> values) {
548 setValues<false>(dst, keys, values);
549 }
550 */
551
552
553};
554
555
556
557
558} // drain
559
560
561#endif // Drain
Definition Castable.h:76
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:666
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
General purpose tools for handling values and keys of std::map<>
Definition SmartMapTools.h:56
static const M::mapped_type & get(const M &m, const typename M::key_type &key)
If the key is found, the value is returned as a reference.
Definition SmartMapTools.h:69
static void get(const M &m, const typename M::key_type &key, F &value)
If the key is found, the value is assigned.
Definition SmartMapTools.h:90
A base class for smart maps providing methods for importing and exporting values, among others.
Definition SmartMapTools.h:106
static void setValue(M &dst, const std::string &key, const V &value)
Utility for "guessing" key order. Derived classes will redefine this e.g. for ordered maps.
Definition SmartMapTools.h:133
static void setValues(M &dst, std::initializer_list< V > values)
Definition SmartMapTools.h:519
static void updateValues(M &dst, const std::map< std::string, S > &src)
Definition SmartMapTools.h:205
static void updateCastableValues(M &dst, const std::map< std::string, S > &src)
Definition SmartMapTools.h:215
static void setValues(M &dst, const std::list< std::string > &values, char equalSign='=', const std::string &trimChars="")
Assign values from list, accepting strict "<key>=<value>" format, no positional arguments.
Definition SmartMapTools.h:229
static void updateValues(M &dst, const std::list< std::string > &keys, const std::list< std::string > &entries, char equals='=')
Definition SmartMapTools.h:421
static void setValues(M &dst, const std::map< std::string, S > &srcMap)
Definition SmartMapTools.h:176
static void updateValue(M &dst, const std::string &key, const V &value)
Set value only if key exists.
Definition SmartMapTools.h:166
static void updateValues(M &dst, const std::string &values, char split=',', char equals='=')
Definition SmartMapTools.h:453
static void setValues(M &dst, const std::list< std::string > &keys, const std::list< std::string > &entries, char assignmentSymbol='=')
Assign values from list, accepting keyword arguments <key>=,<key2>=<value2> and positional arguments...
Definition SmartMapTools.h:311
static void setValues(M &dst, const std::list< std::string > &keys, std::initializer_list< V > values)
Assign values from string, accepting keyword arguments <key>=,<key2>=<value2> and positional argumen...
Definition SmartMapTools.h:498
static void updateValues(M &dst, const std::list< std::string > &values, char equals='=')
Assign values from list, accepting strict "<key>=<value>" format, no positional arguments.
Definition SmartMapTools.h:297
static void updateValues(M &dst, const std::list< std::string > &keys, const std::string &values, char split=',', char equals='=')
Definition SmartMapTools.h:483
static void setValues(M &dst, std::initializer_list< std::pair< K, V > > values)
NEW 2025.
Definition SmartMapTools.h:537
static void setValues(M &dst, const std::string &values, char split=',', char equals='=', const std::string &trimChars="")
Assign values from string, assuming strict "<key>=<value>" format, no positional arguments.
Definition SmartMapTools.h:439
static void setValues(M &dst, const std::list< std::string > &keys, const std::string &values, char split=',', char equals='=')
Assign values from string, accepting keyword arguments <key>=,<key2>=<value2> and positional argumen...
Definition SmartMapTools.h:467
static bool split2(const std::string &s, T1 &first, T2 &second, const C &separators, const std::string &trimChars=" \t\n")
Splits and trims a given std::string to a std Sequence.
static std::string trim(const std::string &s, const std::string &trimChars=" \t\n\r")
Returns a string without leading and trailing whitespace (or str undesired chars).
Definition String.cpp:170
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
VariableT is a final class applied through typedefs Variable, Reference and FlexibleVariable.
Definition VariableT.h:87
Definition DataSelector.cpp:1277