PLCnext API Documentation  22.9.0.33
Enum.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Core/TypeName.hxx"
9 #include "Arp/System/Core/Exception.hpp"
10 #include <iosfwd>
11 #include <type_traits>
12 
13 namespace Arp
14 {
15 
18 
21 template<class T = void>
22 class Enum
23 {
24 public: // typedefs
26  using Value = T;
27  using U = typename std::underlying_type<T>::type;
28 
29 public: // construction
32  Enum(Value val = Zero);
33 
34 public: // static/const fields
35  static const T Zero = static_cast<T>(0);
36 
37 public: // static operations
42  static bool TryParse(const String& input, Enum& result);
43 
48  static bool TryParse(const String& input, T& result);
49 
54  static bool TryParse(const char* input, Enum& result);
55 
60  static bool TryParse(const char* input, T& result);
61 
66  static Enum Parse(const String& input);
67 
72  static Enum Parse(const char* input);
73 
74 public: // getter
75  T GetValue(void)const;
76 
77 public: // operations
80  U ToUnderlyingType(void)const;
81 
85  String ToString(bool throwIfInvalid = true)const;
86 
87 public: // assign operators
91  Enum& operator=(const Enum& rhs) = default;
92 
96  Enum& operator=(Value rhs);
97 
101  Enum& operator&=(Enum rhs);
102 
106  Enum& operator|=(Enum rhs);
107 
108 public: // conversion operators
110  operator T(void)const;
111 
112 private: // fields
113  Value value;
114 };
115 
117 // global function related to class Enum<T>
118 // define global make_ function as usual for C++
123 template<class T>
125 {
126  return Enum<T>(value);
127 }
128 
130 // inline methods of class Enum<T>
131 template<class T>
132 inline Enum<T>::Enum(Value val)
133  : value(val)
134 {
135 }
136 
137 template<class T>
139 {
140  this->value = rhs;
141  return *this;
142 }
143 
144 template<class T>
145 inline Enum<T>::operator T()const
146 {
147  return this->GetValue();
148 }
149 
150 template<class T>
152 {
153  this->value = static_cast<T>(static_cast<U>(this->value) & static_cast<U>(rhs.value));
154  return *this;
155 }
156 
157 template<class T>
159 {
160  this->value = static_cast<T>(static_cast<U>(this->value) | static_cast<U>(rhs.value));
161  return *this;
162 }
163 
164 template<class T>
165 inline T Enum<T>::GetValue()const
166 {
167  return this->value;
168 }
169 
170 template<class T>
171 inline typename Enum<T>::U Enum<T>::ToUnderlyingType()const
172 {
173  return static_cast<U>(this->value);
174 }
175 
176 template<class T>
177 inline String Enum<T>::ToString(bool throwIfInvalid)const
178 {
179  std::ostringstream oss;
180  oss << this->value;
181  if (oss.fail() && throwIfInvalid)
182  {
183  throw Exception("Invalid value for Enum '{0}' occurs: {1}", TypeName<Enum>().Value, static_cast<U>(this->value));
184  }
185  return oss.str();
186 }
187 
188 template<class T>
189 inline bool Enum<T>::TryParse(const String& input, T& result)
190 {
191  return Enum::TryParse(input.CStr(), result);
192 }
193 
194 template<class T>
195 inline bool Enum<T>::TryParse(const String& input, Enum& result)
196 {
197  return Enum::TryParse(input.CStr(), result);
198 }
199 
200 template<class T>
201 inline bool Enum<T>::TryParse(const char* input, T& result)
202 {
203  T value = Zero;
204  std::istringstream iss(input);
205  iss >> value;
206  if (iss.fail())
207  {
208  return false; // enum not found
209  }
210  // else
211  result = value;
212  return true;
213 }
214 
215 template<class T>
216 inline bool Enum<T>::TryParse(const char* input, Enum& result)
217 {
218  T value = Zero;
219  if (!Enum::TryParse(input, value))
220  {
221  return false;
222  }
223  result = value;
224  return true;
225 }
226 
227 template<class T>
228 inline Enum<T> Enum<T>::Parse(const String& input)
229 {
230  Enum<T> result;
231  if (!Enum::TryParse(input, result))
232  {
233  throw Exception("Invalid string for Enum '{0}' occurs: {1}", TypeName<Enum>().Value, input);
234  }
235  return result;
236 }
237 
238 
239 template<class T>
240 inline Enum<T> Enum<T>::Parse(const char* input)
241 {
242  Enum result;
243  if (!Enum::TryParse(input, result))
244  {
245  throw Exception("Invalid string for Enum '{0}' occurs: {1}", TypeName<Enum>().Value, input);
246  }
247  return result;
248 }
249 
251 // global operators of class Enum<T>
252 
254 // stream operators of class Enum<T>
255 
260 template<class T>
261 inline std::ostream& operator<<(std::ostream& os, Enum<T> value)
262 {
263  return os << value.GetValue();
264 }
265 
270 template<class T>
271 inline std::istream& operator>>(std::istream& is, Enum<T>& value)
272 {
273  T enumValue = Enum<T>::Zero;
274  is >> enumValue;
275  if (!is.fail())
276  {
277  value = enumValue;
278  }
279  return is;
280 }
281 
283 // bit operators of class Enum<T>
284 
289 template<class T>
291 {
292  Enum<T> result = lhs;
293  result |= rhs;
294  return result;
295 }
296 
301 template<class T>
303 {
304  Enum<T> result = lhs;
305  result &= rhs;
306  return result;
307 }
308 
310 // compare operators of class Enum<T>
311 
316 template<class T>
317 inline bool operator==(Enum<T> lhs, Enum<T> rhs)
318 {
319  return lhs.GetValue() == rhs.GetValue();
320 }
321 
326 template<class T>
327 inline bool operator<(Enum<T> lhs, Enum<T> rhs)
328 {
329  return lhs.GetValue() < rhs.GetValue();
330 }
331 
336 template<class T>
337 inline bool operator>(Enum<T> lhs, Enum<T> rhs)
338 {
339  return lhs.GetValue() > rhs.GetValue();
340 }
341 
346 template<class T>
347 inline bool operator<=(Enum<T> lhs, Enum<T> rhs)
348 {
349  return lhs.GetValue() <= rhs.GetValue();
350 }
351 
356 template<class T>
357 inline bool operator>=(Enum<T> lhs, Enum<T> rhs)
358 {
359  return lhs.GetValue() >= rhs.GetValue();
360 }
361 
363 // compare operators of class Enum<T> and T
364 
369 template<class T>
370 inline bool operator==(Enum<T> lhs, T rhs)
371 {
372  return lhs.GetValue() == rhs;
373 }
374 
379 template<class T>
380 inline bool operator<(Enum<T> lhs, T rhs)
381 {
382  return lhs.GetValue() < rhs;
383 }
384 
389 template<class T>
390 inline bool operator>(Enum<T> lhs, T rhs)
391 {
392  return lhs.GetValue() > rhs;
393 }
394 
399 template<class T>
400 inline bool operator<=(Enum<T> lhs, T rhs)
401 {
402  return lhs.GetValue() <= rhs;
403 }
404 
409 template<class T>
410 inline bool operator>=(Enum<T> lhs, T rhs)
411 {
412  return lhs.GetValue() >= rhs;
413 }
414 
416 // compare operators of T and class Enum<T>
417 
422 template<class T>
423 inline bool operator==(T lhs, Enum<T> rhs)
424 {
425  return lhs == rhs.GetValue();
426 }
427 
432 template<class T>
433 inline bool operator<(T lhs, Enum<T> rhs)
434 {
435  return lhs < rhs.GetValue();
436 }
437 
442 template<class T>
443 inline bool operator>(T lhs, Enum<T> rhs)
444 {
445  return lhs > rhs.GetValue();
446 }
447 
452 template<class T>
453 inline bool operator<=(T lhs, Enum<T> rhs)
454 {
455  return lhs <= rhs.GetValue();
456 }
457 
462 template<class T>
463 inline bool operator>=(T lhs, Enum<T> rhs)
464 {
465  return lhs >= rhs.GetValue();
466 }
467 
469 
470 } // end of namespace Arp
Adapter class for enums to make them loggable and parsable from e.g. XML files.
Definition: Enum.hxx:23
Enum & operator=(const Enum &rhs)=default
The default assignment operator.
T Value
The adapted enum class type.
Definition: Enum.hxx:26
This is the base class of all Arp exception classes.
Definition: Exception.hpp:16
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:56
U ToUnderlyingType(void) const
Converts this instance to the underlying type of its adapted enum type
Definition: Enum.hxx:171
Enum< T > operator|(Enum< T > lhs, Enum< T > rhs)
Bitwise Or operator for class Enum.
Definition: Enum.hxx:290
String ToString(bool throwIfInvalid=true) const
Converts this instance to its string representation.
Definition: Enum.hxx:177
static bool TryParse(const String &input, Enum &result)
Tries to parse the given input string.
Definition: Enum.hxx:195
Enum< T > make_enum(T value)
Global make function to adapt any enum class by class Enum.
Definition: Enum.hxx:124
Enum & operator|=(Enum rhs)
The assignment OR operator.
Definition: Enum.hxx:158
static Enum Parse(const String &input)
Parses the given input string.
Definition: Enum.hxx:228
Enum< T > operator&(Enum< T > lhs, Enum< T > rhs)
Bitwise And operator for class Enum.
Definition: Enum.hxx:302
Enum & operator&=(Enum rhs)
The assignment AND operator.
Definition: Enum.hxx:151
Enum(Value val=Zero)
Constructs an instace of Enum with the given value.
Definition: Enum.hxx:132
std::ostream & operator<<(std::ostream &os, const BasicString< CharType, Alloc > &right)
Streams the right string to the outstream os .
Definition: BasicString.hxx:1708
const CharType * CStr() const
Gets the character data of this string.
Definition: BasicString.hxx:1508
bool operator<=(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string.
Definition: BasicString.hxx:2020
bool operator>(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string.
Definition: BasicString.hxx:1984
bool operator<(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string.
Definition: BasicString.hxx:1948
bool operator>=(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string.
Definition: BasicString.hxx:2056
std::istream & operator>>(std::istream &is, BasicString< CharType, Alloc > &right)
Streams the instream is into the right string.
Definition: BasicString.hxx:1719
bool operator==(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string on equality.
Definition: BasicString.hxx:1876
Root namespace for the PLCnext API