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 <iostream>
37//#include <typeinfo>
38#include <stdlib.h>
39
40#include <drain/Log.h>
41#include <drain/TypeName.h>
42
43#include "FlagBase.h"
44
45namespace drain {
46
47
48/*
49template <typename E>
50const SprinterLayout drain::FlaggerBase<E>::dictLayout = {",", "?", "=", ""};
51*/
52
53
54
55
56
58
61template <typename E>
62class SingleFlagger : public FlaggerBase<E,E> {
63
64public:
65
66 //typedef typename FlaggerBase<E>::dict_value_t dict_value_t;
67 typedef E value_t;
68 typedef E storage_t;
69
71 // typedef typename Enum<E>::dict_t dict_t;
72 typedef typename flagger_t::dict_t dict_t;
73 typedef typename dict_t::key_t key_t; // ~string
74
75protected:
76
77 const dict_t & dict;
78 // dict_t ownDict;
79
80public:
81
82 virtual
83 const dict_t & getDict() const override {
84 return dict;
85 };
86
87
88 inline
89 SingleFlagger(const dict_t & dict) : dict(dict) {
90 };
91
92 /***
93 *
94 * storage_t == value_t
95 */
96 inline
97 SingleFlagger(const dict_t & dict, const storage_t &v) : dict(dict) {
98 this->value = v;
99 };
100
101
102 /***
103 *
104 * storage_t == value_t
105 */
106 inline
107 SingleFlagger(const dict_t & dict, storage_t & v, char sep=',') : flagger_t(v, sep), dict(dict){
108 };
109
110
111 virtual inline
112 ~SingleFlagger(){};
113
114
116 virtual
117 bool isSet(const storage_t & x) const override {
118 return (this->value == x);
119 };
120
121 // Start copy Base
122 virtual inline
123 void set(const key_t & key){
124 if (key.empty())
125 return; // needed?
126 assign(key);
127 }
128
130 virtual inline
131 void set(const value_t & value){
132 this->value = value;
133 };
134
135 virtual inline
136 void set(const FlaggerBase<E> & flagger){
137 this->value = flagger.value;
138 }
139
140 // END Base
141
142 template <class T>
143 inline
144 SingleFlagger<E> & operator=(const T & v){
145 this->set(v);
146 return *this;
147 }
148
150 virtual inline
151 const key_t & str() const override {
152 return this->getDict().getKey(this->value);
153 }
154
155protected:
156
158
163 virtual
164 void assign(const std::string & key) override {
165
166 // NO this->set(s);
167
168 if ((key.find(',')!= std::string::npos)||(key.find('|')!= std::string::npos)){
169 Logger mout(__FILE__, __FUNCTION__);
170 mout.unimplemented<LOG_ERR>(__FILE__, ':', TypeName<E>::str(), ": multi-key arg: '"+ key, "', for single-flagger: ", sprinter(this->getDict().getKeys()));
171 }
172
173 if (this->getDict().hasKey(key)){
174 this->value = static_cast<storage_t>(this->getDict().getValue(key)); // Cast needed (only) if MultiFlagger converts enum value_t -> storage_t
175 }
176 else {
177 Logger mout(__FILE__, __FUNCTION__);
178 value_t v = static_cast<value_t>(atoi(key.c_str()));
179 if (!this->getDict().hasValue(v)){
180 mout.suspicious("value: ", v, " corresponds to no value in dict:", this->getDict());
181 //mout.error(__FILE__, ':', TypeName<E>::str(), ": no such key: '"+ key, "', keys=", sprinter(this->getDict().getKeys()));
182 mout.error("Flagger@", TypeName<E>::str(), ": no such key: '"+ key, "', dict=", sprinter(this->getDict()));
183 }
184 // this->value = FlagResolver::getIntValue(this->getDict(), key); // SingleFlagger does not like this.
185 // throw std::runtime_error(std::string("Dictionary[") + typeid(dict_value_t).name()+ "]: no such key: "+ key);
186 this->value = v;
187 }
188
189 };
190
191
192
193};
194
195template <typename E>
196inline
197std::ostream & operator<<(std::ostream & ostr, const SingleFlagger<E> & flagger) {
198 ostr << flagger.str();
199 return ostr;
200}
201
202DRAIN_TYPENAME_T0(SingleFlagger,E);
203
205
212template <typename E, typename T=size_t>
213class MultiFlagger : public FlaggerBase<E,T> { // <E,FlagResolver::ivalue_t> { //
214
215public:
216
217 typedef E value_t;
218 typedef T storage_t;
220 //typedef FlagResolver::ivalue_t storage_t;
221 //typedef FlaggerBase<E,FlagResolver::ivalue_t> flagger_t;
222 typedef typename flagger_t::dict_t dict_t;
223 typedef typename dict_t::key_t key_t; // ~string
224
225
226 inline
227 MultiFlagger(const dict_t & dict) : dict(dict) {
228 };
229
230 template <typename ... V>
231 inline
232 MultiFlagger(const dict_t & dict, const V &... args) : dict(dict) {
233 set(args...);
234 };
235
239 inline
240 MultiFlagger(const dict_t & dict, storage_t & target, char sep=',') : flagger_t(target, sep), dict(dict){
241 };
242
243 virtual inline
244 ~MultiFlagger(){};
245
246
247 virtual inline
248 const dict_t & getDict() const override {
249 return dict;
250 };
251
253
257 virtual inline
258 bool isSet(const storage_t & x) const override {
259 return ((this->value & x) == x);
260 };
261
263 inline
264 bool isAnySet(const storage_t & x) const {
265 return ((this->value & x) != 0);
266 };
267
269 inline
270 void unset(const storage_t & x){
271 this->value = (this->value & ~x);
272 //return ((this->value & x) == x);
273 }
274
276
282 template <typename ... V>
283 inline
284 void set(const V &... args) {
285 this->reset();
286 add(args...);
287 }
288
289
291 template <typename V, typename ...VV>
292 inline
293 void add(const V & arg, const VV &... args) {
294 //std::cerr << __FUNCTION__ << ':' << arg << std::endl;
295 addOne(arg);
296 add(args...);
297 }
298
300 virtual
301 const key_t & str() const override {
302 // const dict_t & dict = this->getDict();
303 currentStr = FlagResolver::getKeys(this->getDict(), this->value, this->separator);
304 return currentStr;
305 }
306
307
309 virtual
310 std::string & str(){
311 // NEW: also non-const is updated
312 // const dict_t & dict = this->getDict();
313 currentStr = FlagResolver::getKeys(this->getDict(), this->value, this->separator);
314 return currentStr; // CHECK USAGE
315 }
316
317
318
319protected:
320
321 const dict_t & dict;
322
324 virtual
325 void assign(const std::string & s) override {
326 const dict_t & dict = this->getDict();
327 this->value = FlagResolver::getIntValue(dict, s, this->separator); // uses dict.separator if needed
328 }
329
330
331 inline
332 void add(){};
333
334 inline
335 void addOne(const key_t & key){
336 // Resolves also "" and numeric keys.
337 this->value |= FlagResolver::getIntValue(this->getDict(), key, this->separator);
338 }
339
340 // New
341 inline
342 void addOne(const storage_t & value){
343 this->value |= value;
344 }
345
346 template <typename T2>
347 inline
348 void addOne(const T2 & value){
349 // why OR op in dvalue
350 // this->value = static_cast<dict_value_t>((dvalue_t)this->value | (dvalue_t)value);
351 this->value |= static_cast<value_t>(value);
352 }
353
354 mutable
355 std::string currentStr;
356
357
358};
359
360
361
362template <typename E,typename T>
363inline
364std::ostream & operator<<(std::ostream & ostr, const drain::MultiFlagger<E,T> & flagger) { // ,T
365 return FlagResolver::keysToStream(flagger.getDict(), flagger.getValue(), ostr);
366}
367
368DRAIN_TYPENAME_T0(MultiFlagger,E);
369
370
371
372
373
375
382template <class F>
383class Flags2 : public F {
384
385public:
386
387 typedef F fbase_t;
388 typedef typename F::value_t value_t;
389 typedef typename F::dict_t dict_t;
390
391
392 virtual
393 const dict_t & getDict() const {
394 return dict;
395 };
396
397 virtual
398 dict_t & getDict(){
399 return dict;
400 };
401
402
404
408 inline
410 };
411
413
418 inline
419 Flags2(const std::initializer_list<typename dict_t::entry_t> & list) : dict(list){
420 };
421
422 inline
423 Flags2(const Flags2<F> & flags) : dict(flags.dict){
424 }
425
426 template <class T>
427 inline
428 Flags2<F> & operator=(const T & v){
429 this->set(v);
430 return *this;
431 }
432
433protected:
434
435 // Consider inherited dictionary, through a wrapper (first inherit, to guarantee init ref validity?).
436 dict_t dict;
437
438
439};
440
441
442
443} // drain::
444
445
446#endif
Two-way mapping between strings and objects of template class T.
Definition Dictionary.h:61
const K & getKey(const V &value, bool lenient=true) const
Identity mapping useful for type deduction of template arguments in functions.
Definition Dictionary.h:170
const V & getValue(const K &key, bool lenient=true) const
Given a key, return the first value associated with it.
Definition Dictionary.h:147
bool hasValue(const V &value) const
Given a key, return the first value associated with it.
Definition Dictionary.h:141
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:195
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:276
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:264
Definition FlagBase.h:359
Flagger with own dictionary, and accepting values of (integer) type T.
Definition Flags.h:383
Flags2()
Definition Flags.h:409
Flags2(const std::initializer_list< typename dict_t::entry_t > &list)
Constructor for relatively short dictionaries.
Definition Flags.h:419
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:213
virtual std::string & str()
For importing values. After assignment, update() should be called. Experimental.
Definition Flags.h:310
void unset(const storage_t &x)
Unset some bit(s).
Definition Flags.h:270
MultiFlagger(const dict_t &dict, storage_t &target, char sep=',')
Definition Flags.h:240
void add(const V &arg, const VV &... args)
Add bit values.
Definition Flags.h:293
virtual void assign(const std::string &s) override
Split a string to separate keys and/or values and set them.
Definition Flags.h:325
virtual bool isSet(const storage_t &x) const override
Return true, all the bits of argument x are set.
Definition Flags.h:258
bool isAnySet(const storage_t &x) const
Return true, all the bits of argument x are set.
Definition Flags.h:264
void set(const V &... args)
Set bits, accepting numeric values or keys.
Definition Flags.h:284
virtual const dict_t & getDict() const override
Returns the static dictionary created for this value_t .
Definition Flags.h:248
virtual const key_t & str() const override
For exporting values.
Definition Flags.h:301
Definition Flags.h:62
virtual void set(const value_t &value)
Set a single flag.
Definition Flags.h:131
virtual bool isSet(const storage_t &x) const override
Return true, if value is exactly x .
Definition Flags.h:117
virtual const dict_t & getDict() const override
Returns the static dictionary created for this value_t .
Definition Flags.h:83
virtual const key_t & str() const override
String corresponding the current value. Returns empty, if not found.
Definition Flags.h:151
virtual void assign(const std::string &key) override
Assign key. Expects a single key, not a combination of keys.
Definition Flags.h:164
Definition DataSelector.cpp:1277
Default implementation.
Definition TypeName.h:54