20hi_warning_ignore_msvc(26445);
22namespace hi::inline v1 {
30template<
typename ValueType,
typename NameType, std::
size_t N>
33 using value_type = ValueType;
34 using name_type = NameType;
44 static_assert(std::is_enum_v<value_type>,
"value_type Must be an enum");
45 static_assert(N != 0);
49 [[nodiscard]]
constexpr size_t size() const noexcept
56 [[nodiscard]]
constexpr value_type
minimum() const noexcept
58 return std::get<0>(_by_value).value;
63 [[nodiscard]]
constexpr value_type
maximum() const noexcept
65 return std::get<N - 1>(_by_value).value;
81 template<
typename... Args>
84 static_assert(
sizeof...(Args) == N * 2);
85 add_value_name<0>(args...);
88 return a.name < b.name;
92 return to_underlying(a.value) < to_underlying(b.value);
95 values_are_continues = check_values_are_continues();
103 [[nodiscard]]
constexpr bool contains(std::convertible_to<name_type>
auto&& name)
const noexcept
105 return find(name_type{
hi_forward(name)}) !=
nullptr;
113 [[nodiscard]]
constexpr bool contains(value_type value)
const noexcept
115 return find(value) !=
nullptr;
124 [[nodiscard]]
constexpr value_type
at(std::convertible_to<name_type>
auto&& name)
const
139 [[nodiscard]]
constexpr name_type
const&
at(value_type value)
const
141 if (
hilet *name = find(value)) {
154 [[nodiscard]]
constexpr value_type
at(std::convertible_to<name_type>
auto&& name, value_type default_value)
const noexcept
159 return default_value;
169 [[nodiscard]]
constexpr name_type
at(value_type value, std::convertible_to<name_type>
auto&& default_name)
const noexcept
171 if (
hilet *name = find(value)) {
184 [[nodiscard]]
constexpr value_type
operator[](std::convertible_to<name_type>
auto&& name)
const noexcept
186 auto *value = find(name_type{
hi_forward(name)});
187 hi_axiom(value !=
nullptr);
197 [[nodiscard]]
constexpr name_type
const&
operator[](value_type value)
const noexcept
199 auto *name = find(value);
200 hi_axiom(name !=
nullptr);
209 constexpr value_name() noexcept : value(), name() {}
210 constexpr value_name(value_type value, name_type name) noexcept : value(value), name(
std::move(name)) {}
216 [[nodiscard]]
constexpr name_type
const *
find(value_type value)
const noexcept
218 if (values_are_continues) {
221 hilet offset = to_underlying(it->value);
222 hilet i = to_underlying(value) - offset;
223 return (i >= 0 and i < N) ? &(it + i)->name : nullptr;
227 return item.value < key;
230 return (it != _by_value.
end() and it->value == value) ? &it->name :
nullptr;
234 [[nodiscard]]
constexpr value_type
const *
find(name_type
const& name)
const noexcept
237 return item.name < key;
240 return (it != _by_name.
end() and it->name == name) ? &it->value :
nullptr;
248 constexpr void add_value_name(value_type value, name_type name, Rest
const&...rest)
noexcept
250 static_assert(
sizeof...(Rest) % 2 == 0);
252 std::get<I>(_by_name) = {value, name};
253 std::get<I>(_by_value) = {value,
std::move(name)};
255 if constexpr (
sizeof...(Rest) > 0) {
256 add_value_name<I + 1>(rest...);
264 [[nodiscard]]
constexpr bool check_values_are_continues() const noexcept
266 auto check_value = to_underlying(minimum());
267 for (
hilet& item : _by_value) {
268 if (to_underlying(item.value) != check_value++) {
278 using type = std::decay_t<T>;
289using enum_metadata_name_t = enum_metadata_name<T>::type;
291template<
typename ValueType,
typename NameType,
typename... Rest>
292enum_metadata(ValueType
const&, NameType
const&, Rest
const&...)
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition required.hpp:29
A object that holds enum-values and strings.
Definition enum_metadata.hpp:31
constexpr bool contains(value_type value) const noexcept
Check if the enum has a value.
Definition enum_metadata.hpp:113
constexpr size_t size() const noexcept
Get the number of enum values.
Definition enum_metadata.hpp:49
constexpr value_type maximum() const noexcept
Get the maximum value.
Definition enum_metadata.hpp:63
bool values_are_continues
The numeric values in the enum do not contain a gap.
Definition enum_metadata.hpp:42
constexpr name_type const & operator[](value_type value) const noexcept
Get a name from an enum-value.
Definition enum_metadata.hpp:197
constexpr bool contains(std::convertible_to< name_type > auto &&name) const noexcept
Check if the enum has a name.
Definition enum_metadata.hpp:103
constexpr name_type at(value_type value, std::convertible_to< name_type > auto &&default_name) const noexcept
Get a name from an enum-value.
Definition enum_metadata.hpp:169
constexpr value_type minimum() const noexcept
Get the minimum value.
Definition enum_metadata.hpp:56
constexpr enum_metadata(Args const &...args) noexcept
Construct a enum-names table object.
Definition enum_metadata.hpp:82
constexpr value_type operator[](std::convertible_to< name_type > auto &&name) const noexcept
Get an enum-value from a name.
Definition enum_metadata.hpp:184
constexpr value_type at(std::convertible_to< name_type > auto &&name, value_type default_value) const noexcept
Get an enum-value from a name.
Definition enum_metadata.hpp:154
constexpr value_type at(std::convertible_to< name_type > auto &&name) const
Get an enum-value from a name.
Definition enum_metadata.hpp:124
constexpr name_type const & at(value_type value) const
Get a name from an enum-value.
Definition enum_metadata.hpp:139
Definition enum_metadata.hpp:277