Loading...
Searching...
No Matches
Flags.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
32#ifndef DRAIN_FLAGS
33#define DRAIN_FLAGS
34
35#include <iostream>
36#include <list>
37#include <iterator>
38#include <iostream>
39#include <list>
40#include <sstream>
41#include <stdexcept>
42//#include <typeinfo>
43#include <stdlib.h>
44
45#include <drain/Log.h>
46#include <drain/StringTools.h>
47#include <drain/Type.h>
48
49#include "Dictionary.h"
50
51#include "FlagBase.h"
52
53namespace drain {
54
55
56/*
57template <typename E>
58const SprinterLayout drain::FlaggerBase<E>::dictLayout = {",", "?", "=", ""};
59*/
60
61
62
63
64
66
69template <typename E>
70class SingleFlagger : public FlaggerBase<E,E> {
71
72public:
73
74 //typedef typename FlaggerBase<E>::dict_value_t dict_value_t;
75 typedef E value_t;
76 typedef E storage_t;
77
79 // typedef typename EnumDict<E>::dict_t dict_t;
80 typedef typename flagger_t::dict_t dict_t;
81 typedef typename dict_t::key_t key_t; // ~string
82
83protected:
84
85 const dict_t & dict;
86 // dict_t ownDict;
87
88public:
89
90 virtual
91 const dict_t & getDict() const override {
92 return dict;
93 };
94
95
96 inline
97 SingleFlagger(const dict_t & dict) : dict(dict) {
98 };
99
100 /***
101 *
102 * storage_t == value_t
103 */
104 inline
105 SingleFlagger(const dict_t & dict, const storage_t &v) : dict(dict) {
106 this->value = v;
107 };
108
109
110 /***
111 *
112 * storage_t == value_t
113 */
114 inline
115 SingleFlagger(const dict_t & dict, storage_t & v, char sep=',') : flagger_t(v, sep), dict(dict){
116 };
117
118
119 virtual inline
120 ~SingleFlagger(){};
121
122
124 virtual
125 bool isSet(const storage_t & x) const override {
126 return (this->value == x);
127 };
128
129 // Start copy Base
130 virtual inline
131 void set(const key_t & key){
132 if (key.empty())
133 return; // needed?
134 assign(key);
135 }
136
138 virtual inline
139 void set(const value_t & value){
140 this->value = value;
141 };
142
143 virtual inline
144 void set(const FlaggerBase<E> & flagger){
145 this->value = flagger.value;
146 }
147
148 // END Base
149
150 template <class T>
151 inline
152 SingleFlagger<E> & operator=(const T & v){
153 this->set(v);
154 return *this;
155 }
156
158 virtual inline
159 const key_t & str() const override {
160 return this->getDict().getKey(this->value);
161 }
162
163protected:
164
166
171 virtual
172 void assign(const std::string & key) override {
173
174 // NO this->set(s);
175
176 if ((key.find(',')!= std::string::npos)||(key.find('|')!= std::string::npos)){
177 Logger mout(__FILE__, __FUNCTION__);
178 mout.unimplemented<LOG_ERR>(__FILE__, ':', TypeName<E>::str(), ": multi-key arg: '"+ key, "', for single-flagger: ", sprinter(this->getDict().getKeys()));
179 }
180
181 if (this->getDict().hasKey(key)){
182 this->value = static_cast<storage_t>(this->getDict().getValue(key)); // Cast needed (only) if MultiFlagger converts enum value_t -> storage_t
183 }
184 else {
185 Logger mout(__FILE__, __FUNCTION__);
186 value_t v = static_cast<value_t>(atoi(key.c_str()));
187 if (!this->getDict().hasValue(v)){
188 mout.suspicious("value: ", v, " corresponds to no value in dict:", this->getDict());
189 //mout.error(__FILE__, ':', TypeName<E>::str(), ": no such key: '"+ key, "', keys=", sprinter(this->getDict().getKeys()));
190 mout.error("Flagger@", TypeName<E>::str(), ": no such key: '"+ key, "', dict=", sprinter(this->getDict()));
191 }
192 // this->value = FlagResolver::getIntValue(this->getDict(), key); // SingleFlagger does not like this.
193 // throw std::runtime_error(std::string("Dictionary[") + typeid(dict_value_t).name()+ "]: no such key: "+ key);
194 this->value = v;
195 }
196
197 };
198
199
200
201};
202
203template <typename E>
204inline
205std::ostream & operator<<(std::ostream & ostr, const drain::SingleFlagger<E> & flagger) {
206 ostr << flagger.str();
207 return ostr;
208}
209
210
212
219template <typename E, typename T=size_t>
220class MultiFlagger : public FlaggerBase<E,T> { // <E,FlagResolver::ivalue_t> { //
221
222public:
223
224 typedef E value_t;
225 typedef T storage_t;
227 //typedef FlagResolver::ivalue_t storage_t;
228 //typedef FlaggerBase<E,FlagResolver::ivalue_t> flagger_t;
229 typedef typename flagger_t::dict_t dict_t;
230 typedef typename dict_t::key_t key_t; // ~string
231
232
233 inline
234 MultiFlagger(const dict_t & dict) : dict(dict) {
235 };
236
237 template <typename ... V>
238 inline
239 MultiFlagger(const dict_t & dict, const V &... args) : dict(dict) {
240 set(args...);
241 };
242
246 inline
247 MultiFlagger(const dict_t & dict, storage_t & target, char sep=',') : flagger_t(target, sep), dict(dict){
248 };
249
250 virtual inline
251 ~MultiFlagger(){};
252
253
254 virtual inline
255 const dict_t & getDict() const override {
256 return dict;
257 };
258
260
264 virtual inline
265 bool isSet(const storage_t & x) const override {
266 return ((this->value & x) == x);
267 };
268
270 inline
271 bool isAnySet(const storage_t & x) const {
272 return ((this->value & x) != 0);
273 };
274
276 inline
277 void unset(const storage_t & x){
278 this->value = (this->value & ~x);
279 //return ((this->value & x) == x);
280 }
281
283
289 template <typename ... V>
290 inline
291 void set(const V &... args) {
292 this->reset();
293 add(args...);
294 }
295
296
298 template <typename V, typename ...VV>
299 inline
300 void add(const V & arg, const VV &... args) {
301 //std::cerr << __FUNCTION__ << ':' << arg << std::endl;
302 addOne(arg);
303 add(args...);
304 }
305
307 virtual
308 const key_t & str() const override {
309 // const dict_t & dict = this->getDict();
310 currentStr = FlagResolver::getKeys(this->getDict(), this->value, this->separator);
311 return currentStr;
312 }
313
314
316 virtual
317 std::string & str(){
318 // NEW: also non-const is updated
319 // const dict_t & dict = this->getDict();
320 currentStr = FlagResolver::getKeys(this->getDict(), this->value, this->separator);
321 return currentStr; // CHECK USAGE
322 }
323
324
325
326protected:
327
328 const dict_t & dict;
329
331 virtual
332 void assign(const std::string & s) override {
333 const dict_t & dict = this->getDict();
334 this->value = FlagResolver::getIntValue(dict, s, this->separator); // uses dict.separator if needed
335 }
336
337
338 inline
339 void add(){};
340
341 inline
342 void addOne(const key_t & key){
343 // Resolves also "" and numeric keys.
344 this->value |= FlagResolver::getIntValue(this->getDict(), key, this->separator);
345 }
346
347 // New
348 inline
349 void addOne(const storage_t & value){
350 this->value |= value;
351 }
352
353 template <typename T2>
354 inline
355 void addOne(const T2 & value){
356 // why OR op in dvalue
357 // this->value = static_cast<dict_value_t>((dvalue_t)this->value | (dvalue_t)value);
358 this->value |= static_cast<value_t>(value);
359 }
360
361 mutable
362 std::string currentStr;
363
364
365};
366
367
368
369template <typename E,typename T>
370inline
371std::ostream & operator<<(std::ostream & ostr, const drain::MultiFlagger<E,T> & flagger) { // ,T
372 return FlagResolver::keysToStream(flagger.getDict(), flagger.getValue(), ostr);
373}
374
375
376
377
378
379
381
388template <class F>
389class Flags2 : public F {
390
391public:
392
393 typedef F fbase_t;
394 typedef typename F::value_t value_t;
395 typedef typename F::dict_t dict_t;
396
397
398 virtual
399 const dict_t & getDict() const {
400 return dict;
401 };
402
403 virtual
404 dict_t & getDict(){
405 return dict;
406 };
407
408
410
414 inline
416 };
417
419
424 inline
425 Flags2(const std::initializer_list<typename dict_t::entry_t> & list) : dict(list){
426 };
427
428 inline
429 Flags2(const Flags2<F> & flags) : dict(flags.dict){
430 }
431
432 template <class T>
433 inline
434 Flags2<F> & operator=(const T & v){
435 this->set(v);
436 return *this;
437 }
438
439protected:
440
441 // Consider inherited dictionary, through a wrapper (first inherit, to guarantee init ref validity?).
442 dict_t dict;
443
444
445};
446
447
448
449} // drain::
450
451
452#endif
Two-way mapping between strings and objects of template class T.
Definition Dictionary.h:63
const K & getKey(const V &value, bool lenient=true) const
Identity mapping useful for type deduction of template arguments in functions.
Definition Dictionary.h:172
const V & getValue(const K &key, bool lenient=true) const
Given a key, return the first value associated with it.
Definition Dictionary.h:149
bool hasValue(const V &value) const
Given a key, return the first value associated with it.
Definition Dictionary.h:143
static ivalue_t getIntValue(const drain::Dictionary< key_t, T > &dict, const std::string &keys, char separator=',')
Computes bitwise OR function on the numeric or alphabetic value(s) presented by a string.
Definition FlagBase.h:199
static std::ostream & keysToStream(const drain::Dictionary< key_t, T > &dict, ivalue_t value, std::ostream &ostr, char separator=',')
Write keys in a stream, in numeric order.
Definition FlagBase.h:278
static std::string getKeys(const drain::Dictionary< key_t, T > &dict, ivalue_t, char separator=',')
Given an integer, retrieves dictionary keys corresponding to each index of set bits.
Definition FlagBase.h:266
Definition FlagBase.h:361
Flagger with own dictionary, and accepting values of (integer) type T.
Definition Flags.h:389
Flags2()
Definition Flags.h:415
Flags2(const std::initializer_list< typename dict_t::entry_t > &list)
Constructor for relatively short dictionaries.
Definition Flags.h:425
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & error(const TT &... args)
Echoes.
Definition Log.h:417
Logger & suspicious(const TT &... args)
A weak warning about something going possibly wrong.
Definition Log.h:501
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:512
Definition Flags.h:220
virtual std::string & str()
For importing values. After assignment, update() should be called. Experimental.
Definition Flags.h:317
void unset(const storage_t &x)
Unset some bit(s).
Definition Flags.h:277
MultiFlagger(const dict_t &dict, storage_t &target, char sep=',')
Definition Flags.h:247
void add(const V &arg, const VV &... args)
Add bit values.
Definition Flags.h:300
virtual void assign(const std::string &s) override
Split a string to separate keys and/or values and set them.
Definition Flags.h:332
virtual bool isSet(const storage_t &x) const override
Return true, all the bits of argument x are set.
Definition Flags.h:265
bool isAnySet(const storage_t &x) const
Return true, all the bits of argument x are set.
Definition Flags.h:271
void set(const V &... args)
Set bits, accepting numeric values or keys.
Definition Flags.h:291
virtual const dict_t & getDict() const override
Returns the static dictionary created for this value_t .
Definition Flags.h:255
virtual const key_t & str() const override
For exporting values.
Definition Flags.h:308
Definition Flags.h:70
virtual void set(const value_t &value)
Set a single flag.
Definition Flags.h:139
virtual bool isSet(const storage_t &x) const override
Return true, if value is exactly x .
Definition Flags.h:125
virtual const dict_t & getDict() const override
Returns the static dictionary created for this value_t .
Definition Flags.h:91
virtual const key_t & str() const override
String corresponding the current value. Returns empty, if not found.
Definition Flags.h:159
virtual void assign(const std::string &key) override
Assign key. Expects a single key, not a combination of keys.
Definition Flags.h:172
Definition DataSelector.cpp:1277
Default implementation.
Definition Type.h:541