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/String.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 virtual inline
261 bool isSet(const storage_t & x) const override {
262 return ((this->value & x) == x);
263 };
264
266 inline
267 bool isAnySet(const storage_t & x) const {
268 return ((this->value & x) != 0);
269 };
270
272 inline
273 void unset(const storage_t & x){
274 this->value = (this->value & ~x);
275 //return ((this->value & x) == x);
276 }
277
279
285 template <typename ... V>
286 inline
287 void set(const V &... args) {
288 this->reset();
289 add(args...);
290 }
291
292
294 template <typename V, typename ...VV>
295 inline
296 void add(const V & arg, const VV &... args) {
297 //std::cerr << __FUNCTION__ << ':' << arg << std::endl;
298 addOne(arg);
299 add(args...);
300 }
301
303 virtual
304 const key_t & str() const override {
305 // const dict_t & dict = this->getDict();
306 currentStr = FlagResolver::getKeys(this->getDict(), this->value, this->separator);
307 return currentStr;
308 }
309
310
312 virtual
313 std::string & str(){
314 // NEW: also non-const is updated
315 // const dict_t & dict = this->getDict();
316 currentStr = FlagResolver::getKeys(this->getDict(), this->value, this->separator);
317 return currentStr; // CHECK USAGE
318 }
319
320
321
322protected:
323
324 const dict_t & dict;
325
327 virtual
328 void assign(const std::string & s) override {
329 const dict_t & dict = this->getDict();
330 this->value = FlagResolver::getIntValue(dict, s, this->separator); // uses dict.separator if needed
331 }
332
333
334 inline
335 void add(){};
336
337 inline
338 void addOne(const key_t & key){
339 // Resolves also "" and numeric keys.
340 this->value |= FlagResolver::getIntValue(this->getDict(), key, this->separator);
341 }
342
343 // New
344 inline
345 void addOne(const storage_t & value){
346 this->value |= value;
347 }
348
349 template <typename T2>
350 inline
351 void addOne(const T2 & value){
352 // why OR op in dvalue
353 // this->value = static_cast<dict_value_t>((dvalue_t)this->value | (dvalue_t)value);
354 this->value |= static_cast<value_t>(value);
355 }
356
357 mutable
358 std::string currentStr;
359
360
361};
362
363
364
365template <typename E,typename T>
366inline
367std::ostream & operator<<(std::ostream & ostr, const drain::MultiFlagger<E,T> & flagger) { // ,T
368 return FlagResolver::keysToStream(flagger.getDict(), flagger.getValue(), ostr);
369}
370
371
372
373
374
375
377
384template <class F>
385class Flags2 : public F {
386
387public:
388
389 typedef F fbase_t;
390 typedef typename F::value_t value_t;
391 typedef typename F::dict_t dict_t;
392
393
394 virtual
395 const dict_t & getDict() const {
396 return dict;
397 };
398
399 virtual
400 dict_t & getDict(){
401 return dict;
402 };
403
404
406
410 inline
412 };
413
415
420 inline
421 Flags2(const std::initializer_list<typename dict_t::entry_t> & list) : dict(list){
422 };
423
424 inline
425 Flags2(const Flags2<F> & flags) : dict(flags.dict){
426 }
427
428 template <class T>
429 inline
430 Flags2<F> & operator=(const T & v){
431 this->set(v);
432 return *this;
433 }
434
435protected:
436
437 // Consider inherited dictionary, through a wrapper (first inherit, to guarantee init ref validity?).
438 dict_t dict;
439
440
441};
442
443
444
445} // drain::
446
447
448#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:385
Flags2()
Definition Flags.h:411
Flags2(const std::initializer_list< typename dict_t::entry_t > &list)
Constructor for relatively short dictionaries.
Definition Flags.h:421
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
Logger & suspicious(const TT &... args)
A weak warning about something going possibly wrong.
Definition Log.h:500
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:511
Definition Flags.h:220
virtual std::string & str()
For importing values. After assignment, update() should be called. Experimental.
Definition Flags.h:313
void unset(const storage_t &x)
Unset some bit(s).
Definition Flags.h:273
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:296
virtual void assign(const std::string &s) override
Split a string to separate keys and/or values and set them.
Definition Flags.h:328
virtual bool isSet(const storage_t &x) const override
Return true, all the bits of argument x are set.
Definition Flags.h:261
bool isAnySet(const storage_t &x) const
Return true, all the bits of argument x are set.
Definition Flags.h:267
void set(const V &... args)
Set bits, accepting numeric values or keys.
Definition Flags.h:287
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:304
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
Definition Type.h:542