Flow123d  jenkins-Flow123d-windows-release-multijob-285
flag_array.hh
Go to the documentation of this file.
1 /*
2  * flag_array.hh
3  *
4  * Created on: Apr 30, 2014
5  * Author: jb
6  */
7 
8 #ifndef FLAG_ARRAY_HH_
9 #define FLAG_ARRAY_HH_
10 
11 #include <ostream>
12 
13 /**
14  * @brief std::bitset with generalized mask mechanism.
15  *
16  * The drawback of classical bitfield technique implemented e.g. in std::bitset<>
17  * is problematic work (set and test) with more bits then one at time. This class is simple wrapper
18  * for std::bitset<> that provides public class FlagArray<..>::Mask that represents some
19  * bit subset together with a reference value which can be used to set the bit subset or to test the bit subset.
20  *
21  * The class is meant to be used in several other classes, that can define their specific masks.
22  * Every class using the FlagArray should provide specific @p Tag template parameter in order to
23  * guarantee Mask - FlagArray compatibility.
24  *
25  * Implementation note: since std::bitset do not have constexpr operators (may be in c++1y)
26  * we currently use just unsigned int in our implementation.
27  *
28  * Usage:
29  *
30  * @code
31  * class FlagsUser {
32  * public:
33  * static constexpr
34  * };
35  * @endcode
36  */
37 template <class Tag, int Size = 32>
38 class FlagArray {
39 
40 private:
41  /// Declaration of internal bitfield type.
42  typedef unsigned int BitField;
43 
44 public:
45 
46 
47  /**
48  * Class defines a flag mask that can set or reset certain bits to predefined values.
49  * Thus it consists of a @p mask part that specifies bits which are set to the second part @p set.
50  *
51  * A Mask can be applied to an FlagArray via FlagArray::set() method, masks can be combined through
52  * the "&" operator and can be used to test flags via FlagArray::is() method.
53  */
54  class Mask {
55  public:
56 
57  constexpr Mask() = default;
58 
59  /// Constructor.
60  constexpr Mask(BitField mask, BitField set)
61  : mask_(mask), set_(set)
62  {}
63 
64  /**
65  * Simple constructor. Namely to get elementary mask for one bit, e.g.
66  * @code
67  * static constexpr Mask input_flag{0x0010};
68  * @endcode
69  */
70  constexpr Mask(BitField mask)
71  : Mask(mask,mask)
72  {}
73 
74 
75  /**
76  * Apply mask @p other to *this mask. That is, join bit masks and overwrite
77  * bits given by @p other.mask_ by @p outher.set_ values.
78  * The action of the result Mask on the FlagArray (method @p set()) is the same as application of *this
79  * followed by the application of @p other.
80  */
81  constexpr Mask operator&(Mask other) const
82  { return Mask( mask_ | other.mask_, mask_set(set_, other.mask_, other.set_) );
83  }
84 
85  /// Mask negation.
86  constexpr Mask operator~() const
87  { return Mask( mask_ , mask_ & ~set_); }
88 
89  /**
90  * Returns true if bits in passed @p flags are 1 on positions masked (equal to 1) by the Mask.
91  */
92  constexpr bool match(BitField flags) const
93  { return ( ((mask_ & flags) ^ (mask_ & set_)) == 0); }
94 
95  friend std::ostream &operator<<(std::ostream &stream, const Mask &m)
96  { stream << std::hex << m.mask_ << ", " << std::hex << m.set_;
97  return stream;
98  }
99 
100  private:
101 
102  /// Returns bitset @p set1 with bits given by @p mask set to the values given by the bitset @p set2.
103  static constexpr BitField mask_set( BitField set1, BitField mask2, BitField set2)
104  { return (mask2 & set2) | (~mask2 & set1);
105  }
106  public:
107  /// The mask operates only on true bits of the @p mask_ member.
108  BitField mask_;
109  /// Values of the mask. Only bits given by @p mask_ are significant.
110  BitField set_;
111 
112  template <class T, int S>
113  friend class FlagArray;
114  };
115 
116 
117 public:
118  /// Allocated size of flags storage.
119  static const unsigned int size = Size;
120 
121  static constexpr Mask all_true_mask=Mask(~BitField(0), ~BitField(0));
122  static constexpr Mask all_false_mask=Mask(~BitField(0), BitField(0));
123  static constexpr Mask none_mask=Mask(0, 0);
124 
125 
126 
127 
128  /// Default constructor turns all flags off.
130  : flags_(BitField(0))
131  {}
132 
133  /// Conversion from the mask.
134  FlagArray(Mask mask)
135  : FlagArray()
136  {
137  this->add(mask);
138  }
139 
140  friend constexpr bool operator==(FlagArray left, FlagArray right)
141  { return (left.flags_==right.flags_);
142  }
143 
145  { return (left.flags_!=right.flags_);
146  }
147 
148  /**
149  * The FlagArray match a mask if and only if
150  * bits given by the @p mask.mask_ are same in both
151  * the flags_ and mask.set_.
152  */
153  constexpr bool match(Mask mask) const
154  { return mask.match(flags_); }
155 
156  /**
157  * Apply the mask to the flags.
158  * Bits by the @p mask.mask_ are overwritten by the @p mask.set_ values.
159  */
160  FlagArray &add(Mask mask)
161  { flags_ = Mask::mask_set(flags_, mask.mask_, mask.set_); return *this; }
162 
163  friend std::ostream &operator<<(std::ostream & s, const FlagArray &f) {
164  return (s << f.flags_);
165  }
166 
167 private:
168  /// flags storage
169  BitField flags_;
170 };
171 
172 
173 #endif /* FLAG_ARRAY_HH_ */
BitField mask_
The mask operates only on true bits of the mask_ member.
Definition: flag_array.hh:108
friend std::ostream & operator<<(std::ostream &s, const FlagArray &f)
Definition: flag_array.hh:163
friend bool operator!=(FlagArray left, FlagArray right)
Definition: flag_array.hh:144
BitField set_
Values of the mask. Only bits given by mask_ are significant.
Definition: flag_array.hh:110
std::bitset with generalized mask mechanism.
Definition: flag_array.hh:38
BitField flags_
flags storage
Definition: flag_array.hh:169
static constexpr Mask none_mask
Definition: flag_array.hh:123
FlagArray & add(Mask mask)
Definition: flag_array.hh:160
unsigned int BitField
Declaration of internal bitfield type.
Definition: flag_array.hh:42
constexpr Mask operator&(Mask other) const
Definition: flag_array.hh:81
static const unsigned int size
Allocated size of flags storage.
Definition: flag_array.hh:119
constexpr bool match(Mask mask) const
Definition: flag_array.hh:153
constexpr bool match(BitField flags) const
Definition: flag_array.hh:92
friend constexpr bool operator==(FlagArray left, FlagArray right)
Definition: flag_array.hh:140
constexpr Mask operator~() const
Mask negation.
Definition: flag_array.hh:86
constexpr Mask(BitField mask, BitField set)
Constructor.
Definition: flag_array.hh:60
friend std::ostream & operator<<(std::ostream &stream, const Mask &m)
Definition: flag_array.hh:95
static constexpr Mask all_true_mask
Definition: flag_array.hh:121
static constexpr Mask all_false_mask
Definition: flag_array.hh:122
FlagArray()
Default constructor turns all flags off.
Definition: flag_array.hh:129
constexpr Mask(BitField mask)
Definition: flag_array.hh:70
FlagArray(Mask mask)
Conversion from the mask.
Definition: flag_array.hh:134
constexpr Mask()=default
static constexpr BitField mask_set(BitField set1, BitField mask2, BitField set2)
Returns bitset set1 with bits given by mask set to the values given by the bitset set2...
Definition: flag_array.hh:103