PLCnext API Documentation 25.0.2.69
Enum.hxx
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
7
8#ifndef ARP_USE_ARP_SYSTEM_CORE
9
10#include "Arp/Base/Core/Enum.hxx"
11
12#else
13
14#include "Arp/System/Core/Arp.h"
15#include "Arp/System/Core/TypeName.hxx"
16#include "Arp/System/Core/Exception.hpp"
17#include <sstream>
18#include <type_traits>
19
20namespace Arp
21{
22
25
28template<class T = void>
29class Enum
30{
31public: // typedefs
33 using Value = T;
34 using U = typename std::underlying_type<T>::type;
35
36public: // construction
39 Enum(Value val = Zero);
40
41public: // static/const fields
42 static const T Zero = static_cast<T>(0);
43
44public: // static operations
49 static bool TryParse(const String& input, Enum& result);
50
55 static bool TryParse(const String& input, T& result);
56
61 static bool TryParse(const char* input, Enum& result);
62
67 static bool TryParse(const char* input, T& result);
68
73 static Enum Parse(const String& input);
74
79 static Enum Parse(const char* input);
80
81public: // getter
82 T GetValue(void)const;
83
84public: // operations
87 U ToUnderlyingType(void)const;
88
92 String ToString(bool throwIfInvalid = true)const;
93
94public: // assign operators
98 Enum& operator=(const Enum& rhs) = default;
99
103 Enum& operator=(Value rhs);
104
108 Enum& operator&=(Enum rhs);
109
113 Enum& operator|=(Enum rhs);
114
115public: // conversion operators
117 operator T(void)const;
118
119private: // fields
120 Value value;
121};
122
124// global function related to class Enum<T>
125// define global make_ function as usual for C++
130template<class T>
131Enum<T> make_enum(T value)
132{
133 return Enum<T>(value);
134}
135
137// inline methods of class Enum<T>
138template<class T>
139inline Enum<T>::Enum(Value val)
140 : value(val)
141{
142}
143
144template<class T>
145inline Enum<T>& Enum<T>::operator=(Value rhs)
146{
147 this->value = rhs;
148 return *this;
149}
150
151template<class T>
152inline Enum<T>::operator T()const
153{
154 return this->GetValue();
155}
156
157template<class T>
158inline Enum<T>& Enum<T>::operator&=(Enum rhs)
159{
160 this->value = static_cast<T>(static_cast<U>(this->value) & static_cast<U>(rhs.value));
161 return *this;
162}
163
164template<class T>
165inline Enum<T>& Enum<T>::operator|=(Enum rhs)
166{
167 this->value = static_cast<T>(static_cast<U>(this->value) | static_cast<U>(rhs.value));
168 return *this;
169}
170
171template<class T>
172inline T Enum<T>::GetValue()const
173{
174 return this->value;
175}
176
177template<class T>
178inline typename Enum<T>::U Enum<T>::ToUnderlyingType()const
179{
180 return static_cast<U>(this->value);
181}
182
183template<class T>
184inline String Enum<T>::ToString(bool throwIfInvalid)const
185{
186 std::ostringstream oss;
187 oss << this->value;
188 if (oss.fail() && throwIfInvalid)
189 {
190 throw Exception("Invalid value for Enum '{0}' occurs: {1}", TypeName<Enum>(), static_cast<U>(this->value));
191 }
192 return oss.str();
193}
194
195template<class T>
196inline bool Enum<T>::TryParse(const String& input, T& result)
197{
198 return Enum::TryParse(input.CStr(), result);
199}
200
201template<class T>
202inline bool Enum<T>::TryParse(const String& input, Enum& result)
203{
204 return Enum::TryParse(input.CStr(), result);
205}
206
207template<class T>
208inline bool Enum<T>::TryParse(const char* input, T& result)
209{
210 T value = Zero;
211 std::istringstream iss(input);
212 iss >> value;
213 if (iss.fail())
214 {
215 return false; // enum not found
216 }
217 // else
218 result = value;
219 return true;
220}
221
222template<class T>
223inline bool Enum<T>::TryParse(const char* input, Enum& result)
224{
225 T value = Zero;
226 if (!Enum::TryParse(input, value))
227 {
228 return false;
229 }
230 result = value;
231 return true;
232}
233
234template<class T>
235inline Enum<T> Enum<T>::Parse(const String& input)
236{
237 Enum<T> result;
238 if (!Enum::TryParse(input, result))
239 {
240 throw Exception("Invalid string for Enum '{0}' occurs: {1}", TypeName<Enum>(), input);
241 }
242 return result;
243}
244
245
246template<class T>
247inline Enum<T> Enum<T>::Parse(const char* input)
248{
249 Enum result;
250 if (!Enum::TryParse(input, result))
251 {
252 throw Exception("Invalid string for Enum '{0}' occurs: {1}", TypeName<Enum>(), input);
253 }
254 return result;
255}
256
258// global operators of class Enum<T>
259
261// stream operators of class Enum<T>
262
267template<class T>
268inline std::ostream& operator<<(std::ostream& os, Enum<T> value)
269{
270 return os << value.GetValue();
271}
272
277template<class T>
278inline std::istream& operator>>(std::istream& is, Enum<T>& value)
279{
280 T enumValue = Enum<T>::Zero;
281 is >> enumValue;
282 if (!is.fail())
283 {
284 value = enumValue;
285 }
286 return is;
287}
288
290// bit operators of class Enum<T>
291
296template<class T>
297inline Enum<T> operator|(Enum<T> lhs, Enum<T> rhs)
298{
299 Enum<T> result = lhs;
300 result |= rhs;
301 return result;
302}
303
308template<class T>
309inline Enum<T> operator&(Enum<T> lhs, Enum<T> rhs)
310{
311 Enum<T> result = lhs;
312 result &= rhs;
313 return result;
314}
315
317// compare operators of class Enum<T>
318
323template<class T>
324inline bool operator==(Enum<T> lhs, Enum<T> rhs)
325{
326 return lhs.GetValue() == rhs.GetValue();
327}
328
333template<class T>
334inline bool operator<(Enum<T> lhs, Enum<T> rhs)
335{
336 return lhs.GetValue() < rhs.GetValue();
337}
338
343template<class T>
344inline bool operator>(Enum<T> lhs, Enum<T> rhs)
345{
346 return lhs.GetValue() > rhs.GetValue();
347}
348
353template<class T>
354inline bool operator<=(Enum<T> lhs, Enum<T> rhs)
355{
356 return lhs.GetValue() <= rhs.GetValue();
357}
358
363template<class T>
364inline bool operator>=(Enum<T> lhs, Enum<T> rhs)
365{
366 return lhs.GetValue() >= rhs.GetValue();
367}
368
370// compare operators of class Enum<T> and T
371
376template<class T>
377inline bool operator==(Enum<T> lhs, T rhs)
378{
379 return lhs.GetValue() == rhs;
380}
381
386template<class T>
387inline bool operator<(Enum<T> lhs, T rhs)
388{
389 return lhs.GetValue() < rhs;
390}
391
396template<class T>
397inline bool operator>(Enum<T> lhs, T rhs)
398{
399 return lhs.GetValue() > rhs;
400}
401
406template<class T>
407inline bool operator<=(Enum<T> lhs, T rhs)
408{
409 return lhs.GetValue() <= rhs;
410}
411
416template<class T>
417inline bool operator>=(Enum<T> lhs, T rhs)
418{
419 return lhs.GetValue() >= rhs;
420}
421
423// compare operators of T and class Enum<T>
424
429template<class T>
430inline bool operator==(T lhs, Enum<T> rhs)
431{
432 return lhs == rhs.GetValue();
433}
434
439template<class T>
440inline bool operator<(T lhs, Enum<T> rhs)
441{
442 return lhs < rhs.GetValue();
443}
444
449template<class T>
450inline bool operator>(T lhs, Enum<T> rhs)
451{
452 return lhs > rhs.GetValue();
453}
454
459template<class T>
460inline bool operator<=(T lhs, Enum<T> rhs)
461{
462 return lhs <= rhs.GetValue();
463}
464
469template<class T>
470inline bool operator>=(T lhs, Enum<T> rhs)
471{
472 return lhs >= rhs.GetValue();
473}
474
476
477} // end of namespace Arp
478
479#endif // ndef ARP_USE_ARP_SYSTEM_CORE
static constexpr T Zero
Zero initialized Enum value.
Definition: Enum.hxx:30
T Value
The adapted enum class type.
Definition: Enum.hxx:23
typename std::underlying_type< T >::type U
The underlying integral type of the adapted enum class type.
Definition: Enum.hxx:24
Enum< T > make_enum(T value)
Global make function to adapt any enum class by class Enum.
Definition: Enum.ipp:222
Enum & operator=(Value arg)
The assignment operator for a value of the adapted type.
Definition: Enum.ipp:126
T GetValue(void) const
Gets the adapted enum value.
Definition: Enum.ipp:155
Enum & operator&=(Enum rhs)
The assignment AND operator.
Definition: Enum.ipp:136
Enum & operator|=(Enum rhs)
The assignment OR operator.
Definition: Enum.ipp:146
static bool TryParse(const String &input, Enum &result)
Tries to parse the given input string.
Definition: Enum.ipp:45
String ToString(bool throwIfInvalid=true) const
Converts this instance to its string representation.
Definition: Enum.ipp:199
U ToUnderlyingType(void) const
Converts this instance to the underlying integral type of its adapted enum type
Definition: Enum.ipp:190
Enum(Value initialValue=Zero)
Constructs an instance of Enum with the given value.
Definition: Enum.ipp:25
static Enum Parse(const String &input)
Parses the given input string.
Definition: Enum.ipp:90
Root namespace for the PLCnext API