Gazebo Common

API Reference

4.7.0
gz/common/FlagSet.hh
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2019 Arnaud Kapp (Xaqq), Barry Revzin, Mart Sõmermaa
5  * Copyright (c) 2020 Martin Pecka
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 #ifndef IGNITION_COMMON_FLAGSET_HH
26 #define IGNITION_COMMON_FLAGSET_HH
27 
28 // FlagSet is a type-safe class for using enums as flags in C++14 with an
29 // underlying std::bitset.
30 // See https://github.com/mrts/flag-set-cpp
31 // Licence: MIT
32 
33 #include <bitset>
34 #include <iostream>
35 #include <cassert>
36 #include <string>
37 
38 #include <gz/common/config.hh>
39 
40 namespace ignition::common
41 {
42 
60 template<typename T, T LastElement = T::_, bool ExcludeLast = true>
61 class FlagSet
62 {
64  public: FlagSet() = default;
65 
71  // cppcheck-suppress noExplicitConstructor
72  public: FlagSet(const T& _val)
73  {
74  flags.set(static_cast<UnderlyingType>(_val));
75  }
76 
79  public: explicit FlagSet(const std::initializer_list<T>& _list)
80  {
81  for (const auto& val : _list)
82  {
83  flags.set(static_cast<UnderlyingType>(val));
84  }
85  }
86 
87  // Binary operations.
88 
93  public: FlagSet& operator&=(const T& _val) noexcept
94  {
95  bool tmp = flags.test(static_cast<UnderlyingType>(_val));
96  flags.reset();
97  flags.set(static_cast<UnderlyingType>(_val), tmp);
98  return *this;
99  }
100 
104  public: FlagSet& operator&=(const FlagSet& _o) noexcept
105  {
106  flags &= _o.flags;
107  return *this;
108  }
109 
113  public: FlagSet& operator|=(const T& _val) noexcept
114  {
115  flags.set(static_cast<UnderlyingType>(_val));
116  return *this;
117  }
118 
122  public: FlagSet& operator|=(const FlagSet& _o) noexcept
123  {
124  flags |= _o.flags;
125  return *this;
126  }
127 
133  public: FlagSet operator&(const T& _val) const
134  {
135  FlagSet ret(*this);
136  ret &= _val;
137 
138  assert(ret.flags.count() <= 1);
139  return ret;
140  }
141 
145  public: FlagSet operator&(const FlagSet& _val) const
146  {
147  FlagSet ret(*this);
148  ret.flags &= _val.flags;
149 
150  return ret;
151  }
152 
157  public: FlagSet operator|(const T& _val) const
158  {
159  FlagSet ret(*this);
160  ret |= _val;
161 
162  assert(ret.flags.count() >= 1);
163  return ret;
164  }
165 
169  public: FlagSet operator|(const FlagSet& _val) const
170  {
171  FlagSet ret(*this);
172  ret.flags |= _val.flags;
173 
174  return ret;
175  }
176 
179  public: FlagSet operator~() const
180  {
181  FlagSet cp(*this);
182  cp.flags.flip();
183 
184  return cp;
185  }
186 
189  public: explicit operator bool() const
190  {
191  return flags.any();
192  }
193 
194  // Methods from std::bitset.
195 
199  public: bool operator==(const FlagSet& _o) const
200  {
201  return flags == _o.flags;
202  }
203 
207  public: bool operator!=(const FlagSet& _o) const
208  {
209  return !(*this == _o);
210  }
211 
216  public: std::size_t Size() const
217  {
218  return flags.size();
219  }
220 
224  public: std::size_t Count() const
225  {
226  return flags.count();
227  }
228 
231  public: FlagSet& Set()
232  {
233  flags.set();
234  return *this;
235  }
236 
239  public: FlagSet& Reset()
240  {
241  flags.reset();
242  return *this;
243  }
244 
247  public: FlagSet& Flip()
248  {
249  flags.flip();
250  return *this;
251  }
252 
257  public: FlagSet& Set(const T& _val, bool _value = true)
258  {
259  flags.set(static_cast<UnderlyingType>(_val), _value);
260  return *this;
261  }
262 
266  public: FlagSet& Reset(const T& _val)
267  {
268  flags.reset(static_cast<UnderlyingType>(_val));
269  return *this;
270  }
271 
275  public: FlagSet& Flip(const T& _val)
276  {
277  flags.flip(static_cast<UnderlyingType>(_val));
278  return *this;
279  }
280 
283  public: bool Any() const
284  {
285  return flags.any();
286  }
287 
290  public: bool All() const
291  {
292  return flags.all();
293  }
294 
297  public: bool None() const
298  {
299  return flags.none();
300  }
301 
303  public: static FlagSet AllSet()
304  {
305  return FlagSet().Set();
306  }
307 
309  public: static FlagSet NoneSet()
310  {
311  return FlagSet();
312  }
313 
318  public: constexpr bool operator[](const T& _val) const
319  {
320  return flags[static_cast<size_t>(static_cast<UnderlyingType>(_val))];
321  }
322 
325  public: std::string String() const
326  {
327  return flags.to_string();
328  }
329 
334  public: friend std::ostream& operator<<(std::ostream& _stream,
335  const FlagSet& _self)
336  {
337  return _stream << _self.flags;
338  }
339 
342  public: size_t Hash() const
343  {
344  return std::hash<decltype(this->flags)>{}(this->flags);
345  }
346 
348  private: using UnderlyingType = std::underlying_type_t<T>;
349 
351  public: static constexpr size_t numElements = static_cast<size_t>(
352  static_cast<UnderlyingType>(LastElement) +
353  static_cast<UnderlyingType>(1 - ExcludeLast));
354 
356  private: std::bitset<numElements> flags;
357 };
358 
359 template<typename T, typename = void>
361 {
362 };
363 
364 template<typename T>
365 struct IsEnumThatContainsSentinel<T, decltype(static_cast<void>(T::_))>
366  : std::is_enum<T>
367 {
368 };
369 
370 }
371 
372 // Operator that combines two enumeration values into a FlagSet only if the
373 // enumeration contains the sentinel `_`.
374 template<typename T>
375 std::enable_if_t<
378 >
379 operator|(const T& _lhs, const T& _rhs)
380 {
382  fs |= _lhs;
383  fs |= _rhs;
384 
385  return fs;
386 }
387 
388 namespace std
389 {
390 template<typename T, T LastElement, bool ExcludeLast>
391 struct hash<ignition::common::FlagSet<T, LastElement, ExcludeLast>>
392 {
395  const noexcept
396  {
397  return _s.Hash();
398  }
399 };
400 }
401 
402 #endif
size_t Hash() const
Compute hash of the FlagSet.
Definition: gz/common/FlagSet.hh:342
FlagSet & Flip()
Set all flags to their negation.
Definition: gz/common/FlagSet.hh:247
Forward declarations for the common classes.
STL class.
T any(T... args)
Set of flags defined by a C++11 enum class.
Definition: gz/common/FlagSet.hh:61
std::enable_if_t< ignition::common::IsEnumThatContainsSentinel< T >::value, ignition::common::FlagSet< T >> operator|(const T &_lhs, const T &_rhs)
Definition: gz/common/FlagSet.hh:379
bool Any() const
Test whether any flag is set.
Definition: gz/common/FlagSet.hh:283
bool operator!=(const FlagSet &_o) const
Test FlagSet inequality.
Definition: gz/common/FlagSet.hh:207
FlagSet operator&(const FlagSet &_val) const
Return a bit AND of this FlagSet and the argument.
Definition: gz/common/FlagSet.hh:145
T size(T... args)
static FlagSet AllSet()
Retrurn a FlagSet with all flags set to true.
Definition: gz/common/FlagSet.hh:303
FlagSet()=default
Create an empty FlagSet (no flags set).
FlagSet & Set(const T &_val, bool _value=true)
Set the given flag to the specified value.
Definition: gz/common/FlagSet.hh:257
FlagSet & Set()
Set all flags to true.
Definition: gz/common/FlagSet.hh:231
T reset(T... args)
friend std::ostream & operator<<(std::ostream &_stream, const FlagSet &_self)
Operator for outputting to std::ostream.
Definition: gz/common/FlagSet.hh:334
FlagSet & operator&=(const FlagSet &_o) noexcept
Return a bit AND of this FlagSet and the argument.
Definition: gz/common/FlagSet.hh:104
bool None() const
Test whether no flag is set.
Definition: gz/common/FlagSet.hh:297
static FlagSet NoneSet()
Retrurn a FlagSet with all flags set to false.
Definition: gz/common/FlagSet.hh:309
static constexpr size_t numElements
Number of elements of the bitset.
Definition: gz/common/FlagSet.hh:351
STL class.
bool operator==(const FlagSet &_o) const
Test FlagSet equality.
Definition: gz/common/FlagSet.hh:199
FlagSet(const T &_val)
Construct a FlagSet with the given flag set and all other unset.
Definition: gz/common/FlagSet.hh:72
T to_string(T... args)
FlagSet operator|(const FlagSet &_val) const
Return a bit OR of this FlagSet and the argument.
Definition: gz/common/FlagSet.hh:169
FlagSet operator~() const
Return a negation of this FlagSet.
Definition: gz/common/FlagSet.hh:179
constexpr bool operator[](const T &_val) const
Return whether the given flag is set.
Definition: gz/common/FlagSet.hh:318
FlagSet & operator|=(const FlagSet &_o) noexcept
Return a bit OR of this FlagSet and the argument.
Definition: gz/common/FlagSet.hh:122
FlagSet & operator|=(const T &_val) noexcept
Set the given flag to true in this FlagSet.
Definition: gz/common/FlagSet.hh:113
FlagSet(const std::initializer_list< T > &_list)
Construct a FlagSet with the given flags set and all other unset.
Definition: gz/common/FlagSet.hh:79
FlagSet & operator&=(const T &_val) noexcept
Return a FlagSet with only the given flag set (or even this one unset if it wasn't set in this FlagSe...
Definition: gz/common/FlagSet.hh:93
FlagSet & Reset()
Set all flags to false.
Definition: gz/common/FlagSet.hh:239
std::size_t Count() const
Return the number of flags set to true.
Definition: gz/common/FlagSet.hh:224
Definition: gz/common/Base64.hh:27
STL namespace.
FlagSet & Reset(const T &_val)
Set the given flag to false.
Definition: gz/common/FlagSet.hh:266
T count(T... args)
FlagSet & Flip(const T &_val)
Negate the given flag.
Definition: gz/common/FlagSet.hh:275
FlagSet operator|(const T &_val) const
Return a FlagSet with the given flag set to true.
Definition: gz/common/FlagSet.hh:157
T flip(T... args)
std::size_t operator()(const ignition::common::FlagSet< T, LastElement, ExcludeLast > &_s) const noexcept
Definition: gz/common/FlagSet.hh:393
std::string String() const
Return a string describing this FlagSet.
Definition: gz/common/FlagSet.hh:325
std::size_t Size() const
Return the total number of flags represented by this FlagSet.
Definition: gz/common/FlagSet.hh:216
Definition: gz/common/FlagSet.hh:360
T test(T... args)
T set(T... args)
bool All() const
Test whether all flags are set.
Definition: gz/common/FlagSet.hh:290
FlagSet operator&(const T &_val) const
Return a FlagSet with only the given flag set (or even this one unset if it wasn't set in this FlagSe...
Definition: gz/common/FlagSet.hh:133