46 template <
typename Enum>
48 template <
typename Enum>
52 #define begin_declare_enum( enumName ) \
54 inline neolib::enum_enumerators_t<enumName> const& neolib::enum_enumerators<enumName>() \
56 static neolib::enum_enumerators_t<enumName> const sEnumerators = \
59 #define declare_enum_string( enumName, enumEnumerator ) { static_cast<std::underlying_type_t<enumName>>(enumName::enumEnumerator), neolib::string{ #enumEnumerator } },
60 #define declare_enum_string_explicit( enumName, enumEnumerator, enumString ) { static_cast<std::underlying_type_t<enumName>>(enumName::enumEnumerator), neolib::string{ #enumString } },
62 #define end_declare_enum( enumName ) \
64 return sEnumerators; \
67 struct bad_enum_value : std::runtime_error {
bad_enum_value(
const std::string& aString) : std::runtime_error{
"neolib: bad enum value '" + aString +
"'" } {} };
69 template <
typename Enum>
72 std::ostringstream oss;
73 oss <<
"0x" << std::uppercase << std::hex << std::setfill(
'0') << std::setw(
sizeof(
Enum) * 2u) <<
static_cast<std::underlying_type_t<Enum>
>(aEnumValue) <<
"u";
77 template <
typename Enum,
typename StringT =
string>
80 auto const e = enum_enumerators<Enum>().find(
static_cast<std::underlying_type_t<Enum>
>(aEnumerator));
81 if (e != enum_enumerators<Enum>().end())
83 if constexpr (std::is_same_v<StringT, std::string>)
84 return e->second().to_std_string();
88 else if (!aMustEnumerate)
94 struct bad_enum_string : std::runtime_error {
bad_enum_string(
const std::string& aString) : std::runtime_error{
"neolib: bad enum string '" + aString +
"'" } {} };
96 template <
typename Enum>
100 for (
auto const& e : enum_enumerators<Enum>())
101 if (e.second() == aEnumerator)
102 return static_cast<Enum>(e.first());
105 template <
typename Enum>
111 template <
typename Enum>
115 for (
auto const& e : enum_enumerators<Enum>())
116 if (e.second() == aEnumerator)
117 return static_cast<Enum>(e.first());
120 template <
typename Enum>
126 template <
typename Enum,
typename Char,
typename Traits,
typename = std::enable_if_t<std::is_enum_v<Enum>, sfinae>>
127 inline std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& aInput,
Enum& aEnum)
129 std::basic_string<Char, Traits> enumString;
130 aInput >> enumString;
131 aEnum = string_to_enum<Enum>(enumString);
135 template <
typename Enum,
typename Char,
typename Traits,
typename = std::enable_if_t<std::is_enum_v<Enum>, sfinae>>
136 inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& aOutput,
const Enum& aEnum)
138 aOutput << enum_to_string<Enum, std::basic_string<Char, Traits>>(aEnum);
142 template <
typename UnderlyingType>
162 return do_assign(aRhs);
168 return value() == that.value();
172 return value() <=> that.value();
189 virtual self_type* do_clone()
const = 0;
190 virtual self_type& do_assign(
const self_type& aRhs) = 0;
193 template <
typename Enum>
198 template <
typename Enum>
203 template <
typename Enum>
210 template <
typename T>
213 template <
typename Enum,
typename StringT =
string>
216 return enum_to_string(aEnumerator.template value<Enum>(), aMustEnumerate);
219 template <
typename Enum>
220 inline std::enable_if_t<std::is_enum_v<Enum>,
bool> operator==(
const i_basic_enum<std::underlying_type_t<Enum>>& lhs,
Enum rhs)
222 return lhs.template value<Enum>() == rhs;
225 template <
typename Enum>
226 inline std::enable_if_t<std::is_enum_v<Enum>,
bool> operator==(
Enum lhs,
const i_basic_enum<std::underlying_type_t<Enum>>& rhs)
228 return lhs == rhs.template value<Enum>();
231 template <
typename Enum>
232 inline std::enable_if_t<std::is_enum_v<Enum>,
bool> operator!=(
const i_basic_enum<std::underlying_type_t<Enum>>& lhs,
Enum rhs)
234 return lhs.template value<Enum>() != rhs;
237 template <
typename Enum>
238 inline std::enable_if_t<std::is_enum_v<Enum>,
bool> operator!=(
Enum lhs,
const i_basic_enum<std::underlying_type_t<Enum>>& rhs)
240 return lhs != rhs.template value<Enum>();
243 template <
typename Enum>
244 inline std::enable_if_t<std::is_enum_v<Enum>,
bool> operator<(
const i_basic_enum<std::underlying_type_t<Enum>>& lhs,
Enum rhs)
246 return lhs.template value<Enum>() < rhs;
249 template <
typename Enum>
250 inline std::enable_if_t<std::is_enum_v<Enum>,
bool>
operator<(
Enum lhs,
const i_basic_enum<std::underlying_type_t<Enum>>& rhs)
252 return lhs < rhs.template value<Enum>();
virtual underlying_type set_value(const i_string &aValue)=0
virtual void to_string(i_string &aString) const =0
virtual underlying_type const * data() const =0
std::strong_ordering operator<=>(const self_type &that) const
self_type & operator=(const self_type &aRhs)
virtual underlying_type value() const =0
std::string to_std_string() const
void set_value(Enum aValue)
virtual underlying_type * data()=0
i_multimap< underlying_type, i_string > enumerators_t
virtual void set_value(underlying_type aValue)=0
virtual const enumerators_t & enumerators() const =0
ref_ptr< self_type > clone() const
Enum set_value(const std::string &aValue)
UnderlyingType underlying_type
bool operator==(const self_type &that) const
std::string to_std_string() const
std::string to_std_string() const
bool operator<(const basic_rect< CoordinateType, CoordinateSystem > &left, const basic_rect< CoordinateType, CoordinateSystem > &right)
std::string enum_to_hex(Enum aEnumValue)
i_basic_enum< int64_t > i_enum_i64
i_basic_enum< int8_t > i_enum_i8
i_basic_enum< uint64_t > i_enum_u64
Enum string_to_enum(const i_string &aEnumerator)
i_basic_enum< int32_t > i_enum_i32
i_basic_enum< uint8_t > i_enum_u8
i_basic_enum< int16_t > i_enum_i16
std::optional< Enum > try_string_to_enum(const i_string &aEnumerator)
multimap< std::underlying_type_t< Enum >, string > enum_enumerators_t
i_basic_enum< std::underlying_type_t< T > > i_enum_t
StringT enum_to_string(Enum aEnumerator, bool aMustEnumerate=false)
i_basic_enum< uint32_t > i_enum_u32
enum_enumerators_t< Enum > const & enum_enumerators()
i_basic_enum< uint16_t > i_enum_u16
bad_enum_string(const std::string &aString)
bad_enum_value(const std::string &aString)