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