7#include "../macros.hpp"
10#include "exception.hpp"
19hi_export_module(hikogui.utility.enum_metadata);
25hi_warning_ignore_msvc(26445);
27hi_export
namespace hi {
inline namespace v1 {
35template<
typename ValueType,
typename NameType, std::
size_t N>
38 using value_type = ValueType;
39 using name_type = NameType;
49 static_assert(std::is_enum_v<value_type>,
"value_type Must be an enum");
50 static_assert(N != 0);
54 [[nodiscard]]
constexpr size_t size() const noexcept
61 [[nodiscard]]
constexpr value_type
minimum() const noexcept
63 return std::get<0>(_by_value).value;
68 [[nodiscard]]
constexpr value_type
maximum() const noexcept
70 return std::get<N - 1>(_by_value).value;
86 template<
typename... Args>
89 static_assert(
sizeof...(Args) == N * 2);
90 add_value_name<0>(args...);
93 return a.name < b.name;
97 return std::to_underlying(a.value) < std::to_underlying(b.value);
108 template<std::convertible_to<name_type> Name>
109 [[nodiscard]]
constexpr bool contains(Name&& name)
const noexcept
111 return find(name_type{std::forward<Name>(name)}) !=
nullptr;
119 [[nodiscard]]
constexpr bool contains(value_type value)
const noexcept
121 return find(value) !=
nullptr;
130 template<std::convertible_to<name_type> Name>
131 [[nodiscard]]
constexpr value_type
at(Name&& name)
const
133 if (
auto const *value = find(name_type{std::forward<Name>(name)})) {
146 [[nodiscard]]
constexpr name_type
const&
at(value_type value)
const
148 if (
auto const *name = find(value)) {
160 template<std::convertible_to<name_type> Name>
161 [[nodiscard]]
constexpr std::optional<value_type>
at_if(Name&& name)
const noexcept
163 if (
auto const *value = find(name_type{std::forward<Name>(name)})) {
176 template<std::convertible_to<name_type> Name>
177 [[nodiscard]]
constexpr value_type
at(Name&& name, value_type default_value)
const noexcept
179 if (
auto const *value = find(name_type{std::forward<Name>(name)})) {
182 return default_value;
192 template<std::convertible_to<name_type> Name>
193 [[nodiscard]]
constexpr name_type
at(value_type value, Name&& default_name)
const noexcept
195 if (
auto const *name = find(value)) {
198 return std::forward<Name>(default_name);
208 template<std::convertible_to<name_type> Name>
209 [[nodiscard]]
constexpr value_type
operator[](Name&& name)
const noexcept
211 auto *value = find(name_type{std::forward<Name>(name)});
212 hi_assert_not_null(value);
222 [[nodiscard]]
constexpr name_type
const&
operator[](value_type value)
const noexcept
224 auto *name = find(value);
225 hi_assert_not_null(name);
234 constexpr value_name() noexcept : value(), name() {}
235 constexpr value_name(value_type value, name_type name) noexcept : value(value), name(
std::move(name)) {}
241 [[nodiscard]]
constexpr name_type
const *find(value_type value)
const noexcept
245 auto const it = _by_value.
begin();
246 auto const offset = std::to_underlying(it->value);
247 auto const i = std::to_underlying(value) - offset;
248 return (i >= 0 and i < N) ? &(it + i)->name : nullptr;
252 return item.value < key;
255 return (it != _by_value.
end() and it->value == value) ? &it->name :
nullptr;
259 [[nodiscard]]
constexpr value_type
const *find(name_type
const& name)
const noexcept
262 return item.name < key;
265 return (it != _by_name.
end() and it->name == name) ? &it->value :
nullptr;
273 constexpr void add_value_name(value_type value, name_type name, Rest
const&...rest)
noexcept
275 static_assert(
sizeof...(Rest) % 2 == 0);
277 std::get<I>(_by_name) = {value, name};
278 std::get<I>(_by_value) = {value,
std::move(name)};
280 if constexpr (
sizeof...(Rest) > 0) {
281 add_value_name<I + 1>(rest...);
289 [[nodiscard]]
constexpr bool check_values_are_continues() const noexcept
291 auto check_value = std::to_underlying(
minimum());
292 for (
auto const& item : _by_value) {
293 if (std::to_underlying(item.value) != check_value++) {
303 using type = std::decay_t<T>;
316template<
typename ValueType,
typename NameType,
typename... Rest>
317enum_metadata(ValueType
const&, NameType
const&, Rest
const&...)
Functions for casting values between types savely.
Utilities for throwing exceptions and terminating the application.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
A object that holds enum-values and strings.
Definition enum_metadata.hpp:36
constexpr value_type maximum() const noexcept
Get the maximum value.
Definition enum_metadata.hpp:68
constexpr value_type at(Name &&name, value_type default_value) const noexcept
Get an enum-value from a name.
Definition enum_metadata.hpp:177
constexpr value_type minimum() const noexcept
Get the minimum value.
Definition enum_metadata.hpp:61
constexpr value_type at(Name &&name) const
Get an enum-value from a name.
Definition enum_metadata.hpp:131
constexpr bool contains(value_type value) const noexcept
Check if the enum has a value.
Definition enum_metadata.hpp:119
constexpr name_type at(value_type value, Name &&default_name) const noexcept
Get a name from an enum-value.
Definition enum_metadata.hpp:193
constexpr std::optional< value_type > at_if(Name &&name) const noexcept
Get an enum-value from a name.
Definition enum_metadata.hpp:161
constexpr bool contains(Name &&name) const noexcept
Check if the enum has a name.
Definition enum_metadata.hpp:109
constexpr value_type operator[](Name &&name) const noexcept
Get an enum-value from a name.
Definition enum_metadata.hpp:209
constexpr name_type const & at(value_type value) const
Get a name from an enum-value.
Definition enum_metadata.hpp:146
static constexpr std::size_t count
The number of enum values.
Definition enum_metadata.hpp:43
constexpr size_t size() const noexcept
Get the number of enum values.
Definition enum_metadata.hpp:54
constexpr enum_metadata(Args const &...args) noexcept
Construct a enum-names table object.
Definition enum_metadata.hpp:87
bool values_are_continues
The numeric values in the enum do not contain a gap.
Definition enum_metadata.hpp:47
constexpr name_type const & operator[](value_type value) const noexcept
Get a name from an enum-value.
Definition enum_metadata.hpp:222
Definition enum_metadata.hpp:302