FlagSet.h
Go to the documentation of this file.
1 /**
2  * @file FlagSet.h
3  * @brief Class holding flags.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date January 25, 2017
6  * @see BitMask.h
7  *
8  */
9 
10 #ifndef LARDATAOBJ_UTILITIES_FLAGSET_H
11 #define LARDATAOBJ_UTILITIES_FLAGSET_H
12 
13 // LArSoft headers
14 
16 
17 // C/C++ standard library
18 #include <iosfwd> // std::ostream
19 #include <string>
20 #include <exception>
21 
22 namespace util {
23 
24  namespace flags {
25 
26  /** ************************************************************************
27  * @brief A class containing a set of flags.
28  * @tparam NFlags number of flags to be allocated
29  * @tparam Storage underlying integral type whose bits represent the flags
30  *
31  * A FlagSet contains a set of flags. Each flag can be in one of two
32  * states ("set" and "unset"), or can be not defined at all ("undefined").
33  *
34  * Note that the object might have a `capacity()` larger than just `NFlags`.
35  * The flags after the first `NFlags` are "unsupported", in the sense that
36  * in future implementations they might disappear. For the rest, they behave
37  * just like the other flags though.
38  */
39  template
40  <unsigned int NFlags, typename Storage = details::smallestUInt_t<NFlags>>
41  class FlagSet: public BitMask<Storage> {
42 
43  static_assert(details::computePages<Storage>(NFlags) <= 1,
44  "Too many flags for this storage type.");
45 
46  public:
47  using This_t = FlagSet<NFlags, Storage>; ///< Type of this class.
48 
49  using Mask_t = BitMask<Storage>; ///< Type of bit mask for this flag set.
50 
51  using Base_t = Mask_t; ///< Type of the base class.
52 
53  /// Type of bits for this flag set.
54  using Bits_t = typename Mask_t::Bits_t;
55 
56  /// Type of index of flag.
57  using FlagIndex_t = typename Mask_t::FlagIndex_t;
58 
59  /// Type identifying a single flag.
60  using Flag_t = typename Mask_t::Flag_t;
61 
62 
63  /// @{
64  /// @name Exceptions
65 
66  /// Generic BitMask exception.
67  using Exception = typename Mask_t::Exception;
68 
69  /// Out-of-range flag index.
71 
72  /// Flag not defined.
74 
75  /// @}
76 
77 
78  FlagSet() = default;
79  FlagSet(This_t const&) = default;
80  FlagSet(This_t&&) = default;
81  FlagSet& operator= (This_t const&) = default;
82  FlagSet& operator= (This_t&&) = default;
83 
84  /// Constructor: copy the specified mask.
85  // This is effectively a copy constructor due to the definition of Mask_t.
86  constexpr FlagSet(Mask_t const& from): Base_t(from) {}
87 
88 
89  using Base_t::Base_t; // inherit the rest of the constructors
90 
91 
92 
93  /// @{
94  /// @name Access to flags
95 
96  /// Returns all the flags in the form of a mask.
97  constexpr Mask_t const& mask() const { return *this; }
98 
99  /**
100  * @brief Returns whether the flag index is valid.
101  * @param flagIndex index of the flag to check
102  * @return whether the flag index is valid
103  *
104  * Valid flag index values go from 0 up to the size (`size()`) of this
105  * flag set.
106  */
107  constexpr bool isFlag(FlagIndex_t flagIndex) const;
108 
109  /**
110  * @brief Returns whether the flag index is valid.
111  * @param flag flag to check
112  * @return whether the flag is valid
113  *
114  * Valid flag index values go from 0 up to the size (`size()`) of this
115  * flag set.
116  *
117  * @note This method is unable to check flags that are beyond the capacity
118  * of the flag set itself. For example, in a flag set represented
119  * with 8 bits, the Flag_t value corresponding to flag #12 would be
120  * `Flag_t(0x1000)`, which is beyond the range that `Flag_t` can
121  * represent.
122  */
123  constexpr bool isFlag(Flag_t flag) const;
124 
125 
126  /**
127  * @brief Returns if the specified flag is set.
128  * @param flag flag to test
129  * @return whether the specified flag is set
130  * @throw FlagNotDefinedError if the flag was not defined at all
131  * @throw OutOfRangeError if the flag index denotes a non-existing flag
132  *
133  * This method provides a checked access to a single flag value.
134  * If the flag is not supported (see `isFlag()`), or if it is
135  * `isUndefined()`, an exception is thrown.
136  *
137  * See `get()` for an unchecked access.
138  */
139  bool test(Flag_t flag) const;
140 
141  /**
142  * @brief Returns if the specified flag is set.
143  * @param flagIndex index of the flag to test
144  * @return whether the specified flag is set
145  * @throw FlagNotDefinedError if the flag was not defined at all
146  * @throw OutOfRangeError if the flag index denotes a non-existing flag
147  *
148  * This method provides a checked access to a single flag value.
149  * If the flag is not supported (see `isFlag()`), or if it is
150  * `isUndefined()`, an exception is thrown.
151  *
152  * See `get()` for an unchecked access.
153  */
154  bool test(FlagIndex_t flagIndex) const;
155 
156  /// @}
157 
158 
159  /// Dumps on screen only the "official" flags (see `size()`).
160  template <typename Stream>
161  void dump(Stream&& out) const
162  { mask().dump(std::forward<Stream>(out), size()); }
163 
164 
165  /// Returns the number of flags the set supports.
166  static constexpr size_t size()
167  { return NFlags; }
168 
169 
170  /**
171  * @brief Creates a new BitMask.
172  * @tparam Args types of the arguments
173  * @param args the data to create the mask from
174  * @return a BitMask with the features specified in the arguments
175  *
176  * If no argument is provided, the mask is returned with all the flags
177  * undefined (like in default constructor).
178  * For the details, see `BitMask<Storage>::createMask()`.
179  *
180  */
181  template <typename... Args>
182  static constexpr Mask_t createMask(Args... args)
183  { return Mask_t::create(args...); }
184 
185  private:
186 
187  /// Implementation detail of test()
188  bool testImpl(Flag_t flag) const;
189 
190  }; // class FlagSet<>
191 
192 
193  /// Output of a flag set into a stream.
194  template <unsigned int NBits, typename Storage>
195  std::ostream& operator<<
196  (std::ostream& out, FlagSet<NBits, Storage> const& flags)
197  { flags.dump(out); return out; }
198 
199  } // namespace flags
200 
201 } // namespace util
202 
203 
204 //------------------------------------------------------------------------------
205 //--- template implementation
206 //---
207 
208 #include "FlagSet.tcc"
209 
210 //------------------------------------------------------------------------------
211 
212 
213 #endif // LARDATAOBJ_UTILITIES_FLAGSET_H
typename Bits_t::Flag_t Flag_t
Type identifying a single flag.
Definition: BitMask.h:434
void dump(Stream &&out, unsigned int nBits) const
Prints into the specified stream the least nBits significant bits.
Namespace for general, non-LArSoft-specific utilities.
errors::OutOfRange OutOfRangeError
Out-of-range flag index.
Definition: BitMask.h:443
Class holding flags.
errors::Exception Exception
Generic BitMask exception.
Definition: BitMask.h:440
Base class for exceptions thrown by flag-related utilities.
Definition: BitMask.h:375
errors::FlagNotDefined FlagNotDefinedError
Flag not defined.
Definition: BitMask.h:446
util::flags::Bits_t< Storage_t > Bits_t
Set of bits.
Definition: BitMask.h:431
static QCString args
Definition: declinfo.cpp:674
A class containing a set of flags.
Definition: FlagSet.h:41
constexpr Mask_t const & mask() const
Returns all the flags in the form of a mask.
Definition: FlagSet.h:97
static constexpr Mask_t create(Args...args)
Creates a new BitMask.
util::flags::Index_t FlagIndex_t
Type of index of flag.
Definition: BitMask.h:429
A class containing a set of flags.
Definition: BitMask.h:420
static constexpr Mask_t createMask(Args...args)
Creates a new BitMask.
Definition: FlagSet.h:182
bool test(Flag_t flag) const
Returns if the specified flag is set.
FlagSet & operator=(This_t const &)=default
constexpr FlagSet(Mask_t const &from)
Constructor: copy the specified mask.
Definition: FlagSet.h:86
constexpr bool isFlag(FlagIndex_t flagIndex) const
Returns whether the flag index is valid.
void dump(Stream &&out) const
Dumps on screen only the "official" flags (see size()).
Definition: FlagSet.h:161
Exception thrown to convey that an invalid flag index was used.
Definition: BitMask.h:390
bool testImpl(Flag_t flag) const
Implementation detail of test()
Exception thrown to convey that an undefined flag index was tested.
Definition: BitMask.h:383
BitMask< Storage > Mask_t
Type of bit mask for this flag set.
Definition: FlagSet.h:49
static constexpr size_t size()
Returns the number of flags the set supports.
Definition: FlagSet.h:166