16 template <
typename ENUM>
17 inline constexpr ENUM
Inc (ENUM e)
19 return ToEnum<ENUM> (ToInt (e) + 1);
27 template <
typename ENUM>
28 inline constexpr underlying_type_t<ENUM> ToInt (ENUM e)
32 return static_cast<typename underlying_type<ENUM>::type
> (e);
40 template <
typename ENUM>
41 constexpr make_unsigned_t<underlying_type_t<ENUM>> GetDistanceSpanned ()
43 return static_cast<make_unsigned_t<underlying_type_t<ENUM>
>> (ENUM::eCOUNT);
51 template <
typename ENUM>
52 inline constexpr ENUM
ToEnum (underlying_type_t<ENUM> e)
56 return static_cast<ENUM
> (e);
64 template <
typename ENUM>
65 inline constexpr make_unsigned_t<underlying_type_t<ENUM>>
OffsetFromStart (ENUM e)
67 DISABLE_COMPILER_CLANG_WARNING_START (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
70 return static_cast<make_unsigned_t<underlying_type_t<ENUM>
>> (ToInt (e) - ToInt (ENUM::eSTART));
71 DISABLE_COMPILER_CLANG_WARNING_END (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
79 template <
typename ENUM_TYPE>
80 inline EnumNames<ENUM_TYPE>::EnumNames (
const initializer_list<EnumName<ENUM_TYPE>>& origEnumNames)
82 : fEnumNames_{origEnumNames}
90 auto oi = fEnumNames_.begin ();
91 for (EnumName<ENUM_TYPE> i : origEnumNames) {
92 Require (oi != fEnumNames_.end ());
97 RequireItemsOrderedByEnumValue_ ();
99 template <
typename ENUM_TYPE>
100 constexpr EnumNames<ENUM_TYPE>::EnumNames (
const typename EnumNames<ENUM_TYPE>::BasicArrayInitializer& init)
103 RequireItemsOrderedByEnumValue_ ();
105 template <
typename ENUM_TYPE>
107 constexpr EnumNames<ENUM_TYPE>::EnumNames (
const EnumName<ENUM_TYPE> origEnumNames[N])
108 : fEnumNames_{origEnumNames}
110 RequireItemsOrderedByEnumValue_ ();
112 template <
typename ENUM_TYPE>
113 inline EnumNames<ENUM_TYPE>::operator initializer_list<EnumName<ENUM_TYPE>> ()
const
117 template <
typename ENUM_TYPE>
118 inline typename EnumNames<ENUM_TYPE>::const_iterator EnumNames<ENUM_TYPE>::begin ()
const
120 return fEnumNames_.begin ();
122 template <
typename ENUM_TYPE>
123 inline typename EnumNames<ENUM_TYPE>::const_iterator EnumNames<ENUM_TYPE>::end ()
const
125 return fEnumNames_.end ();
127 template <
typename ENUM_TYPE>
128 constexpr size_t EnumNames<ENUM_TYPE>::size ()
const
130 return fEnumNames_.size ();
132 template <
typename ENUM_TYPE>
133 constexpr const wchar_t* EnumNames<ENUM_TYPE>::PeekName (ENUM_TYPE e)
const
135 if (e == ENUM_TYPE::eEND) {
139 Require (OffsetFromStart<ENUM_TYPE> (e) < fEnumNames_.size ());
140 auto refImpl = [
this] (ENUM_TYPE e) ->
const wchar_t* {
141 for (
const auto& i : fEnumNames_) {
148 Ensure (refImpl (e) == fEnumNames_[OffsetFromStart<ENUM_TYPE> (e)].second);
150 return fEnumNames_[OffsetFromStart<ENUM_TYPE> (e)].second;
152 template <
typename ENUM_TYPE>
153 inline const wchar_t* EnumNames<ENUM_TYPE>::GetName (ENUM_TYPE e)
const
155 auto tmp = PeekName (e);
159 template <
typename ENUM_TYPE>
160 optional<ENUM_TYPE> EnumNames<ENUM_TYPE>::PeekValue (
const wchar_t* name)
const
167 for (const_iterator i = fEnumNames_.begin (); i != fEnumNames_.end (); ++i) {
168 if (::wcscmp (i->second, name) == 0) {
174 template <
typename ENUM_TYPE>
175 inline ENUM_TYPE EnumNames<ENUM_TYPE>::GetValue (
const wchar_t* name)
const
177 optional<ENUM_TYPE> tmp = PeekValue (name);
178 Require (tmp.has_value ());
181 template <
typename ENUM_TYPE>
182 template <
typename NOT_FOUND_EXCEPTION>
183 inline ENUM_TYPE EnumNames<ENUM_TYPE>::GetValue (
const wchar_t* name,
const NOT_FOUND_EXCEPTION& notFoundException)
const
186 optional<ENUM_TYPE> tmp = PeekValue (name);
187 if (!tmp) [[unlikely]] {
189 throw (notFoundException);
193 template <
typename ENUM_TYPE>
194 constexpr void EnumNames<ENUM_TYPE>::RequireItemsOrderedByEnumValue_ ()
const
196 DISABLE_COMPILER_MSC_WARNING_START (4996);
197 DISABLE_COMPILER_GCC_WARNING_START (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"");
198 DISABLE_COMPILER_CLANG_WARNING_START (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
199 Require (
static_cast<size_t> (ENUM_TYPE::eCOUNT) == fEnumNames_.size ());
200 using IndexType = make_unsigned_t<underlying_type_t<ENUM_TYPE>>;
201 if (not is_constant_evaluated ()) {
202 for (IndexType i = 0; i < static_cast<IndexType> (ENUM_TYPE::eCOUNT); ++i) {
203 Require (OffsetFromStart<ENUM_TYPE> (fEnumNames_[i].first) == i);
206 DISABLE_COMPILER_MSC_WARNING_END (4996);
207 DISABLE_COMPILER_GCC_WARNING_END (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"");
208 DISABLE_COMPILER_CLANG_WARNING_END (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
216 template <
typename ENUM_TYPE>
217 constexpr DefaultNames<ENUM_TYPE>::DefaultNames ()
218 : EnumNames<ENUM_TYPE>{k}
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
constexpr make_unsigned_t< underlying_type_t< ENUM > > OffsetFromStart(ENUM e)
offset of given enum from ENUM::eSTART
constexpr ENUM ToEnum(underlying_type_t< ENUM > e)
Cast the given int to the given ENUM type - (like static_cast<int>()) - but check range.
constexpr ENUM Inc(ENUM e)
Increment the given enumeration safely, without a bunch of casts.