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>
158  constexpr bool operator> (Index_t left, Flag_t<Storage> right)
159  { return left > right.index(); }
160  template <typename Storage>
161  constexpr bool operator> (Flag_t<Storage> left, Index_t right)
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>
172  constexpr bool operator>= (Index_t left, Flag_t<Storage> right)
173  { return left >= right.index(); }
174  template <typename Storage>
175  constexpr bool operator>= (Flag_t<Storage> left, Index_t right)
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>
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|
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|
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|
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|
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+
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+
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+
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+
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(); }
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  */
480  constexpr BitMask(BitMaskFromValuesTag, Storage_t defined);
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  */
515  constexpr BitMask(BitMaskFromValuesTag, Bits_t defined, Bits_t values);
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|
1236 
1237  /// Returns a mask which merges two of them.
1238  /// @see `BitMask<Storage>::combineWithMask()`
1239  template <typename Storage>
1240  constexpr BitMask<Storage> operator|
1242 
1243  /// Returns a mask which merges two of them.
1244  /// @see `BitMask<Storage>::combineWithMask()`
1245  template <typename Storage>
1246  constexpr BitMask<Storage> operator|
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&
1257 
1258  /// Returns a mask which intersects two of them.
1259  /// @see `BitMask<Storage>::intersectWithMask()`
1260  template <typename Storage>
1261  constexpr BitMask<Storage> operator&
1263 
1264  /// Returns a mask which intersects two of them.
1265  /// @see `BitMask<Storage>::intersectWithMask()`
1266  template <typename Storage>
1267  constexpr BitMask<Storage> operator&
1269 
1270  /// Returns a mask which intersects two of them.
1271  /// @see `BitMask<Storage>::intersectWithMask()`
1272  template <typename Storage>
1273  constexpr BitMask<Storage> operator&
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+
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-
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>
1326 
1327  /// Returns a mask with the specified bits set.
1328  template <typename Storage>
1330 
1331 
1332  /// Returns a mask `M = -B` so that `A + M` is equivalent to `A - B`.
1333  template <typename Storage>
1335 
1336  /// Returns a mask `M = -B` so that `A + M` is equivalent to `A - B`.
1337  template <typename Storage>
1339 
1340 
1341  /// Returns a bit set which unsets the specified bits.
1342  template <typename Storage>
1343  constexpr BitMask<Storage> operator~
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
Namespace for general, non-LArSoft-specific utilities.
void msg(const char *fmt,...)
Definition: message.cpp:107
typename SmallestUIntType< NBits >::type smallestUInt_t
The smallest integral type accommodating NBits bits.
Definition: BitMask.h:71
constexpr bool operator<(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:151
constexpr bool operator>(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:158
std::string string
Definition: nybbler.cc:12
constexpr bool operator<=(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:165
Base class for exceptions thrown by flag-related utilities.
Definition: BitMask.h:375
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
static void onlyBits(Storage_t &base, Storage_t bits)
Definition: BitMask.h:306
static QCString args
Definition: declinfo.cpp:674
void unsetImpl()
Implementation detail of unset()
Definition: BitMask.h:1173
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 dump(Stream &&out) const
Prints into the specified stream all bits.
Definition: BitMask.h:855
Type for constructor tag from values.
Definition: BitMask.h:401
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 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 bool empty() const
Returns whether there is no bit set at all.
Definition: BitMask.h:220
constexpr Flag_t(Index_t flagIndex)
Constructs from the flag index.
Definition: BitMask.h:96
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
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
def dump(input_file, output_file)
Definition: dumpTree.py:102
Storage 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
bool invert(ublas::matrix< T, L, A > &m)
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.
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
auto select(T const &...t)
Definition: select.h:146
constexpr bool operator!=(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:144
Type identifying a set of bits.
Definition: BitMask.h:194
unsigned short Storage_t
Definition: FlagSet_test.cc:36
constexpr BitMask< Storage > makeMask(Bits_t< Storage > bits)
Constructs a mask from bits.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
constexpr bool operator==(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:137
constexpr BitMask(Bits_t first, Others...others)
Constructor: merges all arguments in the argument list.
Definition: BitMask.h:550
static QInternalList< QTextCodec > * all
Definition: qtextcodec.cpp:63
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
virtual const char * what() const noexcept override
Definition: BitMask.h:377
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
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
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
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
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
void clear()
Undefines all bits.
Definition: BitMask.h:821
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
OutOfRange(std::string msg="Flag out-of-range error")
Definition: BitMask.h:391
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
int bool
Definition: qglobal.h:345
constexpr Index_t index() const
Returns the index of the (first) bit set.
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.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void undefineImpl()
Implementation detail of remove()
Definition: BitMask.h:1156
constexpr bool operator!() const
Returns true if there is no bit set.
Definition: BitMask.h:297
constexpr BitMask(Mask_t first, Second second, Others...others)
Constructor: merges all arguments in the argument list.
Definition: BitMask.h:569