8#include "Arp/System/Core/EnumDictionaryBase.hxx"
9#include "Arp/System/Core/TypeName.hxx"
21template<
class T,
char Delimiter = '|'>
26 using U =
typename Base::U;
27 using InitializerList =
typename Base::InitializerList;
43 EnumFlagsDictionary(T flagsMask,
const char* invalidValueString,
const InitializerList& fields);
54 EnumFlagsDictionary(U flagsMask,
const char* invalidValueString,
const InitializerList& fields);
96 bool IsFlag(T value)
const;
97 bool TryGetCombinedEnumString(T value,
String& result)
const;
98 bool TryParseCombinedEnumValue(
const String& input, T& value)
const;
99 bool TryFormatFlags(T value,
String& result)
const;
102 T flagsMask =
static_cast<T
>(std::numeric_limits<U>::max());
103 T valueMask =
static_cast<T
>(0);
108template<
class T,
char Delimiter>
114template<
class T,
char Delimiter>
117 , flagsMask(flagsMask)
118 , valueMask(~flagsMask)
122template<
class T,
char Delimiter>
124 :
Base(invalidValueString, fields)
125 , flagsMask(flagsMask)
126 , valueMask(~flagsMask)
130template<
class T,
char Delimiter>
133 , flagsMask(static_cast<T>(flagsMask))
134 , valueMask(static_cast<T>(~flagsMask))
138template<
class T,
char Delimiter>
140 :
Base(invalidValueString, fields)
141 , flagsMask(static_cast<T>(flagsMask))
142 , valueMask(static_cast<T>(~flagsMask))
146template<
class T,
char Delimiter>
150 if (this->TryGetEnumString(value, enumString))
156 if (this->invalidValueString.IsEmpty())
158 os <<
"0x" << std::uppercase << std::hex << static_cast<U>(value);
162 os << this->invalidValueString;
164 os.setstate(std::ios::failbit);
169template<
class T,
char Delimiter>
174 if (!this->TryParseCombinedEnumValue(s, value))
176 is.setstate(std::ios::failbit);
181template<
class T,
char Delimiter>
185 if (!this->TryGetCombinedEnumString(value, result))
187 throw Exception(
"Could not find enum string of enum '{}' for value '{}'.",
TypeName<T>().Value,
static_cast<U
>(value));
193template<
class T,
char Delimiter>
196 return this->TryGetCombinedEnumString(value, result);
199template<
class T,
char Delimiter>
205 throw Exception(
"Could not find enum value of enum '{}' for string '{}'.",
TypeName<T>().Value, fieldName);
210template<
class T,
char Delimiter>
213 return this->TryParseCombinedEnumValue(fieldName, value);
216template<
class T,
char Delimiter>
219 return (value & this->flagsMask) == value;
222template<
class T,
char Delimiter>
223inline bool EnumFlagsDictionary<T, Delimiter>::TryGetCombinedEnumString(T value,
String& result)
const
225 const char* pResult =
nullptr;
226 if (Base::TryGetEnumStringInternal(value, pResult))
233 if (TryFormatFlags(value, result))
238 std::ostringstream oss;
239 oss <<
"0x" << std::uppercase << std::hex << static_cast<U>(value);
244template<
class T,
char Delimiter>
245inline bool EnumFlagsDictionary<T, Delimiter>::TryFormatFlags(T value,
String& result)
const
247 std::ostringstream oss;
248 T resultValue = Base::zeroValue;
250 for (
const auto& item : this->fields)
252 if (item.first == Base::zeroValue)
256 if (IsFlag(item.first))
258 if ((value & item.first) == item.first)
260 if (oss.tellp() == std::streampos(0))
266 oss << Delimiter << item.second;
268 resultValue |= item.first;
273 if ((value & ~flagsMask) == item.first)
275 if (oss.tellp() == std::streampos(0))
281 oss << Delimiter << item.second;
283 resultValue |= item.first;
287 if (resultValue != value)
297template<
class T,
char Delimiter>
298inline bool EnumFlagsDictionary<T, Delimiter>::TryParseCombinedEnumValue(
const String& input, T& value)
const
300 static const char delimiters[] = {
'|',
',',
';', Delimiter };
301 static const size_t count =
sizeof(delimiters) /
sizeof(
char);
303 T result = Base::zeroValue;
305 for (
const String& token : tokens)
307 T flag = Base::zeroValue;
308 if (!this->TryGetEnumValueInternal(token, flag))
The class implements an adapter for enums to define the string literals of the enum entries.
Definition: EnumDictionaryBase.hxx:21
The class implements an adapter for enums to define the string literals of the enum entries.
Definition: EnumFlagsDictionary.hxx:23
bool TryGetEnumValue(const String &fieldName, T &value) const
Tries to get the enum value of the specified string.
Definition: EnumFlagsDictionary.hxx:211
std::istream & ReadEnumValue(std::istream &is, T &value) const
Tries to return the enum entry of the specified string.
Definition: EnumFlagsDictionary.hxx:170
EnumFlagsDictionary(const InitializerList &fields)
Constructor passing the enum fields as initializer list.
Definition: EnumFlagsDictionary.hxx:109
bool TryGetEnumString(T value, String &result) const
Returns the string of the specified enum value or nullptr if the value could not be found.
Definition: EnumFlagsDictionary.hxx:194
String GetEnumString(T value) const
Returns the string of the specified enum entry.
Definition: EnumFlagsDictionary.hxx:182
T GetEnumValue(const String &fieldName) const
Returns the value of the specified enum string.
Definition: EnumFlagsDictionary.hxx:200
std::ostream & WriteEnumString(std::ostream &os, T value) const
Writes the string of the specified enum value to the given stream.
Definition: EnumFlagsDictionary.hxx:147
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:67
std::vector< SelfType > Tokens
Used by Split() operation.
Definition: BasicString.hxx:40
Arp::BasicString< char8 > String
The Arp String class.
Definition: TypeSystem.h:27
Root namespace for the PLCnext API
ARP_CXX_SYMBOL_EXPORT bool TryGetEnumValue(const char *name, T &value)
This helper function tries to return the enum entry of the specified string.