Loading...
Searching...
No Matches
MapTools.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_MAP_TOOLS_H
32#define DRAIN_MAP_TOOLS_H
33
34#include <iostream>
35#include <string>
36#include <set>
37#include <list>
38#include <vector>
39#include <map>
40// #include <stdlib.h>
41// #include <sys/syslog.h>
42// #include <syslog.h>
43
44#include "Log.h"
45#include "Sprinter.h"
46#include "StringTools.h"
47
48
49namespace drain {
50
52class MapTools {
53
54public:
55
57
63 template <class M>
64 static
65 const typename M::mapped_type & get(const M & m, const typename M::key_type & key){
66 typename M::const_iterator it = m.find(key);
67 if (it != m.end()){
68 return it->second;
69 }
70 else {
71 static const typename M::mapped_type empty;
72 return empty;
73 }
74 }
75
76
77
78 typedef std::list<std::string> keylist_t;
79
80
81
83
87 template <class M,class V,bool STRICT=true>
88 static
89 void setValue(M & dst, const std::string & key, const V & value) {
90 if (STRICT){
91 dst[key] = value; // throws exception in derived classes!
92 }
93 else {
94 //typename std::map<std::string,T>::iterator it = dst.find(key);
95 typename M::iterator it = dst.find(key);
96 if (it != dst.end()){
97 it->second = value;
98 }
99 else {
100 //std::cerr << __FILE__ << ':' << __FUNCTION__ << ": key '" << key << "' not found\n";
101 }
102 }
103 }
104
105 template <class M,class V>
106 static inline
107 void setValue(M & dst, const std::string & key, const V & value, bool STRICT) {
108 if (STRICT)
109 setValue<M,V,true>(dst, key, value);
110 else
111 setValue<M,V,false>(dst, key, value);
112 }
113
114
116
120 template <class M,class V>
121 static inline
122 void updateValue(M & dst, const std::string & key, const V & value) {
123 setValue<M,V,false>(dst, key, value);
124 }
125
126
130 template <class M,class S,bool STRICT=true>
131 static
132 void setValues(M & dst, const std::map<std::string,S> & srcMap) {
133 // std::cerr << __FUNCTION__ << ':' << typeid(M).name() << " <= map<str," << typeid(S).name() << ">\n";
134 for (const typename std::map<std::string,S>::value_type & entry: srcMap){
135 setValue<M,S,STRICT>(dst, entry.first, entry.second);
136 }
137 }
138
139
140
141
146 template <class M,class S>
147 static inline
148 void updateValues(M & dst, const std::map<std::string,S> & src) {
149 setValues<M,S,false>(dst, src);
150 }
151
152
154
161 template <class M, bool STRICT=true>
162 static
163 void setValues(M & dst, const std::list<std::string> & values, char equalSign='=', const std::string & trimChars = "") {
164
165 const bool TRIM = !trimChars.empty();
166
167 for (const std::string & entry: values){
168
169 if (entry.empty()){
170
171 Logger mout(__FILE__, __FUNCTION__);
172 if (values.size()==1){
173 //std::cerr << __FILE__ << ':' << __
174 mout.experimental("clearing a map of ", dst.size(), " elements");
175 dst.clear();
176 return;
177 }
178 else {
179 mout.debug("parameter list contained an empty value (ok)");
180 continue;
181 }
182
183 }
184
185 const size_t i = entry.find(equalSign);
186 if (i != std::string::npos){
187 if (i == (entry.length()-1)){
188 if (TRIM){
189 setValue<M,std::string,STRICT>(dst, StringTools::trim(entry, trimChars), ""); // todo: touch
190 }
191 else {
192 setValue<M,std::string,STRICT>(dst, entry, ""); // todo: touch
193 }
194 }
195 else {
196 if (TRIM){
197 setValue<M,std::string,STRICT>(dst, StringTools::trim(entry.substr(0, i)), StringTools::trim(entry.substr(i+1)));
198 }
199 else {
200 setValue<M,std::string,STRICT>(dst, entry.substr(0, i), entry.substr(i+1));
201 }
202 }
203 }
204 else {
205 for (const std::string & e: values){
206 std::cerr << '"' << e << '"' << std::endl;
207 }
208 // TODO: warn dump
209 throw std::runtime_error(entry + ": positional args without keys");
210 }
211 }
212 }
213
214
215
217
222 template <class M>
223 static inline
224 void updateValues(M & dst, const std::list<std::string> & values, char equals='=') {
225 setValues<M,false>(dst, values, equals);
226 }
227
229
235 // Potential for allowed-keys-only policy (hidden/read-only entries)
236 template <class M, bool STRICT=true>
237 static
238 void setValues(M & dst, const std::list<std::string> & keys, const std::list<std::string> & entries, char assignmentChar='=') {
239
240 Logger mout(__FILE__, __FUNCTION__);
241
242
243 // 2026: use char in split2
244 //const std::string assignmentSymbols(1, assignmentSymbol);
245
246 std::list<std::string>::const_iterator kit = keys.begin();
247
248 bool acceptOrderedParams = true;
249
250 // mout.warn(" assignmentSymbol: " , assignmentSymbol );
251 // mout.warn(" size: " , this->size() );
252 for (const std::string & entry: entries){
253
254 //for (std::list<std::string>::const_iterator pit = p.begin(); pit != p.end(); ++pit){
255 //mout.warn(" entry: " , *pit );
256
257 // Check specific assignment, ie. check if the key=value is given explicitly.
258 if (assignmentChar){ // typically '='
259
260 std::string key, value;
261
262 //if (StringTools::split2(entry, key, value, assignmentSymbols)){
263 if (StringTools::split2(entry, key, value, assignmentChar)){
264
265 // mout.warn(" specified " , key , "=\t" , value );
266
267 if (dst.size()==1){
268 /*
269 * This special handling is for single-element maps
270 * "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
271 */
272 typename M::iterator it = dst.begin();
273 if (key == it->first)
274 it->second = value;
275 else {
276 it->second = entry;
277 // mout.warn("is this in use?" , it->first , " <= '" , entry , "'" );
278 }
279 return;
280 }
281
282 setValue<M,std::string,STRICT>(dst, key, value); //, criticality);
283 acceptOrderedParams = false;
284 continue;
285 }
286 else {
287 // mout.warn(" could not split: " , *pit );
288 }
289 }
290
291 // Key and assignment symbol not given.
292
293 if (kit != keys.end()){
294 // Assignment-by-order
295 if (!acceptOrderedParams){
296 mout.warn("positional arg '" , entry , "' for [", *kit , "] given after explicit args" );
297 }
298 //mout.warn(" ordered " , );
299 dst[*kit] = entry; // does not need to call import() because *kit exists.
300 ++kit; // NUEVO
301 }
302 else {
303 //mout.log(criticality)
304 // << "too many (over "<< this->size() << ") params, run out of keys with entry=" << *pit << mout.endl;
305 if (STRICT){
306 mout.error("too many (over ", dst.size() , ") params, run out of keys with entry=" , entry );
307 }
308
309 }
310
311
312 }
313
314
315 }
316
323 template <class M>
324 static inline
325 void updateValues(M & dst, const std::list<std::string> & keys, const std::list<std::string> & entries, char equals='=') {
326 setValues<false>(dst, keys, entries, equals);
327 }
328
329
331
341 template <class M, bool STRICT=true>
342 static
343 void setValues(M & dst, const std::string & values, char split=',', char equals='=', const std::string & trimChars = "") {
344 std::list<std::string> l;
345 drain::StringTools::split(values, l, split);
346 setValues<M,STRICT>(dst, l, equals, trimChars);
347 }
348
355 template <class M>
356 static inline
357 void updateValues(M & dst, const std::string & values, char split=',', char equals='=') {
358 setValues<false>(dst, values, split, equals);
359 }
360
362
369 template <class M, bool STRICT=true>
370 static
371 void setValues(M & dst, const std::list<std::string> & keys, const std::string & values, char split=',', char equals='=') {
372 std::list<std::string> l;
373 drain::StringTools::split(values, l, split);
374 setValues(dst, keys, l, equals);
375 }
376
377
385 template <class M>
386 static inline
387 void updateValues(M & dst, const std::list<std::string> & keys, const std::string & values, char split=',', char equals='=') {
388 setValues<false>(dst, keys, values, split, equals);
389 }
390
392
400 template <class M, class V, bool STRICT=true>
401 static
402 void setValues(M & dst, const std::list<std::string> & keys, std::initializer_list<V> values) {
403
404 std::list<std::string>::const_iterator kit = keys.begin();
405
406 for (const V & value: values){
407 if (kit == keys.end()){
408 throw std::runtime_error(std::string(__FILE__) + " run out of keys");
409 }
410 setValue(dst, *kit, value);
411 ++kit;
412 }
413 }
414
421 template <class M, class V>
422 static
423 void setValues(M & dst, std::initializer_list<V> values) {
424
425 //typename std::map<std::string,T>::const_iterator it = dst.begin();
426 typename M::const_iterator it = dst.begin();
427
428 for (const V & value: values){
429 if (it == dst.end()){
430 throw std::runtime_error(std::string(__FILE__) + " run out of keys");
431 }
432 setValue(dst, it->first, value);
433 ++it;
434 }
435 }
436
438 // Designed for: const std::initializer_list<std::pair<const char *,const char *> >
439 template <class M, typename K, typename V>
440 static
441 void setValues(M & dst, std::initializer_list<std::pair<K,V> > values) {
442 for (const auto & entry: values){
443 setValue(dst, entry.first, entry.second);
444 }
445 }
446
447
448 /*
449 template <class T, class T2>
450 static inline
451 void updateValues(std::map<std::string,T> & dst, const std::list<std::string> & keys, std::initializer_list<T2> values) {
452 setValues<false>(dst, keys, values);
453 }
454 */
455
456
457};
458
459
460
461
462} // drain
463
464
465#endif // Drain
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:431
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:667
Logger & error(const TT &... args)
Echoes.
Definition Log.h:417
General purpose tools for handling values and keys of std::map<>
Definition MapTools.h:52
static void setValue(M &dst, const std::string &key, const V &value)
Set value of an element. If not STRICT, set only if key exists ie update.
Definition MapTools.h:89
static void setValues(M &dst, std::initializer_list< V > values)
Definition MapTools.h:423
static void updateValues(M &dst, const std::map< std::string, S > &src)
Definition MapTools.h:148
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 MapTools.h:163
static void updateValues(M &dst, const std::list< std::string > &keys, const std::list< std::string > &entries, char equals='=')
Definition MapTools.h:325
static void setValues(M &dst, const std::map< std::string, S > &srcMap)
Definition MapTools.h:132
static void updateValue(M &dst, const std::string &key, const V &value)
Set value only if key exists.
Definition MapTools.h:122
static void updateValues(M &dst, const std::string &values, char split=',', char equals='=')
Definition MapTools.h:357
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 MapTools.h:402
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 MapTools.h:224
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 MapTools.h:65
static void setValues(M &dst, const std::list< std::string > &keys, const std::list< std::string > &entries, char assignmentChar='=')
Assign values from list, accepting keyword arguments <key>=,<key2>=<value2> and positional arguments...
Definition MapTools.h:238
static void updateValues(M &dst, const std::list< std::string > &keys, const std::string &values, char split=',', char equals='=')
Definition MapTools.h:387
static void setValues(M &dst, std::initializer_list< std::pair< K, V > > values)
NEW 2025.
Definition MapTools.h:441
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 MapTools.h:343
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 MapTools.h:371
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 StringTools.cpp:239
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 StringTools.h:479
Definition DataSelector.cpp:1277