All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BitMask.h
Go to the documentation of this file.
1 /**
2  * @file lardataobj/Utilities/BitMask.h
3  * @brief Class holding flags.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date January 25, 2017
6  * @see lardataobj/Utilities/FlagSet.h
7  *
8  * This pure header defines the template class `util::flags::BitMask`, which is
9  * used in `util::flags::FlagSet`, and a few auxiliary classes and types
10  * (`util::flags::Index_t`, `util::flags::Flag_t`).
11  *
12  */
13 
14 #ifndef LARDATAOBJ_UTILITIES_BITMASK_H
15 #define LARDATAOBJ_UTILITIES_BITMASK_H
16 
17 
18 // C/C++ standard library
19 #include <ostream>
20 #include <string>
21 #include <exception>
22 
23 namespace util {
24 
25  /**
26  * @brief Classes and functions to manage bit masks and flags.
27  *
28  * In this namespace a "hierarchy" of classes are defined:
29  *
30  * * `Flag_t`: a single bit; it can be initialized with the bit index, but
31  * it is stored as a bit mask. A flag has two states: set and unset.
32  * * `Bits_t`: a set of flags (represented as a bit mask).
33  * * `BitMask`: a set of flags which can have one of three states each:
34  * set, unset or undefined.
35  * * `FlagSet`: a set of flags (like `BitMask`), with the knowledge of a total
36  * number of supported flags.
37  *
38  * The first three classes manage exactly how many bits they have storage for.
39  * `FlagSet` instead has also the notion of how many flags are actually
40  * supported.
41  * A number of flag-wise operations are defined. The result of an operation
42  * between two classes might be a class of a superior level in the hierarchy.
43  * In this sense, the lower objects should be intended as shortcut
44  * representations of `Bits_t`.
45  * More specifically:
46  *
47  * * a `Bits_t` can be created out of a `Flag_t`
48  * * a `BitMask` can be created out of a `Bits_t` (or a `Flag_t`)
49  * * `~Flag_t` is not defined
50  * * `Bits_t | Bits_t` and `Bits_t + Bits_t` are still `Bits_t` (and they are
51  * equivalent)
52  * * `Bits_t & Bits_t` and `Bits_t - Bits_t` are `BitMask`, to preserve the
53  * information of bits that are defined and unset
54  * * `~Bits_t` is a `BitMask` as well
55  *
56  */
57  namespace flags {
58 
59  /// Type to denote the index of the flag.
60  using Index_t = unsigned int;
61 
62  namespace details {
63 
64  /// Trait containing the smallest integral type accommodating `NBits`
65  /// bits.
66  template <unsigned int NBits>
68 
69  /// The smallest integral type accommodating `NBits` bits.
70  template <unsigned int NBits>
72 
73  /// Returns the number of Storage variables needed to hold that many bits.
74  template <typename Storage>
75  constexpr unsigned int computePages(unsigned int bits);
76 
77  /// Returns a set of bits with only the one at the specified index set.
78  template <typename Storage>
79  constexpr Storage makeBits(Index_t index)
80  { return Storage(1) << index; }
81 
82  } // namespace details
83 
84 
85 
86  //--------------------------------------------------------------------------
87  /// Type identifying a flag. Operations are implemented as free functions.
88  template <typename Storage>
89  struct Flag_t {
90  using Storage_t = Storage;
91  using This_t = Flag_t<Storage>; ///< This type.
92 
93  Storage_t bits; ///< The bits representing this flag (only one is set)
94 
95  /// Constructs from the flag index.
96  constexpr Flag_t(Index_t flagIndex)
97  : bits(details::makeBits<Storage_t>(flagIndex))
98  {}
99 
100  /// Returns the index of the (first) bit set.
101  constexpr Index_t index() const;
102 
103  /**
104  * @brief Returns a copy of this object.
105  * @return a copy of this flag
106  *
107  * When a flag is declared as `constexpr`, functions trying to take its
108  * address will trigger a link failure (as there is no address for a
109  * constexpr). Passing a copy of it should fix the problem.
110  */
111  constexpr Flag_t copy() const { return *this; }
112 
113  /// @{
114  /// @name Comparison operators for flags
115 
116  constexpr bool operator== (This_t other) const
117  { return bits == other.bits; }
118  constexpr bool operator!= (This_t other) const
119  { return bits != other.bits; }
120  constexpr bool operator< (This_t other) const
121  { return bits < other.bits; }
122  constexpr bool operator> (This_t other) const
123  { return bits > other.bits; }
124  constexpr bool operator<= (This_t other) const
125  { return bits <= other.bits; }
126  constexpr bool operator>= (This_t other) const
127  { return bits >= other.bits; }
128 
129  /// @}
130 
131  }; // Flag_t
132 
133 
134  /// @{
135  /// @name Comparison operators for flags (based on the index)
136  template <typename Storage>
138  { return left == right.index(); }
139  template <typename Storage>
141  { return left.index() == right; }
142 
143  template <typename Storage>
145  { return left != right.index(); }
146  template <typename Storage>
148  { return left.index() != right; }
149 
150  template <typename Storage>
151  constexpr bool operator< (Index_t left, Flag_t<Storage> right)
152  { return left < right.index(); }
153  template <typename Storage>
154  constexpr bool operator< (Flag_t<Storage> left, Index_t right)
155  { return left.index() < right; }
156 
157  template <typename Storage>
159  { return left > right.index(); }
160  template <typename Storage>
162  { return left.index() > right; }
163 
164  template <typename Storage>
165  constexpr bool operator<= (Index_t left, Flag_t<Storage> right)
166  { return left <= right.index(); }
167  template <typename Storage>
168  constexpr bool operator<= (Flag_t<Storage> left, Index_t right)
169  { return left.index() <= right; }
170 
171  template <typename Storage>
173  { return left >= right.index(); }
174  template <typename Storage>
176  { return left.index() >= right; }
177 
178  /// @}
179 
180  /// Output of a flag into a stream (prints its index).
181  template <typename Storage>
182  std::ostream& operator<< (std::ostream& out, Flag_t<Storage> flag)
183  { out << '[' << flag.index() << ']'; return out; }
184 
185  /// Convert a flag into a stream (shows its index).
186  template <typename Storage>
187  std::string to_string(Flag_t<Storage> const flag)
188  { return std::to_string(flag.index()); }
189 
190 
191  //--------------------------------------------------------------------------
192  /// Type identifying a set of bits.
193  template <typename Storage>
194  struct Bits_t {
195  using Storage_t = Storage;
196  using This_t = Bits_t<Storage>; ///< This type.
197 
198  /// Type of flag matching our storage.
200 
201  Storage_t data = { 0 }; ///< The bits representing all set bits
202 
203  /// Default constructor: no bit set.
204  constexpr Bits_t() = default;
205 
206  /// Constructs from a single flag.
207  constexpr Bits_t(Flag_t flag)
208  : data(flag.bits)
209  {}
210 
211  /// Constructs from a set of bits.
212  explicit constexpr Bits_t(Storage_t bits)
213  : data(bits)
214  {}
215 
216  /// @{
217  /// @name Bit query operations
218 
219  /// Returns whether there is no bit set at all.
220  constexpr bool empty() const
221  { return data == Storage_t(0); }
222 
223  /// Returns wether all bits are set.
224  constexpr bool all(This_t bits) const;
225 
226  /// Returns wether at least one of the bits is set.
227  constexpr bool any(This_t bits) const;
228 
229  /// Returns wether all bits are unset.
230  constexpr bool none(This_t bits) const;
231 
232  /// Returns wether no bits are set except (at most) the specified ones.
233  constexpr bool only(This_t bits) const;
234 
235  /// @}
236 
237 
238  /// @{
239  /// @name Bit change operations
240 
241  /// Sets the specified bits.
242  void set(This_t bits);
243 
244  /// Unsets the specified bits.
245  void unset(This_t bits);
246 
247  /// Unsets the bits which are _not_ in `bits` argument.
248  void keepOnly(This_t bits);
249 
250  /// Unsets all bits.
251  void clear()
252  { data = 0; }
253 
254  /// @}
255 
256 
257  /// @{
258  /// @name Bit manipulation operations returning a new object
259 
260  /// Returns only the bits that are also present in the argument.
261  constexpr This_t select(This_t bits) const;
262 
263  /// Returns only the bits that are not present in the argument.
264  constexpr This_t exclude(This_t bits) const;
265 
266  /// Returns our bits, plus the ones present in the argument.
267  constexpr This_t combine(This_t bits) const;
268 
269  /// Returns all and only the bits that are not set.
270  constexpr This_t invert() const;
271 
272  /// @}
273 
274 
275  /// @{
276  /// @name Comparison operators for bits
277 
278  constexpr bool operator== (This_t other) const
279  { return data == other.data; }
280  constexpr bool operator!= (This_t other) const
281  { return data != other.data; }
282  constexpr bool operator< (This_t other) const
283  { return data < other.data; }
284  constexpr bool operator> (This_t other) const
285  { return data > other.data; }
286  constexpr bool operator<= (This_t other) const
287  { return data <= other.data; }
288  constexpr bool operator>= (This_t other) const
289  { return data >= other.data; }
290 
291  /// @}
292 
293  /// Returns true if there is at least one bit set.
294  explicit constexpr operator bool() const { return bool(data); }
295 
296  /// Returns true if there is no bit set.
297  constexpr bool operator!() const { return !data; }
298 
299 
300  /// Returns data with all bits from base and from bits set.
301  static void setBits(Storage_t& base, Storage_t bits)
302  { base |= bits; }
303 
304  /// Returns data with all bits from base which are also in `bits`
305  /// argument.
306  static void onlyBits(Storage_t& base, Storage_t bits)
307  { base &= bits; }
308 
309  /// Returns data with all bits from base, but the ones from bits unset.
310  static void unsetBits(Storage_t& base, Storage_t bits)
311  { onlyBits(base, ~bits); }
312 
313  }; // Bits_t
314 
315 
316  /// @{
317  /**
318  * @name Flag and bit operations.
319  *
320  * Any bitwise operation with a flag returns a `Bits_t`.
321  *
322  */
323 
324  /// Returns a new Bits_t with all the bits from both arguments set.
325  template <typename Storage>
326  constexpr Bits_t<Storage> operator|
327  (Bits_t<Storage> left, Bits_t<Storage> right);
328 
329  /// Returns a new Bits_t with all the bits from both arguments set.
330  template <typename Storage>
331  constexpr Bits_t<Storage> operator|
332  (Bits_t<Storage> left, typename Bits_t<Storage>::Flag_t right);
333 
334  /// Returns a new Bits_t with all the bits from both arguments set.
335  template <typename Storage>
336  constexpr Bits_t<Storage> operator|
337  (typename Bits_t<Storage>::Flag_t left, Bits_t<Storage> right);
338 
339  /// Returns a new Bits_t with all the bits from both arguments set.
340  template <typename Storage>
341  constexpr Bits_t<Storage> operator|
342  (Flag_t<Storage> left, Flag_t<Storage> right);
343 
344  /// Returns a new Bits_t with all the bits from both arguments set.
345  template <typename Storage>
346  constexpr Bits_t<Storage> operator+
347  (Bits_t<Storage> left, Bits_t<Storage> right);
348 
349  /// Returns a new Bits_t with all the bits from both arguments set.
350  template <typename Storage>
351  constexpr Bits_t<Storage> operator+
352  (Bits_t<Storage> left, typename Bits_t<Storage>::Flag_t right);
353 
354  /// Returns a new Bits_t with all the bits from both arguments set.
355  template <typename Storage>
356  constexpr Bits_t<Storage> operator+
357  (typename Bits_t<Storage>::Flag_t left, Bits_t<Storage> right);
358 
359  /// Returns a new Bits_t with all the bits from both arguments set.
360  template <typename Storage>
361  constexpr Bits_t<Storage> operator+
362  (Flag_t<Storage> left, Flag_t<Storage> right);
363 
364  /// @}
365 
366 
367  //--------------------------------------------------------------------------
368  /// Namespace enclosing BitMask exceptions.
369  namespace errors {
370 
371  /// @{
372  /// @name BitMask exceptions
373 
374  /// Base class for exceptions thrown by flag-related utilities.
375  struct Exception: public std::exception {
376  explicit Exception(std::string msg = "Flag error"): message(msg) {}
377  virtual const char* what() const noexcept override
378  { return message.c_str(); }
379  std::string message;
380  }; // Exception
381 
382  /// Exception thrown to convey that an undefined flag index was tested
383  struct FlagNotDefined: public Exception {
384  explicit FlagNotDefined(std::string msg = "Flag undefined-flag error")
385  : Exception(msg)
386  {}
387  }; // FlagNotDefined
388 
389  /// Exception thrown to convey that an invalid flag index was used
390  struct OutOfRange: public Exception {
391  explicit OutOfRange(std::string msg = "Flag out-of-range error")
392  : Exception(msg)
393  {}
394  }; // OutOfRange
395 
396  /// @}
397 
398  } // namespace errors
399 
400 
401  struct BitMaskFromValuesTag {}; ///< Type for constructor tag from values.
402 
403  /// Value useful for `BitMask` constructors from value.
405 
406  /**
407  * @brief A class containing a set of flags.
408  * @tparam NFlags number of flags to be allocated
409  * @tparam Storage underlying integral type whose bits represent the flags
410  *
411  * A BitMask contains a set of flags. Each flag can be in one of two
412  * states ("set" and "unset"), or can be not defined at all ("undefined").
413  *
414  * Note that the object might have a `capacity()` larger than just `NFlags`.
415  * The flags after the first `NFlags` are "unsupported", in the sense that
416  * in future implementations they might disappear. For the rest, they behave
417  * just like the other flags though.
418  */
419  template <typename Storage>
420  class BitMask {
421 
422  /// Type of underlying bit data representation.
423  using Storage_t = Storage;
424 
425  public:
426 
427  using Mask_t = BitMask<Storage>; ///< This type.
428 
429  using FlagIndex_t = util::flags::Index_t; ///< Type of index of flag.
430 
431  using Bits_t = util::flags::Bits_t<Storage_t>; ///< Set of bits.
432 
433  /// Type identifying a single flag.
434  using Flag_t = typename Bits_t::Flag_t;
435 
436  /// @{
437  /// @name Exceptions
438 
439  /// Generic BitMask exception.
441 
442  /// Out-of-range flag index.
444 
445  /// Flag not defined.
447 
448  /// @}
449 
450  /// Constructor tag from values.
451  static constexpr auto fromValues = maskFromValues;
452 
453 
454  // -- BEGIN Constructors from values -------------------------------------
455  /**
456  * @name Constructors from values
457  *
458  * These constructors initialize the bit mask from the traditional bit
459  * mask constants in C style.
460  * The first argument of them should be `util::flags::maskFromValues`
461  * (or the equivalent `fromValues` from `BitMask` itself).
462  */
463  /// @{
464 
465  /// Default constructor: no flag defined at all.
466  explicit constexpr BitMask() = default;
467 
468 
469  /**
470  * @brief Constructor: defines and sets flags.
471  * @param defined a bit mask of the values to be defined and set
472  *
473  * All bits in `values` will be defined and set.
474  * Example:
475  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
476  * using MyMask_t = util::flags::BitMask<unsigned int>;
477  * constexpr MyMask_t DefaultMask(MyMask_t::fromValues, 0x0300U);
478  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
479  */
481 
482 
483  /**
484  * @brief Constructor: defines and sets flags.
485  * @param defined a bit mask of the flags to be defined
486  * @param values a bit mask of the values to be set
487  *
488  * If a bit value is requested to be set (in `values`), it will be also
489  * defined, regardless whether its definition bit (in `defined`) is set.
490  * Example:
491  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
492  * using MyMask_t = util::flags::BitMask<unsigned int>;
493  * constexpr MyMask_t DefaultMask(MyMask_t::fromValues, 0x0300U, 0x0200U);
494  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
495  */
496  constexpr BitMask
498 
499 
500  /**
501  * @brief Constructor: defines and sets flags.
502  * @param values a bit mask of the values to be set
503  */
505 
506 
507  /**
508  * @brief Constructor: defines and sets flags.
509  * @param defined a bit mask of the flags to be defined
510  * @param values a bit mask of the values to be set
511  *
512  * If a bit value is requested to be set (in `values`), it will be also
513  * defined, regardless whether its definition bit (in `defined`) is set.
514  */
516 
517 
518  /// @}
519  // -- END Constructors from values ---------------------------------------
520 
521 
522  // -- BEGIN Constructors combining flags ---------------------------------
523  /// @name Constructors combining flags
524  /// @{
525 
526  /**
527  * @brief Constructor: merges all arguments in the argument list.
528  * @tparam Others type of the remaining parameters to be merged
529  * @param first first argument to be merged (here, a Flag_t)
530  * @param others remaining arguments to be merged
531  * @see create()
532  *
533  * The effect is equivalent to call `create(first, others...)`.
534  */
535  template <typename... Others>
536  constexpr BitMask(Flag_t first, Others... others)
537  : BitMask(create(first, others...))
538  {}
539 
540  /**
541  * @brief Constructor: merges all arguments in the argument list.
542  * @tparam Others type of the remaining parameters to be merged
543  * @param first first argument to be merged (here, a Bits_t)
544  * @param others remaining arguments to be merged
545  * @see create()
546  *
547  * The effect is equivalent to call `create(first, others...)`.
548  */
549  template <typename... Others>
550  constexpr BitMask(Bits_t first, Others... others)
551  : BitMask(create(first, others...))
552  {}
553 
554  /**
555  * @brief Constructor: merges all arguments in the argument list.
556  * @tparam Second type of the second argument to be merged
557  * @tparam Others type of the remaining arguments to be merged
558  * @param first first argument to be merged (here, a Mask_t)
559  * @param second second argument to be merged
560  * @param others remaining arguments to be merged
561  * @see create()
562  *
563  * The effect is equivalent to call `create(first, others...)`.
564  */
565  // NOTE: if the first argument passed as reference prevent constexpr,
566  // two separate constructors will be needed;
567  // also note that this works as copy constructor as well
568  template <typename Second, typename... Others>
569  constexpr BitMask(Mask_t first, Second second, Others... others)
570  : BitMask(create(first, second, others...))
571  {}
572 
573  /// @}
574  // -- END Constructors combining flags -----------------------------------
575 
576 
577  // -- BEGIN Access to flags ----------------------------------------------
578  /// @name Access to flags
579  /// @{
580 
581  /**
582  * @brief Returns whether the flag is defined.
583  * @param flag index of the flag to check
584  * @return whether the flag is defined
585  *
586  * A flag must be defined before it can be used. A common convention is to
587  * use the "undefined" state of the flag to denote that its value is
588  * currently unknown.
589  *
590  * A flag is defined by setting (`set()`) or unsetting (`unset()`) it.
591  */
592  constexpr bool isDefined(Flag_t flag) const;
593 
594  /**
595  * @brief Returns whether all specified bits are defined.
596  * @param bits bits to check
597  * @return whether all bits set in bits are defined
598  * @see isDefined(Flag_t)
599  *
600  * This method is equivalent to calling `isDefined(Flag_t)` on each single
601  * flag defined in `bits`. The result is true only if all of them are
602  * defined.
603  */
604  constexpr bool isDefined(Bits_t bits) const;
605 
606  /**
607  * @brief Returns whether the flag is undefined.
608  * @param flag index of the flag to check
609  * @return whether the flag is undefined
610  * @see isUndefined()
611  *
612  * This is exactly the negation of `isDefined()`.
613  */
614  constexpr bool isUndefined(Flag_t flag) const;
615 
616  /**
617  * @brief Returns whether all specified bits are undefined.
618  * @param bits bits to check
619  * @return whether all bits set in bits are undefined
620  * @see isDefined(Bits_t), isUndefined(Flag_t)
621  *
622  * This is exactly the negation of `isDefined()`.
623  */
624  constexpr bool isUndefined(Bits_t bits) const;
625 
626  /**
627  * @brief Returns if the specified flag is on ("set").
628  * @param flag index of the flag to test
629  * @return whether the specified flag is set
630  *
631  * This method provides an unchecked access to a single flag value.
632  * If the flag is `isUndefined()`, the behaviour of this method is also
633  * undefined.
634  */
635  constexpr bool get(Flag_t flag) const;
636 
637  /**
638  * @brief Returns if the specified flag is set.
639  * @param flag index of the flag to test
640  * @return whether the specified flag is set
641  *
642  * This method provides an unchecked access to a single flag value.
643  * If the flag is `isUndefined()`, the behaviour of this method is also
644  * undefined.
645  */
646  constexpr bool isSet(Flag_t flag) const;
647 
648  /**
649  * @brief Returns if the specified flag is unset.
650  * @param flag index of the flag to test
651  * @return whether the specified flag is unset
652  *
653  * This method provides an unchecked access to a single flag value.
654  * If the flag is `isUndefined()`, the behaviour of this method is also
655  * undefined.
656  */
657  constexpr bool isUnset(Flag_t flag) const;
658 
659  /**
660  * @brief Returns whether all the specified bits are set.
661  * @param bits bits to check
662  * @return whether all bits are set
663  * @see isSet(Flag_t)
664  *
665  * This method is equivalent to calling `isSet(Flag_t)` on each single
666  * flag defined in `bits`. The result is true only if all of them are set,
667  * that includes all of them being defined.
668  */
669  constexpr bool all(Bits_t bits) const;
670 
671  /**
672  * @brief Returns whether at least one of the specified bits is set.
673  * @param bits bits to check
674  * @return whether any of the bits is set
675  * @see `isSet(Flag_t)`
676  *
677  * This method is equivalent to calling `isSet(Flag_t)` on each single
678  * flag defined in `bits`. The result is true only if at least one of them
679  * is set (including that one being defined).
680  */
681  constexpr bool any(Bits_t bits) const;
682 
683  /**
684  * @brief Returns whether all the specified bits are unset.
685  * @param bits bits to check
686  * @return whether all bits are unset
687  * @see `isUnset(Flag_t)`
688  *
689  * This method is equivalent to calling `isUnset(Flag_t)` on each single
690  * flag defined in `bits`. The result is true only if all of them are
691  * unset, that includes all of them being defined.
692  */
693  constexpr bool none(Bits_t bits) const;
694 
695 
696  /**
697  * @brief Returns whether any of the bits set in the mask are set.
698  * @param mask the mask of bits
699  * @return whether we have any of those bits set
700  * @see `noneSet()`, `match()`
701  *
702  * The bits that are undefined in mask are not used to compute the result.
703  */
704  constexpr bool anySet(Mask_t const& mask) const;
705 
706  /**
707  * @brief Returns whether none of the bits set in the mask is set.
708  * @param mask the mask of bits
709  * @return whether we have any of those bits set
710  * @see `anySet()`, `match()`
711  *
712  * This is the logical negation of `anySet()`.
713  */
714  constexpr bool noneSet(Mask_t const& mask) const;
715 
716  /**
717  * @brief Returns whether all bits defined in the mask are equal to ours.
718  * @param mask the mask of bits
719  * @return whether the mask matches ours
720  *
721  * The flags that are undefined in mask are not used to compute the
722  * result.
723  * If all the flags that are set in `mask` (`isSet()`) are set in this
724  * object, and likewise all the flags that are unset in `mask`
725  * (`isUnset()`) are unset, this method returns `true`.
726  */
727  constexpr bool match(Mask_t const& mask) const;
728 
729  /// @}
730  // -- END Access to flags ------------------------------------------------
731 
732 
733  // -- BEGIN Setting flags ------------------------------------------------
734  /// @name Setting flags
735  /// @{
736 
737  /**
738  * @brief Sets all specified flags
739  * @tparam Flag types of the first flag
740  * @tparam OtherFlags types of other optional flags
741  * @param first the first flag to be set
742  * @param others flags also to be set
743  *
744  * All specified flags are set. Flags set are automatically defined.
745  *
746  * Each argument can be of one of the following supported types:
747  * * `Flag_t`: single flag (a FlagIndex_t can be implicitly converted to
748  * this one, too)
749  */
750  template <typename Flag, typename... OtherFlags>
751  void set(Flag first, OtherFlags... others)
752  { setImpl(first, others...); }
753 
754  /**
755  * @brief Sets all flags specified by the index iterator range
756  * @tparam BeginIter type of iterator to the first of the flags
757  * @tparam EndIter type of end iterator
758  * @param begin iterator to the index of the first flag
759  * @param end iterator past the index of the last flag
760  * @see set()
761  *
762  * Each flag is set as if `set(flag)` were called.
763  */
764  template <typename BeginIter, typename EndIter>
765  void rangeSet(BeginIter begin, EndIter end);
766 
767  /**
768  * @brief Unsets all specified flags
769  * @tparam Flag types of the first flag
770  * @tparam OtherFlags types of other optional flags
771  * @param first the first flag to be unset
772  * @param others flags also to be unset
773  * @see set()
774  *
775  * All specified flags are unset. Flags unset are automatically defined.
776  * The types accepted are the same as for `set()`.
777  */
778  template <typename Flag, typename... OtherFlags>
779  void unset(Flag first, OtherFlags... others)
780  { unsetImpl(first, others...); }
781 
782  /**
783  * @brief Unsets all flags specified by the index iterator range
784  * @tparam BeginIter type of iterator to the first of the flags
785  * @tparam EndIter type of end iterator
786  * @param begin iterator to the index of the first flag
787  * @param end iterator past the index of the last flag
788  * @see unset()
789  *
790  * Each flag is unset as if `unset(flag)` were called.
791  */
792  template <typename BeginIter, typename EndIter>
793  void rangeUnset(BeginIter begin, EndIter end);
794 
795 
796  /**
797  * @brief Declares all specified flags as undefined.
798  * @tparam Flag types of the first flag
799  * @tparam OtherFlags types of other optional flags
800  * @param first the first flag to be removed
801  * @param others flags also to be removed
802  * @see set(), unset(), isDefined()
803  *
804  * All specified flags are marked back as undefined.
805  * Already undefined flags are not affected.
806  * The value of an undefined flag is... well, undefined.
807  *
808  * There is no equivalent direct way to just define a flag, but rather
809  * when a flag is assigned a value the first time, that flag is at the
810  * same time defined.
811  *
812  * Each argument can be of one of the following supported types:
813  * * `Flag_t`: single flag (a FlagIndex_t can be implicitly converted to
814  * this one, too)
815  */
816  template <typename Flag, typename... OtherFlags>
817  void remove(Flag first, OtherFlags... others)
818  { undefineImpl(first, others...); }
819 
820  /// Undefines all bits.
821  void clear()
822  { presence.clear(); values.clear(); }
823 
824  /// @}
825  // -- END Setting flags --------------------------------------------------
826 
827 
828  // -- BEGIN Number of flags ----------------------------------------------
829  /// @name Number of flags
830  /// @{
831 
832  /// Returns the number of flags the set has room for.
833  static constexpr size_t capacity();
834 
835  /// @}
836  // -- END Number of flags ------------------------------------------------
837 
838  /// Comparison: all flags must be the same
839  /// @bug Also the value of undefined flags is currently checked
840  constexpr bool operator== (Mask_t const& other) const
841  { return (values == other.values) && (presence == other.presence); }
842 
843  /// Comparison: not all flags must be the same
844  /// @bug Also the value of undefined flags is currently checked
845  constexpr bool operator!= (Mask_t const& other) const
846  { return (values != other.values) || (presence != other.presence); }
847 
848 
849  /// Prints into the specified stream the least nBits significant bits.
850  template <typename Stream>
851  void dump(Stream&& out, unsigned int nBits) const;
852 
853  /// Prints into the specified stream all bits.
854  template <typename Stream>
855  void dump(Stream&& out) const
856  { dump(std::forward<Stream>(out), capacity()); }
857 
858 
859  // -- BEGIN Static mask manipulation -------------------------------------
860  /// @name Static mask manipulation
861  /// @{
862 
863  /**
864  * @brief Creates a new BitMask.
865  * @tparam Args types of the arguments
866  * @param args the data to create the mask from
867  * @return a BitMask with the features specified in the arguments
868  *
869  * If no argument is provided, the mask is returned with all the flags
870  * undefined (like in default constructor).
871  * The order of the arguments matters: the first arguments are processed
872  * first and their effect can be overridden by the following arguments.
873  * For the details, see `mergeIntoMask()`, which is used to incrementally
874  * merge the argument to create the result.
875  */
876  template <typename... Args>
877  static constexpr Mask_t create(Args... args);
878 
879  /**
880  * @brief Returns a new mask with the content of the other `mask` merged.
881  * @param baseMask the starting mask
882  * @param mask the bits to be set
883  * @return a new mask with all the content of base and the new mask
884  *
885  * The content of the new mask overrides the base one: if a flag is
886  * defined in mask, it is defined and copied into the result, otherwise
887  * the state of the flag is copied from baseMask.
888  *
889  * The truth table of the operation is described in the following table,
890  * where '-' represents an undefined flag (`isUndefined()`), '0' an unset
891  * flag (`isUnset()`), and '1' a set flag (`isSet()`).
892  *
893  * | `mask` | - | 0 | 1 |
894  * | ---------- | ------- | ------- | ------- |
895  * | `baseMask` | | | |
896  * | - | - | 0 | 1 |
897  * | 0 | 0 | 0 | 1 |
898  * | 1 | 1 | 0 | 1 |
899  *
900  */
901  static constexpr Mask_t mergeIntoMask(Mask_t baseMask, Mask_t mask);
902 
903  /**
904  * @brief Returns a new mask with the specified bits defined and set.
905  * @param baseMask the starting mask
906  * @param bits the bits to be set
907  * @return a new mask with all content from baseMask, plus the flag bit
908  * set
909  *
910  * The truth table of this operation follows (see `mergeIntoMask()` for
911  * its legend).
912  *
913  * | `bits` | 0 | 1 |
914  * | ---------- | ------- | ------- |
915  * | `baseMask` | | |
916  * | - | - | 1 |
917  * | 0 | 0 | 1 |
918  * | 1 | 1 | 1 |
919  */
920  static constexpr Mask_t mergeIntoMask(Mask_t baseMask, Bits_t bits);
921 
922  /**
923  * @brief Returns a new mask with the specified flag defined and set.
924  * @param baseMask the starting mask
925  * @param flag the single flag to be set
926  * @return a new mask with all content from baseMask, plus the flag bit
927  * set
928  */
929  static constexpr Mask_t mergeIntoMask(Mask_t baseMask, Flag_t flag);
930 
931  /**
932  * @brief Returns a new mask combining bits set from two masks.
933  * @param A one of the masks to be combined
934  * @param B the other mask to be combined
935  * @return a new mask with all set bits from of the two masks
936  *
937  * The content of the new mask has a bit set if it was set (`isSet()`) in
938  * either of the masks, otherwise unset if it was unset (`isUnset()`) in
939  * either of the masks, or else undefined (`isUndefined()`), as it was
940  * undefined in both masks.
941  *
942  * The result differs from `mergeIntoMask()` only for bits which are
943  * set (`isSet()`) in the first mask but unset (`isUnset()`) in the
944  * second: `combineWithMask()` will leave the bit set, like in the first
945  * mask, while `mergeIntoMask()` would have that bit always unset.
946  *
947  * This is equivalent to a flagwise OR operation.
948  *
949  * The truth table of the operation is described in the following table,
950  * where '-' represents an undefined flag (`isUndefined()`), '0' an unset
951  * flag (`isUnset()`), and '1' a set flag (`isSet()`).
952  *
953  * | B | - | 0 | 1 |
954  * | --- | ------- | ------- | ------- |
955  * | A | | | |
956  * | - | - | 0 | 1 |
957  * | 0 | 0 | 0 | 1 |
958  * | 1 | 1 | 1 | 1 |
959  *
960  */
961  static constexpr Mask_t combineWithMask(Mask_t A, Mask_t B);
962 
963  /**
964  * @brief Returns a new mask with the specified flag defined and set.
965  * @param baseMask the starting mask
966  * @param bits the bits to be set
967  * @return a new mask with all content from baseMask, plus the flag bit
968  * set
969  *
970  * The truth table of this operation follows (see `mergeIntoMask()` for
971  * its legend).
972  *
973  * | `bits` | 0 | 1 |
974  * | ---------- | ------- | ------- |
975  * | `baseMask` | | |
976  * | - | - | 1 |
977  * | 0 | 0 | 1 |
978  * | 1 | 1 | 1 |
979  *
980  */
981  static constexpr Mask_t combineWithMask(Mask_t baseMask, Bits_t bits);
982 
983  /**
984  * @brief Returns a new mask with the specified flag defined and set.
985  * @param baseMask the starting mask
986  * @param flag the single flag to be set
987  * @return a new mask with all content from baseMask, plus the bits set
988  */
989  static constexpr Mask_t combineWithMask(Mask_t baseMask, Flag_t flag);
990 
991  /**
992  * @brief Returns a new mask with the bits set from both masks.
993  * @param A one of the masks to be combined
994  * @param B the other mask to be combined
995  * @return a new mask with all bits set in both masks
996  *
997  * The content of the new mask has a bit set if it was set (`isSet()`) in
998  * both masks, otherwise unset if it was unset (`isUnset()`) in
999  * either of the masks, or else undefined (`isUndefined()`), as it was
1000  * undefined in both masks.
1001  *
1002  * This is equivalent to a flagwise AND operation.
1003  *
1004  * The truth table of the operation is described in the following table,
1005  * where '-' represents an undefined flag (`isUndefined()`), '0' an unset
1006  * flag (`isUnset()`), and '1' a set flag (`isSet()`).
1007  *
1008  * | `B` | - | 0 | 1 |
1009  * | ----- | ------- | ------- | ------- |
1010  * | `A` | | | |
1011  * | - | - | 0 | 1 |
1012  * | 0 | 0 | 0 | 0 |
1013  * | 1 | 1 | 0 | 1 |
1014  *
1015  */
1016  static constexpr Mask_t intersectWithMask(Mask_t A, Mask_t B);
1017 
1018  /**
1019  * @brief Returns a new mask with only the specified bits set.
1020  * @param baseMask the starting mask
1021  * @param bits the bits to be set
1022  * @return a new mask with all defined flags from baseMask, with only the
1023  * specified bits set
1024  *
1025  * All bits in the argument are also defined.
1026  *
1027  * The truth table of this operation follows (see `mergeIntoMask()` for
1028  * its legend).
1029  *
1030  * | `bits` | 0 | 1 |
1031  * | ---------- | ------- | ------- |
1032  * | `baseMask` | | |
1033  * | - | - | 1 |
1034  * | 0 | 0 | 0 |
1035  * | 1 | 0 | 1 |
1036  *
1037  */
1038  static constexpr Mask_t intersectWithMask(Mask_t baseMask, Bits_t bits);
1039 
1040  /**
1041  * @brief Returns a new mask with the specified flag as only set flag.
1042  * @param baseMask the starting mask
1043  * @param flag the single flag to be set
1044  * @return a new mask with all flags from baseMask, with only flag set
1045  */
1046  static constexpr Mask_t intersectWithMask(Mask_t baseMask, Flag_t flag);
1047 
1048  /**
1049  * @brief Returns a new mask with the bits set from both masks.
1050  * @param baseMask one of the masks to be combined
1051  * @param mask the other mask to be combined
1052  * @return a new mask with all bits set in both masks
1053  *
1054  * The content of the new mask has a bit set if it was set (`isSet()`) in
1055  * both masks, otherwise unset if it was unset (`isUnset()`) in
1056  * either of the masks, or else undefined (`isUndefined()`), as it was
1057  * undefined in both masks.
1058  *
1059  * The truth table of this operation follows (see `mergeIntoMask()` for
1060  * its legend).
1061  *
1062  * | `mask` | - | 0 | 1 |
1063  * | ---------- | ------- | ------- | ------- |
1064  * | `baseMask` | | | |
1065  * | - | - | 0 | 0 |
1066  * | 0 | 0 | 0 | 0 |
1067  * | 1 | 1 | 1 | 0 |
1068  *
1069  */
1070  static constexpr Mask_t unsetMask(Mask_t baseMask, Mask_t mask);
1071 
1072  /**
1073  * @brief Returns a new mask with only the specified bits set.
1074  * @param baseMask the starting mask
1075  * @param bits the bits to be set
1076  * @return a new mask with all defined flags from baseMask, with only the
1077  * specified bits set
1078  *
1079  * All bits in the argument are also defined.
1080  *
1081  * The truth table of this operation follows (see `mergeIntoMask()` for
1082  * its legend).
1083  *
1084  * | `bits` | 0 | 1 |
1085  * | ---------- | ------- | ------- |
1086  * | `baseMask` | | |
1087  * | - | - | 0 |
1088  * | 0 | 0 | 0 |
1089  * | 1 | 1 | 0 |
1090  *
1091  */
1092  static constexpr Mask_t unsetMask(Mask_t baseMask, Bits_t bits);
1093 
1094  /**
1095  * @brief Returns a new mask with the specified flag as only set flag.
1096  * @param baseMask the starting mask
1097  * @param flag the single flag to be set
1098  * @return a new mask with all flags from baseMask, with only flag set
1099  */
1100  static constexpr Mask_t unsetMask(Mask_t baseMask, Flag_t flag);
1101 
1102  /**
1103  * @brief Returns the negation of mask.
1104  * @param mask the starting mask
1105  * @return a new mask with all defined bits flipped
1106  *
1107  * The bits which were undefined, stay so. The others change their value.
1108  *
1109  * The truth table of this operation follows (see `mergeIntoMask()` for
1110  * its legend).
1111  *
1112  * | `mask` | `negate()` |
1113  * | -------- | ---------- |
1114  * | - | - |
1115  * | 0 | 1 |
1116  * | 1 | 0 |
1117  *
1118  */
1119  static constexpr Mask_t negateMask(Mask_t mask);
1120 
1121  /**
1122  * @brief Returns a new mask with the specified bits unset.
1123  * @param bits bits to be unset
1124  * @return a new mask with the specified bits unset
1125  *
1126  * Only the unset bits are defined.
1127  */
1128  static constexpr Mask_t negateMask(Bits_t bits);
1129 
1130  /**
1131  * @brief Returns a new mask with the specified flag unset.
1132  * @param flag the single flag to be set
1133  * @return a new mask with only the flag bit defined, and unset
1134  */
1135  static constexpr Mask_t negateMask(Flag_t flag);
1136 
1137  /// @}
1138  // -- END Static mask manipulation ---------------------------------------
1139 
1140  private:
1141 
1142  Bits_t values; ///< Storage of value bits.
1143  Bits_t presence; ///< Storage of definition bits.
1144 
1145  // Storage details
1146  // We store values and definition information in two different bit
1147  // buckets; the same Flag_t pattern is good for both.
1148 
1149  /// Marks a flag as defined. Value is still uninitialised!
1150  void defineSingle(Flag_t flag);
1151 
1152  /// Marks a flag as undefined.
1153  void undefineSingle(Flag_t flag);
1154 
1155  /// Implementation detail of remove()
1156  void undefineImpl() {}
1157 
1158  /// Implementation detail of remove()
1159  template <typename... Flags>
1160  void undefineImpl(Flag_t flag, Flags... others);
1161 
1162  /// Implementation detail of set()
1163  void setImpl() {}
1164 
1165  /// Implementation detail of set()
1166  template <typename... Flags>
1167  void setImpl(Flag_t flag, Flags... others);
1168 
1169  /// Implementation detail of set()
1170  void setSingle(Flag_t flag);
1171 
1172  /// Implementation detail of unset()
1173  void unsetImpl() {}
1174 
1175  /// Returns a bit set with all undefined bits unset.
1176  constexpr Bits_t definedOnly() const;
1177 
1178  /// Implementation detail of unset()
1179  template <typename... Flags>
1180  void unsetImpl(Flag_t flag, Flags... others);
1181 
1182  /// Implementation detail of unset()
1183  void unsetSingle(Flag_t flag);
1184 
1185  /// Returns whether any of the specified bits is set.
1186  static constexpr bool testBits(Storage_t data, Storage_t bits)
1187  { return data & bits; }
1188 
1189  /// Returns whether all the specified bits in the mask are set.
1190  static constexpr bool testBitmask(Storage_t data, Storage_t mask)
1191  { return (data & mask) == mask; }
1192 
1193  /// Returns whether all the specified bits in the mask are set.
1194  static constexpr bool testUnsetBitmask(Storage_t data, Storage_t mask)
1195  { return (data & ~mask) == data; }
1196 
1197 
1198  }; // BitMask<>
1199 
1200 
1201  /// Output of a bit mask into a stream.
1202  template <typename Stream, typename Storage>
1203  Stream& operator<< (Stream&& out, BitMask<Storage> const& mask)
1204  { mask.dump(std::forward<Stream>(out)); return out; }
1205 
1206 
1207  // -- BEGIN Flag and mask management ---------------------------------------
1208  /**
1209  * @name Flag and mask management
1210  *
1211  * The operations use the first operand as the starting point for the
1212  * result.
1213  * The binary operations in this group are:
1214  *
1215  * * bit-wise OR (equivalent to `combineWithMask()`)
1216  * * bit-wise AND (equivalent to `intersectWithMask()`)
1217  * * addition: the flags of the right operand that are defined are copied
1218  * into the result
1219  * * subtraction: the flags of the right operand that are set are unset
1220  * in the result
1221  *
1222  * The unary operations are:
1223  * * bitwise negation (equivalent to `negateMask()`)
1224  * * unary plus sign: no operation (bit it converts the operand to `Mask_t`)
1225  * * unary minus sign is not defined
1226  *
1227  */
1228  /// @{
1229 
1230 
1231  /// Returns a mask which combines two of them.
1232  /// @see `BitMask<Storage>::combineWithMask()`
1233  template <typename Storage>
1234  constexpr BitMask<Storage> operator|
1235  (BitMask<Storage> left, BitMask<Storage> right);
1236 
1237  /// Returns a mask which merges two of them.
1238  /// @see `BitMask<Storage>::combineWithMask()`
1239  template <typename Storage>
1240  constexpr BitMask<Storage> operator|
1241  (BitMask<Storage> left, typename BitMask<Storage>::Bits_t right);
1242 
1243  /// Returns a mask which merges two of them.
1244  /// @see `BitMask<Storage>::combineWithMask()`
1245  template <typename Storage>
1246  constexpr BitMask<Storage> operator|
1247  (typename BitMask<Storage>::Bits_t left, BitMask<Storage> right);
1248 
1249  // operator|(Bits_t, Bits_t) is still a Bits_t
1250 
1251 
1252  /// Returns a mask which intersects two of them.
1253  /// @see `BitMask<Storage>::intersectWithMask()`
1254  template <typename Storage>
1255  constexpr BitMask<Storage> operator&
1256  (BitMask<Storage> left, BitMask<Storage> right);
1257 
1258  /// Returns a mask which intersects two of them.
1259  /// @see `BitMask<Storage>::intersectWithMask()`
1260  template <typename Storage>
1261  constexpr BitMask<Storage> operator&
1262  (BitMask<Storage> left, typename BitMask<Storage>::Bits_t right);
1263 
1264  /// Returns a mask which intersects two of them.
1265  /// @see `BitMask<Storage>::intersectWithMask()`
1266  template <typename Storage>
1267  constexpr BitMask<Storage> operator&
1268  (typename BitMask<Storage>::Bits_t left, BitMask<Storage> right);
1269 
1270  /// Returns a mask which intersects two of them.
1271  /// @see `BitMask<Storage>::intersectWithMask()`
1272  template <typename Storage>
1273  constexpr BitMask<Storage> operator&
1274  (Bits_t<Storage> left, Bits_t<Storage> right);
1275 
1276 
1277  /// Returns a mask which merges two of them.
1278  /// @see `BitMask<Storage>::mergeIntoMask()`
1279  template <typename Storage>
1280  constexpr BitMask<Storage> operator+
1281  (BitMask<Storage> baseMask, BitMask<Storage> mask);
1282 
1283  /// Returns a mask which merges two of them
1284  /// @see `BitMask<Storage>::mergeIntoMask()`
1285  template <typename Storage>
1286  constexpr BitMask<Storage> operator+
1287  (BitMask<Storage> baseMask, typename BitMask<Storage>::Bits_t bits);
1288 
1289  /// Returns a mask which merges two of them
1290  /// @see `BitMask<Storage>::mergeIntoMask()`
1291  template <typename Storage>
1292  constexpr BitMask<Storage> operator+
1293  (typename BitMask<Storage>::Bits_t baseBits, BitMask<Storage> mask);
1294 
1295  // operator+(Bits_t, Bits_t) is still a Bits_t
1296 
1297 
1298  /// Returns a mask set which defines and unsets the bits set in the mask.
1299  /// @see `BitMask<Storage>::unsetMask()`
1300  template <typename Storage>
1301  constexpr BitMask<Storage> operator-
1302  (BitMask<Storage> baseMask, BitMask<Storage> mask);
1303 
1304  /// Returns a mask set which defines and unsets the specified bits.
1305  /// @see `BitMask<Storage>::unsetMask()`
1306  template <typename Storage>
1307  constexpr BitMask<Storage> operator-
1308  (BitMask<Storage> baseMask, typename BitMask<Storage>::Bits_t bits);
1309 
1310  /// Returns a mask set which defines and unsets the bits set in the mask.
1311  /// @see `BitMask<Storage>::unsetMask()`
1312  template <typename Storage>
1313  constexpr BitMask<Storage> operator-
1314  (typename BitMask<Storage>::Bits_t baseBits, BitMask<Storage> mask);
1315 
1316  /// Returns a mask which defines and unsets the specified bits.
1317  /// @see `BitMask<Storage>::unsetMask()`
1318  template <typename Storage>
1319  constexpr BitMask<Storage> operator-
1320  (Bits_t<Storage> baseBits, Bits_t<Storage> bits);
1321 
1322 
1323  /// Returns a copy of the mask.
1324  template <typename Storage>
1325  constexpr BitMask<Storage> operator+ (BitMask<Storage> mask);
1326 
1327  /// Returns a mask with the specified bits set.
1328  template <typename Storage>
1329  constexpr BitMask<Storage> operator+ (Bits_t<Storage> bits);
1330 
1331 
1332  /// Returns a mask `M = -B` so that `A + M` is equivalent to `A - B`.
1333  template <typename Storage>
1334  constexpr BitMask<Storage> operator- (Bits_t<Storage> bits);
1335 
1336  /// Returns a mask `M = -B` so that `A + M` is equivalent to `A - B`.
1337  template <typename Storage>
1338  constexpr BitMask<Storage> operator- (Flag_t<Storage> flag);
1339 
1340 
1341  /// Returns a bit set which unsets the specified bits.
1342  template <typename Storage>
1343  constexpr BitMask<Storage> operator~
1344  (BitMask<Storage> mask);
1345 
1346  /*
1347  /// Returns a bit set which unsets the specified bits.
1348  template <typename Storage>
1349  constexpr BitMask<Storage> operator~ (Bits_t<Storage> bits);
1350  */
1351 
1352 
1353  /// Returns a bit mask which sets the specified flag.
1354  template <typename Storage>
1355  constexpr BitMask<Storage> Set(Flag_t<Storage> flag);
1356 
1357  /// Returns a bit mask which unsets the specified flag.
1358  template <typename Storage>
1359  constexpr BitMask<Storage> Unset(Flag_t<Storage> flag);
1360 
1361 
1362  /// @}
1363  // -- END Flag and mask management -----------------------------------------
1364 
1365  /// Constructs a mask from bits
1366  template <typename Storage>
1367  constexpr BitMask<Storage> makeMask(Bits_t<Storage> bits);
1368 
1369 
1370  } // namespace flags
1371 
1372 } // namespace util
1373 
1374 
1375 //------------------------------------------------------------------------------
1376 //--- template implementation
1377 //---
1378 
1379 #include "lardataobj/Utilities/BitMask.tcc"
1380 
1381 //------------------------------------------------------------------------------
1382 
1383 
1384 #endif // LARDATAOBJ_UTILITIES_BITMASK_H
typename Bits_t::Flag_t Flag_t
Type identifying a single flag.
Definition: BitMask.h:434
Storage_t bits
The bits representing this flag (only one is set)
Definition: BitMask.h:93
constexpr unsigned int computePages(unsigned int bits)
Returns the number of Storage variables needed to hold that many bits.
constexpr Bits_t(Flag_t flag)
Constructs from a single flag.
Definition: BitMask.h:207
void dump(Stream &&out, unsigned int nBits) const
Prints into the specified stream the least nBits significant bits.
constexpr bool isSet(Flag_t flag) const
Returns if the specified flag is set.
constexpr bool operator==(This_t other) const
Definition: BitMask.h:116
constexpr bool match(Mask_t const &mask) const
Returns whether all bits defined in the mask are equal to ours.
typename SmallestUIntType< NBits >::type smallestUInt_t
The smallest integral type accommodating NBits bits.
Definition: BitMask.h:71
then echo unknown compiler flag
constexpr bool operator>(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:158
constexpr bool none(Bits_t bits) const
Returns whether all the specified bits are unset.
walls no right
Definition: selectors.fcl:105
constexpr bool anySet(Mask_t const &mask) const
Returns whether any of the bits set in the mask are set.
Base class for exceptions thrown by flag-related utilities.
Definition: BitMask.h:375
static constexpr size_t capacity()
Returns the number of flags the set has room for.
void defineSingle(Flag_t flag)
Marks a flag as defined. Value is still uninitialised!
FlagNotDefined(std::string msg="Flag undefined-flag error")
Definition: BitMask.h:384
Type identifying a flag. Operations are implemented as free functions.
Definition: BitMask.h:89
virtual const char * what() const noexceptoverride
Definition: BitMask.h:377
static constexpr bool
static void onlyBits(Storage_t &base, Storage_t bits)
Definition: BitMask.h:306
constexpr bool operator>=(This_t other) const
Definition: BitMask.h:126
static constexpr auto fromValues
Constructor tag from values.
Definition: BitMask.h:451
constexpr Bits_t definedOnly() const
Returns a bit set with all undefined bits unset.
static constexpr Mask_t create(Args...args)
Creates a new BitMask.
void unsetImpl()
Implementation detail of unset()
Definition: BitMask.h:1173
constexpr bool operator!=(This_t other) const
Definition: BitMask.h:118
constexpr bool operator>=(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:172
unsigned int Index_t
Type to denote the index of the flag.
Definition: BitMask.h:60
util::flags::Index_t FlagIndex_t
Type of index of flag.
Definition: BitMask.h:429
void undefineSingle(Flag_t flag)
Marks a flag as undefined.
void dump(Stream &&out) const
Prints into the specified stream all bits.
Definition: BitMask.h:855
void rangeUnset(BeginIter begin, EndIter end)
Unsets all flags specified by the index iterator range.
Type for constructor tag from values.
Definition: BitMask.h:401
static constexpr Mask_t negateMask(Mask_t mask)
Returns the negation of mask.
static constexpr bool testUnsetBitmask(Storage_t data, Storage_t mask)
Returns whether all the specified bits in the mask are set.
Definition: BitMask.h:1194
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
static constexpr bool testBits(Storage_t data, Storage_t bits)
Returns whether any of the specified bits is set.
Definition: BitMask.h:1186
constexpr bool operator>(This_t other) const
Definition: BitMask.h:122
constexpr BitMask< Storage > operator-(BitMask< Storage > baseMask, BitMask< Storage > mask)
A class containing a set of flags.
Definition: BitMask.h:420
constexpr Storage makeBits(Index_t index)
Returns a set of bits with only the one at the specified index set.
Definition: BitMask.h:79
constexpr This_t invert() const
Returns all and only the bits that are not set.
static constexpr Mask_t mergeIntoMask(Mask_t baseMask, Mask_t mask)
Returns a new mask with the content of the other mask merged.
static constexpr Mask_t combineWithMask(Mask_t A, Mask_t B)
Returns a new mask combining bits set from two masks.
constexpr bool empty() const
Returns whether there is no bit set at all.
Definition: BitMask.h:220
void unset(This_t bits)
Unsets the specified bits.
constexpr Flag_t(Index_t flagIndex)
Constructs from the flag index.
Definition: BitMask.h:96
constexpr mask_t< EnumType > mask(EnumType bit, OtherBits...otherBits)
Returns a mask with all specified bits set.
constexpr bool isUnset(Flag_t flag) const
Returns if the specified flag is unset.
constexpr bool noneSet(Mask_t const &mask) const
Returns whether none of the bits set in the mask is set.
constexpr bool operator!=(Mask_t const &other) const
Definition: BitMask.h:845
constexpr bool operator<(This_t other) const
Definition: BitMask.h:282
constexpr BitMask< Storage > Set(Flag_t< Storage > flag)
Returns a bit mask which sets the specified flag.
static void setBits(Storage_t &base, Storage_t bits)
Returns data with all bits from base and from bits set.
Definition: BitMask.h:301
constexpr bool operator>=(This_t other) const
Definition: BitMask.h:288
details::smallestUInt_t< NFlags > Storage_t
Type of underlying bit data representation.
Definition: BitMask.h:423
Storage Storage_t
Definition: BitMask.h:90
void clear()
Unsets all bits.
Definition: BitMask.h:251
constexpr bool only(This_t bits) const
Returns wether no bits are set except (at most) the specified ones.
constexpr bool any(This_t bits) const
Returns wether at least one of the bits is set.
walls no left
Definition: selectors.fcl:105
constexpr Bits_t< Storage > operator+(Bits_t< Storage > left, Bits_t< Storage > right)
Returns a new Bits_t with all the bits from both arguments set.
constexpr bool none(This_t bits) const
Returns wether all bits are unset.
static constexpr bool testBitmask(Storage_t data, Storage_t mask)
Returns whether all the specified bits in the mask are set.
Definition: BitMask.h:1190
constexpr bool operator!=(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:144
constexpr This_t combine(This_t bits) const
Returns our bits, plus the ones present in the argument.
Type identifying a set of bits.
Definition: BitMask.h:194
constexpr BitMask< Storage > makeMask(Bits_t< Storage > bits)
Constructs a mask from bits.
BitMask< Storage > Mask_t
This type.
Definition: BitMask.h:427
constexpr bool operator==(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:137
constexpr bool any(Bits_t bits) const
Returns whether at least one of the specified bits is set.
constexpr bool operator>(This_t other) const
Definition: BitMask.h:284
constexpr BitMask()=default
Default constructor: no flag defined at all.
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not defined
constexpr BitMask(Bits_t first, Others...others)
Constructor: merges all arguments in the argument list.
Definition: BitMask.h:550
void unsetSingle(Flag_t flag)
Implementation detail of unset()
constexpr bool all(This_t bits) const
Returns wether all bits are set.
void unset(Flag first, OtherFlags...others)
Unsets all specified flags.
Definition: BitMask.h:779
constexpr BitMask(Flag_t first, Others...others)
Constructor: merges all arguments in the argument list.
Definition: BitMask.h:536
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
constexpr bool operator==(Mask_t const &other) const
Definition: BitMask.h:840
Bits_t< Storage > This_t
This type.
Definition: BitMask.h:196
static void unsetBits(Storage_t &base, Storage_t bits)
Returns data with all bits from base, but the ones from bits unset.
Definition: BitMask.h:310
std::string to_string(WindowPattern const &pattern)
Exception(std::string msg="Flag error")
Definition: BitMask.h:376
util::flags::Flag_t< Storage_t > Flag_t
Type of flag matching our storage.
Definition: BitMask.h:199
void keepOnly(This_t bits)
Unsets the bits which are not in bits argument.
Bits_t values
Storage of value bits.
Definition: BitMask.h:1142
constexpr Bits_t(Storage_t bits)
Constructs from a set of bits.
Definition: BitMask.h:212
void setImpl()
Implementation detail of set()
Definition: BitMask.h:1163
Exception thrown to convey that an invalid flag index was used.
Definition: BitMask.h:390
constexpr bool operator<=(This_t other) const
Definition: BitMask.h:124
static constexpr Mask_t intersectWithMask(Mask_t A, Mask_t B)
Returns a new mask with the bits set from both masks.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
constexpr bool isDefined(Flag_t flag) const
Returns whether the flag is defined.
constexpr BitMaskFromValuesTag maskFromValues
Value useful for BitMask constructors from value.
Definition: BitMask.h:404
Bits_t presence
Storage of definition bits.
Definition: BitMask.h:1143
float A
Definition: dedx.py:137
void clear()
Undefines all bits.
Definition: BitMask.h:821
OutOfRange(std::string msg="Flag out-of-range error")
Definition: BitMask.h:391
constexpr This_t select(This_t bits) const
Returns only the bits that are also present in the argument.
void set(This_t bits)
Sets the specified bits.
Storage_t data
The bits representing all set bits.
Definition: BitMask.h:201
constexpr Flag_t copy() const
Returns a copy of this object.
Definition: BitMask.h:111
constexpr bool operator!=(This_t other) const
Definition: BitMask.h:280
void set(Flag first, OtherFlags...others)
Sets all specified flags.
Definition: BitMask.h:751
constexpr Index_t index() const
Returns the index of the (first) bit set.
constexpr bool operator==(This_t other) const
Definition: BitMask.h:278
Exception thrown to convey that an undefined flag index was tested.
Definition: BitMask.h:383
constexpr BitMask< Storage > Unset(Flag_t< Storage > flag)
Returns a bit mask which unsets the specified flag.
void rangeSet(BeginIter begin, EndIter end)
Sets all flags specified by the index iterator range.
constexpr bool all(Bits_t bits) const
Returns whether all the specified bits are set.
constexpr bool isUndefined(Flag_t flag) const
Returns whether the flag is undefined.
bnb BNB Stream
constexpr This_t exclude(This_t bits) const
Returns only the bits that are not present in the argument.
void undefineImpl()
Implementation detail of remove()
Definition: BitMask.h:1156
static constexpr Mask_t unsetMask(Mask_t baseMask, Mask_t mask)
Returns a new mask with the bits set from both masks.
void setSingle(Flag_t flag)
Implementation detail of set()
constexpr bool operator<=(This_t other) const
Definition: BitMask.h:286
constexpr bool operator<(This_t other) const
Definition: BitMask.h:120
constexpr bool operator!() const
Returns true if there is no bit set.
Definition: BitMask.h:297
constexpr Bits_t()=default
Default constructor: no bit set.
constexpr BitMask(Mask_t first, Second second, Others...others)
Constructor: merges all arguments in the argument list.
Definition: BitMask.h:569