PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bitwise_enum.h
Go to the documentation of this file.
1 /*
2  * bitwise_enum.h
3  *
4  * Template class to allow operators on an enum representing bits.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 2009 Vox Lucida
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Contributor(s): ______________________________________.
25  */
26 
27 #ifndef PTLIB_BITWISE_ENUM_H
28 #define PTLIB_BITWISE_ENUM_H
29 
30 #ifdef P_USE_PRAGMA
31 #pragma interface
32 #endif
33 
38 template <typename BaseEnum, BaseEnum MaxValue, typename BaseInt = unsigned>
40 {
41  public:
42  typedef BaseEnum Enumeration;
43  typedef BaseInt IntType;
44 
45  protected:
47 
48  public:
49  static __inline Enumeration Zero() { return (Enumeration)0; }
50  static __inline Enumeration All() { return (Enumeration)((MaxValue<<1)-1); }
51  static __inline Enumeration Begin() { return (Enumeration)1; }
52  static __inline Enumeration End() { return MaxValue; }
53 
54  __inline PBitwiseEnum(Enumeration e = Zero()) : m_enum(e) { }
55  __inline PBitwiseEnum(const PBitwiseEnum & e) : m_enum(e.m_enum) { }
56 
57  __inline PBitwiseEnum & operator=(const PBitwiseEnum & e) { m_enum = e.m_enum; return *this; }
58  __inline PBitwiseEnum & operator=(Enumeration e) { m_enum = e; return *this; }
59 
60  __inline operator Enumeration() const { return m_enum; }
61  __inline operator Enumeration&() { return m_enum; }
62  __inline operator const Enumeration&() const { return m_enum; }
63  __inline Enumeration * operator&() { return &m_enum; }
64  __inline unsigned AsBits() const { return m_enum; }
65  __inline static Enumeration FromBits(unsigned b) { return (Enumeration)( b &All()); }
66  __inline static Enumeration FromBit (unsigned b) { return (Enumeration)((1<<b)&All()); }
67 
69  {
70  Enumeration previous = m_enum;
71  if (m_enum < MaxValue)
72  m_enum = static_cast<Enumeration>(m_enum << 1);
73  return previous;
74  }
75 
77  {
78  if (m_enum < MaxValue)
79  m_enum = static_cast<Enumeration>(static_cast<IntType>(m_enum) << 1);
80  return *this;
81  }
82 
84  {
85  Enumeration previous = m_enum;
86  m_enum = static_cast<Enumeration>(static_cast<IntType>(m_enum) >> 1);
87  return previous;
88  }
89 
91  {
92  m_enum = static_cast<Enumeration>(static_cast<IntType>(m_enum) >> 1);
93  return *this;
94  }
95 
96 
97 #define P_BITWISE_ENUM_INTERNAL_OP1(op) (static_cast<IntType>(m_enum) op static_cast<IntType>(rhs))
98 #define P_BITWISE_ENUM_INTERNAL_OP2(op) static_cast<Enumeration>(P_BITWISE_ENUM_INTERNAL_OP1(op))
99 
100  __inline PBitwiseEnum & operator|=(Enumeration rhs) { m_enum = P_BITWISE_ENUM_INTERNAL_OP2( | ); return *this; }
101  __inline PBitwiseEnum & operator+=(Enumeration rhs) { m_enum = P_BITWISE_ENUM_INTERNAL_OP2( | ); return *this; }
102  __inline PBitwiseEnum & operator-=(Enumeration rhs) { m_enum = P_BITWISE_ENUM_INTERNAL_OP2(& ~); return *this; }
103  __inline PBitwiseEnum & operator*=(Enumeration rhs) { m_enum = P_BITWISE_ENUM_INTERNAL_OP2( & ); return *this; }
104  __inline PBitwiseEnum & operator^=(Enumeration rhs) { m_enum = P_BITWISE_ENUM_INTERNAL_OP2( ^ ); return *this; }
105 
106  __inline PBitwiseEnum operator+ (Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP2( | ); }
107  __inline PBitwiseEnum operator| (Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP2( | ); }
108  __inline PBitwiseEnum operator- (Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP2(& ~); }
109  __inline PBitwiseEnum operator* (Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP2( & ); }
110  __inline PBitwiseEnum operator^ (Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP2( ^ ); }
111 
112  __inline bool operator& (Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP1(&) != 0; }
113  __inline bool operator==(Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP1(==); }
114  __inline bool operator<=(Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP1(<=); }
115  __inline bool operator>=(Enumeration rhs) const { return P_BITWISE_ENUM_INTERNAL_OP1(>=); }
116 
117  __inline bool operator!=(Enumeration rhs) const { return !operator==(rhs); }
118  __inline bool operator< (Enumeration rhs) const { return !operator>=(rhs); }
119  __inline bool operator> (Enumeration rhs) const { return !operator<=(rhs); }
120 
121  __inline PBitwiseEnum & operator|=(PBitwiseEnum rhs) { return operator|=(rhs.m_enum); }
122  __inline PBitwiseEnum & operator+=(PBitwiseEnum rhs) { return operator+=(rhs.m_enum); }
123  __inline PBitwiseEnum & operator-=(PBitwiseEnum rhs) { return operator-=(rhs.m_enum); }
124  __inline PBitwiseEnum & operator*=(PBitwiseEnum rhs) { return operator*=(rhs.m_enum); }
125  __inline PBitwiseEnum & operator^=(PBitwiseEnum rhs) { return operator^=(rhs.m_enum); }
126 
127  __inline PBitwiseEnum operator| (PBitwiseEnum rhs) const { return operator|(rhs.m_enum); }
128  __inline PBitwiseEnum operator+ (PBitwiseEnum rhs) const { return operator+(rhs.m_enum); }
129  __inline PBitwiseEnum operator- (PBitwiseEnum rhs) const { return operator-(rhs.m_enum); }
130  __inline PBitwiseEnum operator* (PBitwiseEnum rhs) const { return operator*(rhs.m_enum); }
131  __inline PBitwiseEnum operator^ (PBitwiseEnum rhs) const { return operator^(rhs.m_enum); }
132 
133  __inline bool operator& (PBitwiseEnum rhs) const { return operator& (rhs.m_enum); }
134  __inline bool operator==(PBitwiseEnum rhs) const { return operator==(rhs.m_enum); }
135  __inline bool operator<=(PBitwiseEnum rhs) const { return operator<=(rhs.m_enum); }
136  __inline bool operator>=(PBitwiseEnum rhs) const { return operator>=(rhs.m_enum); }
137 
138  __inline bool operator!=(PBitwiseEnum rhs) const { return !operator==(rhs); }
139  __inline bool operator< (PBitwiseEnum rhs) const { return !operator>=(rhs); }
140  __inline bool operator> (PBitwiseEnum rhs) const { return !operator<=(rhs); }
141 
142  __inline PBitwiseEnum operator~ () const { return FromBits(~m_enum); }
143 };
144 
145 
146 #define P_DECLARE_BITWISE_ENUM_1(_0,_1)_0=0,_1=1
147 #define P_DECLARE_BITWISE_ENUM_2(_0,_1,_2)P_DECLARE_BITWISE_ENUM_1(_0,_1),_2=2
148 #define P_DECLARE_BITWISE_ENUM_3(_0,_1,_2,_3)P_DECLARE_BITWISE_ENUM_2(_0,_1,_2),_3=4
149 #define P_DECLARE_BITWISE_ENUM_4(_0,_1,_2,_3,_4)P_DECLARE_BITWISE_ENUM_3(_0,_1,_2,_3),_4=8
150 #define P_DECLARE_BITWISE_ENUM_5(_0,_1,_2,_3,_4,_5)P_DECLARE_BITWISE_ENUM_4(_0,_1,_2,_3,_4),_5=16
151 #define P_DECLARE_BITWISE_ENUM_6(_0,_1,_2,_3,_4,_5,_6)P_DECLARE_BITWISE_ENUM_5(_0,_1,_2,_3,_4,_5),_6=32
152 #define P_DECLARE_BITWISE_ENUM_7(_0,_1,_2,_3,_4,_5,_6,_7)P_DECLARE_BITWISE_ENUM_6(_0,_1,_2,_3,_4,_5,_6),_7=64
153 #define P_DECLARE_BITWISE_ENUM_8(_0,_1,_2,_3,_4,_5,_6,_7,_8)P_DECLARE_BITWISE_ENUM_7(_0,_1,_2,_3,_4,_5,_6,_7),_8=128
154 #define P_DECLARE_BITWISE_ENUM_9(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9)P_DECLARE_BITWISE_ENUM_8(_0,_1,_2,_3,_4,_5,_6,_7,_8),_9=256
155 #define P_DECLARE_BITWISE_ENUM_10(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10)P_DECLARE_BITWISE_ENUM_9(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9),_10=512
156 #define P_DECLARE_BITWISE_ENUM_11(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11)P_DECLARE_BITWISE_ENUM_10(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10),_11=1024
157 #define P_DECLARE_BITWISE_ENUM_12(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12)P_DECLARE_BITWISE_ENUM_11(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11),_11=2048
158 
159 #define P_DECLARE_BITWISE_NAMES_1(_0,_1)#_0,#_1
160 #define P_DECLARE_BITWISE_NAMES_2(_0,_1,_2)P_DECLARE_BITWISE_NAMES_1(_0,_1),#_2
161 #define P_DECLARE_BITWISE_NAMES_3(_0,_1,_2,_3)P_DECLARE_BITWISE_NAMES_2(_0,_1,_2),#_3
162 #define P_DECLARE_BITWISE_NAMES_4(_0,_1,_2,_3,_4)P_DECLARE_BITWISE_NAMES_3(_0,_1,_2,_3),#_4
163 #define P_DECLARE_BITWISE_NAMES_5(_0,_1,_2,_3,_4,_5)P_DECLARE_BITWISE_NAMES_4(_0,_1,_2,_3,_4),#_5
164 #define P_DECLARE_BITWISE_NAMES_6(_0,_1,_2,_3,_4,_5,_6)P_DECLARE_BITWISE_NAMES_5(_0,_1,_2,_3,_4,_5),#_6
165 #define P_DECLARE_BITWISE_NAMES_7(_0,_1,_2,_3,_4,_5,_6,_7)P_DECLARE_BITWISE_NAMES_6(_0,_1,_2,_3,_4,_5,_6),#_7
166 #define P_DECLARE_BITWISE_NAMES_8(_0,_1,_2,_3,_4,_5,_6,_7,_8)P_DECLARE_BITWISE_NAMES_7(_0,_1,_2,_3,_4,_5,_6,_7),#_8
167 #define P_DECLARE_BITWISE_NAMES_9(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9)P_DECLARE_BITWISE_NAMES_8(_0,_1,_2,_3,_4,_5,_6,_7,_8),#_9
168 #define P_DECLARE_BITWISE_NAMES_10(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10)P_DECLARE_BITWISE_NAMES_9(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9),#_10
169 #define P_DECLARE_BITWISE_NAMES_11(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11)P_DECLARE_BITWISE_NAMES_10(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10),#_11
170 #define P_DECLARE_BITWISE_NAMES_12(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12)P_DECLARE_BITWISE_NAMES_11(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11),#_12
171 
172 #define P_DECLARE_BITWISE_ENUM_FRIENDS(name) \
173  __inline friend name##_Bits operator+(name##_Bits lhs, name##_Bits rhs) \
174  { return static_cast<name##_Bits>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); } \
175  __inline friend name##_Bits operator|(name##_Bits lhs, name##_Bits rhs) \
176  { return static_cast<name##_Bits>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); } \
177  __inline friend name##_Bits operator-(name##_Bits lhs, name##_Bits rhs) \
178  { return static_cast<name##_Bits>(static_cast<unsigned>(lhs) & ~static_cast<unsigned>(rhs)); }
179 
180 #define P_DECLARE_BITWISE_ENUM_END(name, count) \
181  P_DECLARE_BITWISE_ENUM_FRIENDS(name) \
182  typedef PBitwiseEnum<name##_Bits, (name##_Bits)(1<<(count-1))> name
183 
184 
195 #define P_DECLARE_BITWISE_ENUM(name, count, values) \
196  enum name##_Bits { P_DECLARE_BITWISE_ENUM_##count values }; \
197  P_DECLARE_BITWISE_ENUM_END(name, count)
198 
210 #define P_DECLARE_BITWISE_ENUM_EX(name, count, values, ...) \
211  enum name##_Bits { P_DECLARE_BITWISE_ENUM_##count values , ##__VA_ARGS__ }; \
212  P_DECLARE_BITWISE_ENUM_END(name, count)
213 
214 
215 #endif // PTLIB_BITWISE_ENUM_H
216 
217 #if defined(PTLIB_STRING_H) && !defined(PTLIB_BITWISE_STREAMABLE_ENUM_H)
218 #define PTLIB_BITWISE_STREAMABLE_ENUM_H 1
219 
220 extern void PPrintBitwiseEnum(std::ostream & strm, unsigned bits, char const * const * names);
221 extern unsigned PReadBitwiseEnum(std::istream & strm, char const * const * names, bool continueOnError = false);
222 
223 
224 template <typename BaseEnum, BaseEnum MaxValue, typename BaseInt = unsigned>
225 class PStreamableBitwiseEnum : public PBitwiseEnum<BaseEnum, MaxValue, BaseInt>
226 {
227  public:
229 
230  __inline PStreamableBitwiseEnum(typename BaseClass::Enumeration e = BaseClass::Zero()) : BaseClass(e) { }
231  __inline virtual ~PStreamableBitwiseEnum() { }
232 
233  friend __inline std::ostream & operator<<(std::ostream & strm, const PStreamableBitwiseEnum & e)
234  {
235  PPrintBitwiseEnum(strm, e.AsBits(), e.Names());
236  return strm;
237  }
238 
239  friend __inline std::istream & operator>>(std::istream & strm, PStreamableBitwiseEnum & e)
240  {
241  e.m_enum = BaseClass::FromBits(PReadBitwiseEnum(strm, e.Names(), false));
242  return strm;
243  }
244 
245  PString ToString()
246  {
247  PStringStream strm;
248  strm >> *this;
249  return strm;
250  }
251 
252  bool FromString(const PString & s, bool clear = true)
253  {
254  if (clear)
255  this->m_enum = BaseClass::Zero();
256 
257  PStringStream strm(s);
258  this->m_enum = BaseClass::FromBits(this->m_enum | PReadBitwiseEnum(strm, Names(), true));
259  return strm.good();
260  }
261 
262  virtual char const * const * Names() const = 0;
263 };
264 
265 #define P_DECLARE_STREAMABLE_BITWISE_ENUM_EX(name, count, values, ...) \
266  enum name##_Bits { P_DECLARE_BITWISE_ENUM_##count values }; \
267  P_DECLARE_BITWISE_ENUM_FRIENDS(name) \
268  class name : public PStreamableBitwiseEnum<name##_Bits, (name##_Bits)(1<<count)>{ \
269  public: typedef PStreamableBitwiseEnum<name##_Bits, (name##_Bits)(1<<count)> BaseClass; \
270  __inline name(BaseClass::Enumeration e = BaseClass::Zero()) : BaseClass(e) { } \
271  __inline explicit name(const PString & s) { FromString(s); } \
272  virtual char const * const * Names() const { static char const * const Strings[] = { __VA_ARGS__, NULL }; return Strings; } \
273  }
274 
275 #define P_DECLARE_STREAMABLE_BITWISE_ENUM(name, count, values) \
276  P_DECLARE_STREAMABLE_BITWISE_ENUM_EX(name, count, values, P_DECLARE_BITWISE_NAMES_##count values)
277 
278 
279 #endif // defined(PTLIB_STRING_H) && !defined(PTLIB_BITWISE_STREAMABLE_ENUM_H)
280 
281 
282 // End Of File ///////////////////////////////////////////////////////////////
__inline std::ostream & operator<<(std::ostream &strm, const PHashTableList &hash)
Definition: dict.h:180
__inline PBitwiseEnum operator-(Enumeration rhs) const
Definition: bitwise_enum.h:108
static __inline Enumeration FromBits(unsigned b)
Definition: bitwise_enum.h:65
__inline PBitwiseEnum operator|(Enumeration rhs) const
Definition: bitwise_enum.h:107
__inline bool operator<=(Enumeration rhs) const
Definition: bitwise_enum.h:114
__inline PBitwiseEnum operator*(Enumeration rhs) const
Definition: bitwise_enum.h:109
static __inline Enumeration Zero()
Definition: bitwise_enum.h:49
__inline PBitwiseEnum & operator*=(PBitwiseEnum rhs)
Definition: bitwise_enum.h:124
BaseEnum Enumeration
Definition: bitwise_enum.h:42
__inline PBitwiseEnum operator^(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:131
__inline bool operator==(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:134
__inline bool operator==(Enumeration rhs) const
Definition: bitwise_enum.h:113
__inline bool operator<=(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:135
This class is a standard C++ stream class descendent for reading or writing streamed data to or from ...
Definition: pstring.h:2188
__inline bool operator>=(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:136
PBitwiseEnum operator--()
Definition: bitwise_enum.h:83
__inline PBitwiseEnum operator-(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:129
__inline bool operator!=(Enumeration rhs) const
Definition: bitwise_enum.h:117
__inline PBitwiseEnum & operator-=(PBitwiseEnum rhs)
Definition: bitwise_enum.h:123
__inline bool operator<(Enumeration rhs) const
Definition: bitwise_enum.h:118
__inline PBitwiseEnum & operator|=(PBitwiseEnum rhs)
Definition: bitwise_enum.h:121
__inline Enumeration * operator&()
Definition: bitwise_enum.h:63
#define P_BITWISE_ENUM_INTERNAL_OP1(op)
Definition: bitwise_enum.h:97
__inline PBitwiseEnum & operator|=(Enumeration rhs)
Definition: bitwise_enum.h:100
__inline PBitwiseEnum & operator^=(PBitwiseEnum rhs)
Definition: bitwise_enum.h:125
PBitwiseEnum operator++(int)
Definition: bitwise_enum.h:76
__inline PBitwiseEnum operator|(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:127
__inline PBitwiseEnum & operator+=(Enumeration rhs)
Definition: bitwise_enum.h:101
__inline PBitwiseEnum & operator-=(Enumeration rhs)
Definition: bitwise_enum.h:102
static __inline Enumeration All()
Definition: bitwise_enum.h:50
__inline unsigned AsBits() const
Definition: bitwise_enum.h:64
static __inline Enumeration FromBit(unsigned b)
Definition: bitwise_enum.h:66
__inline PBitwiseEnum & operator=(Enumeration e)
Definition: bitwise_enum.h:58
__inline bool operator>=(Enumeration rhs) const
Definition: bitwise_enum.h:115
This class defines a set of operators for a bit wise enumeration.
Definition: bitwise_enum.h:39
The character string class.
Definition: pstring.h:108
__inline PBitwiseEnum operator~() const
Definition: bitwise_enum.h:142
__inline PBitwiseEnum operator*(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:130
__inline bool operator!=(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:138
__inline PBitwiseEnum & operator*=(Enumeration rhs)
Definition: bitwise_enum.h:103
__inline PBitwiseEnum operator+(PBitwiseEnum rhs) const
Definition: bitwise_enum.h:128
__inline PBitwiseEnum operator^(Enumeration rhs) const
Definition: bitwise_enum.h:110
static __inline Enumeration Begin()
Definition: bitwise_enum.h:51
#define P_BITWISE_ENUM_INTERNAL_OP2(op)
Definition: bitwise_enum.h:98
__inline bool operator>(Enumeration rhs) const
Definition: bitwise_enum.h:119
__inline PBitwiseEnum(Enumeration e=Zero())
Definition: bitwise_enum.h:54
PBitwiseEnum operator++()
Definition: bitwise_enum.h:68
__inline PBitwiseEnum & operator^=(Enumeration rhs)
Definition: bitwise_enum.h:104
Enumeration m_enum
Definition: bitwise_enum.h:46
__inline PBitwiseEnum & operator=(const PBitwiseEnum &e)
Definition: bitwise_enum.h:57
PBitwiseEnum operator--(int)
Definition: bitwise_enum.h:90
__inline PBitwiseEnum operator+(Enumeration rhs) const
Definition: bitwise_enum.h:106
static __inline Enumeration End()
Definition: bitwise_enum.h:52
__inline PBitwiseEnum(const PBitwiseEnum &e)
Definition: bitwise_enum.h:55
BaseInt IntType
Definition: bitwise_enum.h:43
__inline PBitwiseEnum & operator+=(PBitwiseEnum rhs)
Definition: bitwise_enum.h:122