sandbox
Loading...
Searching...
No Matches
enum.hpp
1#ifndef LIBSBX_UTILITY_ENUM_HPP_
2#define LIBSBX_UTILITY_ENUM_HPP_
3
4#include <type_traits>
5#include <array>
6#include <ranges>
7#include <optional>
8
9#include <libsbx/utility/string_literal.hpp>
10
11namespace sbx::utility {
12
13template<typename Enum>
14requires (std::is_enum_v<Enum>)
15constexpr auto to_underlying(const Enum value) -> std::underlying_type_t<Enum> {
16 return static_cast<std::underlying_type_t<Enum>>(value);
17}
18
19template<typename Enum>
20requires (std::is_enum_v<Enum>)
21constexpr auto from_underlying(const std::underlying_type_t<Enum> value) -> Enum {
22 return static_cast<Enum>(value);
23}
24
25template<typename Enum>
26requires (std::is_enum_v<Enum>)
27struct entry {
28 Enum value;
29 const char* name;
30}; // struct entry
31
32template<typename Enum>
33requires (std::is_enum_v<Enum>)
35
36
37template<typename Type>
38concept mapped_enum = requires() {
39 std::is_enum_v<Type>;
41}; // concept mapped_enum
42
43template<mapped_enum Enum>
44constexpr auto to_string(const Enum value) -> std::string {
45 auto entry = std::ranges::find_if(enum_mapping<Enum>::values, [&value](const auto& entry){ return entry.value == value; });
46
47 if (entry == std::ranges::end(enum_mapping<Enum>::values)) {
48 return "<unknown>";
49 }
50
51 return entry->name;
52}
53
54template<mapped_enum Enum>
55constexpr auto from_string(const std::string& string) -> std::optional<Enum> {
56 auto entry = std::ranges::find_if(enum_mapping<Enum>::values, [&string](const auto& entry){ return entry.name == string; });
57
58 if (entry == std::ranges::end(enum_mapping<Enum>::values)) {
59 return std::nullopt;
60 }
61
62 return entry->value;
63}
64
65} // namespace sbx::utility
66
67#endif // LIBSBX_UTILITY_ENUM_HPP_
Definition: enum.hpp:27
Definition: enum.hpp:34