Loading...
Searching...
No Matches
ReferenceMap.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//#include <typeinfo>
32#include <drain/Log.h>
33#include <stdexcept>
34//#include <iostream>
35//#include <vector>
36#include <string>
37
38#include <map>
39#include <list>
40
41
42#include <drain/Reference.h>
43#include <drain/String.h>
44
45#include "Range.h"
46// #include "FlexibleVariable.h"
47//#include "ReferenceVariable.h"
48
49#include "SmartMap.h"
50
51
52#ifndef REFERENCE_MAP
53#define REFERENCE_MAP
54
55
56namespace drain {
57
59
68template <class T=Reference>
69class ReferenceMap2 : public SmartMap<T> {
70
71public:
72
73 typedef T ref_t;
74 typedef SmartMap<T> map_t;
75
76
78
82 template <class F>
83 inline
84 ref_t & link(const std::string & key, F &x){
85
86 ref_t & r = (*this)[key];
87 r.link(x); // .setSeparator(this->arraySeparator);
88 return r;
89
90 }
91
93 inline
94 ref_t & link(const std::string & key, void *ptr, const std::type_info &type, size_t count=1){
95
96 ref_t & r = (*this)[key];
97 r.link(ptr, type, count);
98 return r;
99
100 /*
101 if (this->find(key) == this->end()) // not already referenced
102 this->keyList.push_back(key);
103
104 Reference & r = map_t::operator[](key);
105 r.setSeparator(this->arraySeparator); // applicable, if array type element
106 r.link(ptr, type, count);
107 // unitMap[key] = unit;
108 return r;
109 */
110 }
111
112 inline
113 void unlink(const std::string & key){
114 map_t::erase(key);
115 for (std::list<std::string>::iterator it = this->keyList.begin(); it != this->keyList.end(); ++it){
116 if (*it == key){
117 this->keyList.erase(it);
118 break;
119 }
120 }
121 //unitMap.erase(key);
122 }
123
124
134
136
143 template <class T2>
144 //static // Start with T. Todo: consider other
145 void copyStruct(const ReferenceMap2<T> & m, const T2 & src, T2 & dst, extLinkPolicy policy=RESERVE) {
146 //, bool copyValues = true, bool linkExternal = false){
147
148 Logger mout(__FILE__, __FUNCTION__);
149 long s = sizeof(T2); // yes signed
150 //mout.warn("experimental, obj.size=" , s );
151
152 // Clearing is bad, it resets work of base class constructors
153 // if (policy==LINK)
154 // clear();
155
156 typedef unsigned long addr_t;
157 typedef long addr_diff_t;
158
159 const addr_t srcAddr = (addr_t)(&src);
160 const addr_t dstAddr = (addr_t)(&dst);
161 //for (std::list<std::string>::const_iterator it = m.getKeyList().begin(); it != m.getKeyList().end(); ++it){
162 for (const std::string & key: m.getKeyList()){
163 // const std::string & key = *it;
164 const ref_t & srcRef = m[key];
165 addr_t srcVarAddr = (addr_t)srcRef.getPtr();
166 addr_diff_t relativeAddr = srcVarAddr - srcAddr;
167 if ((relativeAddr >= 0) && (relativeAddr < s)){ // INTERNAL
168 //Reference & dstMemberRef = (*this)[key];
169 ref_t & dstMemberRef = link(key, (void *)(dstAddr + relativeAddr), srcRef.getType(), srcRef.getElementCount());
170 //mout.warn("local: " , key , ':' , srcRef.getElementCount() );
171 dstMemberRef.copyFormat(srcRef);
172 dstMemberRef.assignCastable(srcRef); // value
173 }
174 else {
175 //mout.warn("external: " , key );
176 switch (policy) {
177 case LINK:
178 link(key, (void *)srcVarAddr, srcRef.getType(), srcRef.getElementCount()).copyFormat(srcRef);
179 break;
180 case RESERVE:
181 // reserve(key);
182 (*this)[key];
183 //mout.warn("reserved: " , key );
184 //mout.warn("keyList: " , getKeys() );
185 break;
186 case SKIP:
187 mout.debug("skipping external variable: '" , key , '=' , srcRef , "' relative addr=" , relativeAddr );
188 break;
189 case ERROR:
190 mout.error("external variable: '" , key , '=' , srcRef , "' relative addr=" , relativeAddr );
191 break;
192 default:
193 mout.warn("unknown enum option in handling external variable '" , key , '=' , srcRef , "' relative addr=" , relativeAddr );
194 }
195 }
196 }
197 }
198};
199
200
202
206// TODO: consider clear() (shallow op)
207class ReferenceMap : public SmartMap<Reference> {//public std::map<std::string,Reference> {
208
209public:
210
212
215 // ReferenceMap(bool ordered, char separator) : SmartMap<Reference>(ordered, separator){}; //, STRICTLY_CLOSED, keys(orderedKeyList), units(unitMap)
216 ReferenceMap(char separator=',') : SmartMap<Reference>(separator){}; //, STRICTLY_CLOSED, keys(orderedKeyList), units(unitMap)
217
219 inline
222
223 inline virtual
224 ~ReferenceMap(){};
225
226 // Temporary catch for Range
227 template <class F>
228 Reference & link(const std::string & key, Range<F> &x, const std::string & unit = std::string()){
229 Logger mout(__FILE__, __FUNCTION__);
230 mout.deprecating(" type drain::Range<> use .tuple() instead: ", key, '[', unit, ']');
231 return link(key, &x, typeid(F), 2, unit);
232 }
233
235
239 template <class F>
240 Reference & link(const std::string & key, F &x, const std::string & unit = std::string()){
241
242 if (find(key) == end()){ // not already referenced
243
244 if (keyList.empty()){
245 if (key.empty()){
246 std::cerr << "empty key referencing to " << sprinter(x) << " unit=" << unit << std::endl;
247 }
248 else if (key.at(0) == '_'){
249 throw std::runtime_error(key + ": hidden parameters can be added only after visible");
250 }
251 }
252 else if ((keyList.back().at(0) == '_') && (key.at(0) != '_')){
253 throw std::runtime_error(key + ": cannot add visible parameters after hidden");
254 }
255
256
257 keyList.push_back(key);
258
259 }
260
261 // Create
262 Reference & r = std::map<std::string,Reference>::operator[](key);
263 r.setSeparator(arraySeparator); // applicable, if array type element
264 // Link
265 r.link(x);
266 unitMap[key] = unit;
267 return r;
268 }
269
270 inline
271 Reference & link(const std::string & key, Reference &x, const std::string & unit = std::string()){
272 return link(key, x.getPtr(), x.getType(), x.getElementCount(), unit); //.fillArray = item.fillArray;
273 }
274
275
277 inline
278 Reference & link(const std::string & key, void *ptr, const std::type_info &type, size_t count, const std::string & unit = std::string()){
279
280 if (find(key) == end()) // not already referenced
281 keyList.push_back(key);
282
283 Reference & r = std::map<std::string,Reference>::operator[](key);
284 r.setSeparator(arraySeparator); // applicable, if array type element
285 r.link(ptr, type, count);
286 unitMap[key] = unit;
287 return r;
288
289 }
290
292 inline
293 Reference & link(const std::string & key, void *ptr, const std::type_info &type, const std::string & unit = std::string()){
294 return link(key, ptr, type, 1, unit);
295 }
296
298
302 template <class F>
303 Reference & referenceTop(const std::string & key, F &x, const std::string & unit = std::string()){
304
305 if (find(key) != end()) // already referenced
306 keyList.push_front(key);
307
308 //Reference & r = std::map<std::string,Reference>::operator[](key).link(x);
309 Reference & r = std::map<std::string,Reference>::operator[](key);
310 r.setSeparator(arraySeparator); // applicable, if array type element
311 // Link
312 r.link(x);
313
314 unitMap[key] = unit;
315 return r;
316 }
317
318
320 void append(ReferenceMap & rMap, bool replace=true){
321 //std::cerr << __FILE__ << " -> " << __FUNCTION__ << std::endl;
322 const std::list<std::string> & keys = rMap.getKeyList();
323 //for (std::list<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it){
324 for (const std::string & key: keys){
325 //std::cerr << " -> " << *it << std::endl;
326 if (replace || !hasKey(key)){
327 Reference & srcItem = rMap[key];
328 Reference & item = link(key, srcItem, rMap.unitMap[key]); //.fillArray = item.fillArray;
329 // Reference & item = link(key, (const Castable &)srcItem, rMap.unitMap[key]); //.fillArray = item.fillArray;
330 // Reference & item = link(key, srcItem.getPtr(), srcItem.getType(), srcItem.getElementCount(), rMap.unitMap[key]); //.fillArray = item.fillArray;
331 item.setFill(srcItem.fillArray);
332 item.setInputSeparator(srcItem.getInputSeparator());
333 item.setOutputSeparator(srcItem.getOutputSeparator());
334 }
335 }
336 }
337
338 // todo: consider NULL? (but leads to problems)
339
341 inline
342 void delink(const std::string & key){
343 std::map<std::string,Reference>::erase(key);
344 for (std::list<std::string>::iterator it = keyList.begin(); it != keyList.end(); ++it)
345 if (*it == key){
346 keyList.erase(it);
347 break;
348 }
349 unitMap.erase(key);
350 }
351
353
357 void reserve(const std::string & key){
358
359 if (find(key) == end()) // not already referenced
360 keyList.push_back(key);
361
362 // Create
363 // Reference & r =
364 std::map<std::string,Reference>::operator[](key);
365 // Now r type is unset. (ptr undefined)
366
367 }
368
370
373 virtual inline
374 void clear(){
376 keyList.clear();
377 unitMap.clear();
378 }
379
389
391
398 template <class T>
399 void copyStruct(const ReferenceMap & m, const T & src, T & dst, extLinkPolicy policy=RESERVE) {
400 //, bool copyValues = true, bool linkExternal = false){
401
402 Logger mout(__FILE__, __FUNCTION__);
403 long s = sizeof(T); // yes signed
404 //mout.warn("experimental, obj.size=" , s );
405
406 // Clearing is bad, it resets work of base class constructors
407 // if (policy==LINK)
408 // clear();
409
410 typedef unsigned long addr_t;
411 typedef long addr_diff_t;
412
413 const addr_t srcAddr = (addr_t)(&src);
414 const addr_t dstAddr = (addr_t)(&dst);
415 //for (std::list<std::string>::const_iterator it = m.getKeyList().begin(); it != m.getKeyList().end(); ++it){
416 for (const std::string & key: m.getKeyList()){
417 // const std::string & key = *it;
418 const Reference & srcRef = m[key];
419 addr_t srcVarAddr = (addr_t)srcRef.getPtr();
420 addr_diff_t relativeAddr = srcVarAddr - srcAddr;
421 if ((relativeAddr >= 0) && (relativeAddr < s)){ // INTERNAL
422 Reference & dstMemberRef = link(key, (void *)(dstAddr + relativeAddr), srcRef.getType(), srcRef.getElementCount());
423 //mout.warn("local: " , key , ':' , srcRef.getElementCount() );
424 dstMemberRef.copyFormat(srcRef);
425 dstMemberRef = srcRef; // value
426 //dstMemberRef.setInputSeparator(srcRef.getInputSeparator());
427 }
428 else {
429 //mout.warn("external: " , key );
430 switch (policy) {
431 case LINK:
432 link(key, (void *)srcVarAddr, srcRef.getType(), srcRef.getElementCount()).copyFormat(srcRef);
433 break;
434 case RESERVE:
435 reserve(key);
436 //mout.warn("reserved: " , key );
437 //mout.warn("keyList: " , getKeys() );
438 break;
439 case SKIP:
440 mout.debug("skipping external variable: '" , key , '=' , srcRef , "' relative addr=" , relativeAddr );
441 break;
442 case ERROR:
443 mout.error("external variable: '" , key , '=' , srcRef , "' relative addr=" , relativeAddr );
444 break;
445 default:
446 mout.warn("unknown enum option in handling external variable '" , key , '=' , srcRef , "' relative addr=" , relativeAddr );
447 }
448 }
449 }
450
451 // Shared properties.
452 //keyList = m.keyList;
455 unitMap = m.unitMap;
456
457 }
458
459
461 template <class T>
462 inline
464 //Logger log(__FILE__, __FUNCTION__);
465 //log.error() << "in:" << v << log.endl;
466 importMap(v);
467 return *this;
468 }
469
471 virtual
472 mapped_type & operator[](const std::string &key){
473
474 Logger mout(__FILE__, __FUNCTION__);
475
476 iterator it = this->find(key);
477 if (it != this->end()) {
478 return it->second;
479 }
480 else {
481 mout.warn("current contents: " , *this );
482
483 mout.error("key '" , key ,"' not declared (referenced)" );
484 //throw std::runtime_error(key + ": ReferenceMap & operator[] : key not found");
485 static mapped_type empty;
486 return empty;
487 }
488
489 }
490
492 virtual
493 const mapped_type & operator[](const std::string &key) const {
494
495 Logger mout(__FILE__, __FUNCTION__); //Logger mout(__FILE__, __FUNCTION__);
496
497 const_iterator it = this->find(key);
498 if (it != this->end()) {
499 return it->second;
500 }
501 else {
502 mout.error("key '" , key ,"' not declared (referenced)" );
503 //throw std::runtime_error(key + ": ReferenceMap & operator[] : key not found");
504 static const mapped_type empty;
505 return empty;
506 }
507 }
508
509 typedef std::map<std::string,std::string> unitmap_t;
510
512 inline
513 const unitmap_t & getUnitMap() const { return unitMap; };
514
516 /*
517 template <class T>
518 static
519 size_t serialize(const SmartMap<T> & rmap, std::vector<char> & memory);
520 */
521
523
529protected:
530
532 // Questionable: consider SmartReference etc. with caster and unit info?
533 unitmap_t unitMap;
534
535
536};
537
538/*
539template <class T>
540size_t ReferenceMap::serialize(const SmartMap<T> & smap, std::vector<char> & memory){
541
542 typedef SmartMap<T> smap_t;
543
544 size_t i;
545 for (smap_t::const_iterator it = smap.begin(); it != smap.end(); ++it){
546
547 const std::string & key = it->first;
548 const Castable & value = it->second;
549
550 if (v.isString()){
551
553
554 }
555 else {
556 }
557
558 }
559
560}
561*/
562
563} // namespace drain
564
565
566#endif
567
568// Drain
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
A map of references to base type scalars, arrays or std::string; changing values in either are equiva...
Definition ReferenceMap.h:69
ref_t & link(const std::string &key, F &x)
Associates a map entry with a variable.
Definition ReferenceMap.h:84
ref_t & link(const std::string &key, void *ptr, const std::type_info &type, size_t count=1)
Create a reference to a basic type or std::string. (Also for basetype arrays.)
Definition ReferenceMap.h:94
void copyStruct(const ReferenceMap2< T > &m, const T2 &src, T2 &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:145
extLinkPolicy
Definition ReferenceMap.h:128
@ ERROR
Definition ReferenceMap.h:132
@ SKIP
Definition ReferenceMap.h:130
@ LINK
Definition ReferenceMap.h:129
@ RESERVE
Definition ReferenceMap.h:131
Definition ReferenceMap.h:207
Reference & link(const std::string &key, void *ptr, const std::type_info &type, size_t count, const std::string &unit=std::string())
For arrays.
Definition ReferenceMap.h:278
unitmap_t unitMap
Creating a common segment for.
Definition ReferenceMap.h:533
void append(ReferenceMap &rMap, bool replace=true)
Adopts the references of r. If replace==false, only new entries are appended.
Definition ReferenceMap.h:320
Reference & link(const std::string &key, F &x, const std::string &unit=std::string())
Associates a map entry with a variable.
Definition ReferenceMap.h:240
ReferenceMap(char separator=',')
Default constructor.
Definition ReferenceMap.h:216
Reference & link(const std::string &key, void *ptr, const std::type_info &type, const std::string &unit=std::string())
Convenience: create a reference to a scalar. For arrays, use the.
Definition ReferenceMap.h:293
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:399
void reserve(const std::string &key)
Adds a null entry, expecting the link later.
Definition ReferenceMap.h:357
ReferenceMap & operator=(const SmartMap< T > &v)
Import map, adopting the element types.
Definition ReferenceMap.h:463
const unitmap_t & getUnitMap() const
Returns measurement unit information of the actual map entries.
Definition ReferenceMap.h:513
virtual mapped_type & operator[](const std::string &key)
Return element associated with key.
Definition ReferenceMap.h:472
Reference & referenceTop(const std::string &key, F &x, const std::string &unit=std::string())
Associates a map entry with a variable, adding key in the beginning of key list.
Definition ReferenceMap.h:303
virtual void clear()
Removes all the elements of the map.
Definition ReferenceMap.h:374
virtual const mapped_type & operator[](const std::string &key) const
Calling unreferenced key throws an exception.
Definition ReferenceMap.h:493
void delink(const std::string &key)
Removes an entry from the map.
Definition ReferenceMap.h:342
ReferenceMap(const ReferenceMap &rmap)
Copy constructor copies only the separators; does not copy the items.
Definition ReferenceMap.h:220
extLinkPolicy
Definition ReferenceMap.h:383
@ ERROR
Definition ReferenceMap.h:387
@ SKIP
Definition ReferenceMap.h:386
@ LINK
Definition ReferenceMap.h:384
@ RESERVE
Definition ReferenceMap.h:385
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
char arraySeparator
Default separator character for array elements (std::vector's)
Definition SmartMap.h:88
std::list< std::string > keyList
Assigns values from std::string of type "value,value2,...valueN".
Definition SmartMap.h:438
char separator
Default character used for splitting input and output. See setValues.
Definition SmartMap.h:85
virtual const keylist_t & getKeyList() const
Derived versions may produce an ordered set of keys.
Definition SmartMap.h:200
void importMap(const std::map< std::string, S > &m)
Assign values from a map, overriding existing entries.
Definition SmartMap.h:252
VariableT is a final class applied through typedefs Variable, Reference and FlexibleVariable.
Definition VariableT.h:87
Definition DataSelector.cpp:1277
VariableT< ReferenceT< Castable > > Reference
Variable-like that is linked to a standard variable: double, int, std::string . Supports multi-elemen...
Definition Reference.h:78