source: rrlib_util/tEnumBasedFlags.h @ 160:aaeedeabee77

14.08
Last change on this file since 160:aaeedeabee77 was 160:aaeedeabee77, checked in by Tobias Föhst <tobias.foehst@…>, 2 years ago

Adds operator < to tEnumBasedFlags

File size: 6.2 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/util/tEnumBasedFlags.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2013-10-18
27 *
28 * \brief   Contains tEnumBasedFlags
29 *
30 * \b tEnumBasedFlags
31 *
32 * Set of flags with possible flags defined by an enum.
33 * As enums do not support e.g. OR operations, this type is used to handle combining of flags.
34 *
35 */
36//----------------------------------------------------------------------
37#ifndef __rrlib__util__tEnumBasedFlags_h__
38#define __rrlib__util__tEnumBasedFlags_h__
39
40//----------------------------------------------------------------------
41// External includes (system with <>, local with "")
42//----------------------------------------------------------------------
43
44//----------------------------------------------------------------------
45// Internal includes with ""
46//----------------------------------------------------------------------
47
48//----------------------------------------------------------------------
49// Namespace declaration
50//----------------------------------------------------------------------
51namespace rrlib
52{
53namespace util
54{
55
56//----------------------------------------------------------------------
57// Forward declarations / typedefs / enums
58//----------------------------------------------------------------------
59
60//----------------------------------------------------------------------
61// Class declaration
62//----------------------------------------------------------------------
63//! Set of flags
64/*!
65 * Set of flags with possible flags defined by an enum.
66 * As enums do not support e.g. OR operations, this type is used to handle combining of flags.
67 *
68 * \tparam TFlag Enum type that defines possible flags
69 * \tparam TStorage Integer class that stores flags internally (must have at least as many bits as there are enum constants)
70 *
71 * Usage:
72 *
73 * 1) define enum with possible flags
74 *
75 *    enum class tExampleFlag
76 *    {
77 *      FLAG1,
78 *      FLAG2,
79 *      ...
80 *    }
81 *
82 * 2) create a typedef to the tEnumBasedFlags class
83 *
84 *    typedef tEnumBasedFlags<tExampleFlag> tExampleFlags
85 *
86 * 3) define operator(s)
87 *
88 *    constexpr tExampleFlags operator | (const tExampleFlags& flags1, const tExampleFlags& flags2)
89 *    {
90 *      return tExampleFlags(flags1.Raw() | flags2.Raw());
91 *    }
92 */
93template <typename TFlag, typename TStorage = uint>
94class tEnumBasedFlags
95{
96
97//----------------------------------------------------------------------
98// Public methods and typedefs
99//----------------------------------------------------------------------
100public:
101
102  constexpr tEnumBasedFlags(TFlag flag) :
103    wrapped(1 << static_cast<TStorage>(flag))
104  {}
105
106  constexpr tEnumBasedFlags() :
107    wrapped(0)
108  {}
109
110  /*!
111   * It should only be necessary to call this for deserialization
112   * (explicit to not accept ints and bools etc. and e.g. offer operators for those)
113   */
114  explicit constexpr tEnumBasedFlags(TStorage flags) :
115    wrapped(flags)
116  {}
117
118  /*!
119   * \flag Flag to check
120   * \return Is specified flag currently set?
121   */
122  bool Get(TFlag flag) const
123  {
124    return this->wrapped & (1 << static_cast<TStorage>(flag));
125  }
126
127  /*!
128   * \return Flags as raw integer value
129   */
130  constexpr TStorage Raw() const
131  {
132    return this->wrapped;
133  }
134
135  /*!
136   * Set or remove specified flag
137   *
138   * \param flag Flag to set or remove
139   * \param value Set flag? (false will remove it)
140   */
141  inline tEnumBasedFlags &Set(TFlag flag, bool value = true)
142  {
143    if (value)
144    {
145      this->wrapped |= (1 << static_cast<TStorage>(flag));
146    }
147    else
148    {
149      this->wrapped &= (~(1 << static_cast<TStorage>(flag)));
150    }
151    return *this;
152  }
153
154  /*! Reset all flags
155   *
156   */
157  inline tEnumBasedFlags &Reset()
158  {
159    this->wrapped = TStorage();
160    return *this;
161  }
162
163  /*! Reset given flag to false
164   *
165   * \param flag   The Flag to reset
166   */
167  inline tEnumBasedFlags &Reset(TFlag flag)
168  {
169    return this->Set(flag, false);
170  }
171
172  tEnumBasedFlags& operator |= (const tEnumBasedFlags& other)
173  {
174    this->wrapped |= other.wrapped;
175    return *this;
176  }
177
178  /*! Checks if any flag is set
179   *
180   * \return True if at least one flag is set
181   */
182  inline bool Any() const
183  {
184    return this->wrapped;
185  }
186
187  /*! Checks if no flag is set to true
188   *
189   * \return True if no flag is set
190   */
191  inline bool None() const
192  {
193    return !this->Any();
194  }
195
196//----------------------------------------------------------------------
197// Private fields and methods
198//----------------------------------------------------------------------
199private:
200
201  /*! Wrapped integer containing flag set */
202  TStorage wrapped;
203};
204
205template <typename TFlag, typename TStorage = uint>
206inline bool operator==(const tEnumBasedFlags<TFlag, TStorage>& flags1, const tEnumBasedFlags<TFlag, TStorage>& flags2)
207{
208  return flags1.Raw() == flags2.Raw();
209}
210template <typename TFlag, typename TStorage = uint>
211inline bool operator!=(const tEnumBasedFlags<TFlag, TStorage>& flags1, const tEnumBasedFlags<TFlag, TStorage>& flags2)
212{
213  return flags1.Raw() != flags2.Raw();
214}
215template <typename TFlag, typename TStorage = uint>
216inline bool operator<(const tEnumBasedFlags<TFlag, TStorage>& flags1, const tEnumBasedFlags<TFlag, TStorage>& flags2)
217{
218  return flags1.Raw() < flags2.Raw();
219}
220
221//----------------------------------------------------------------------
222// End of namespace declaration
223//----------------------------------------------------------------------
224}
225}
226
227
228#endif
Note: See TracBrowser for help on using the repository browser.