VapourSynth-llvmexpr
Loading...
Searching...
No Matches
EnumName.hpp
Go to the documentation of this file.
1
44
45#ifndef LLVMEXPR_UTILS_ENUMNAME_HPP
46#define LLVMEXPR_UTILS_ENUMNAME_HPP
47
48#include <array>
49#include <string_view>
50#include <type_traits>
51#include <utility>
52
53#ifndef __clang__
54#error "Vapoursynth-llvmexpr is only supported by Clang"
55#endif
56
57template <auto value> consteval std::string_view enum_name() {
58 constexpr std::string_view NAME = __PRETTY_FUNCTION__;
59 constexpr auto START = NAME.find('=') + 2;
60 constexpr auto END = NAME.size() - 1;
61 constexpr auto FULL = NAME.substr(START, END - START);
62 constexpr auto LAST_COLON = FULL.rfind("::");
63 return LAST_COLON == std::string_view::npos ? FULL
64 : FULL.substr(LAST_COLON + 2);
65}
66
68template <typename T, std::size_t N> consteval bool is_valid_enum() {
69 return !enum_name<static_cast<T>(N)>().contains(")");
70}
71
72template <typename T, std::size_t N = 1>
73consteval std::size_t find_upper_bound() {
74 if constexpr (!is_valid_enum<T, N>()) {
75 return N;
76 } else {
78 }
79}
80
81template <typename T, std::size_t Low, std::size_t High>
82consteval std::size_t binary_search_count() {
83 if constexpr (High - Low <= 1) {
84 return is_valid_enum<T, Low>() ? High : Low;
85 } else {
86 constexpr std::size_t MID = Low + ((High - Low) / 2);
87 if constexpr (is_valid_enum<T, MID>()) {
89 } else {
91 }
92 }
93}
94
95template <typename T> consteval std::size_t enum_count() {
96 constexpr std::size_t UPPER = find_upper_bound<T>();
97 return binary_search_count<T, UPPER / 2, UPPER>();
98}
99
100template <typename T, std::size_t... Is>
101consteval auto make_names_impl(std::index_sequence<Is...> /*unused*/) {
102 return std::array{enum_name<static_cast<T>(Is)>()...};
103}
104
105template <typename T> consteval auto make_names() {
106 return make_names_impl<T>(std::make_index_sequence<enum_count<T>()>{});
107}
108} // namespace llvmexpr_enum_detail
109
110template <typename T> constexpr std::size_t enum_max() {
112}
113
114template <typename T>
115 requires std::is_enum_v<T> && std::is_scoped_enum_v<T>
116constexpr std::string_view enum_name(T value) {
117 static constexpr auto NAMES = llvmexpr_enum_detail::make_names<T>();
118 const auto index = static_cast<std::size_t>(std::to_underlying(value));
119 return index < NAMES.size() ? NAMES[index] : std::string_view{};
120}
121
122#endif // LLVMEXPR_UTILS_ENUMNAME_HPP
constexpr std::size_t enum_max()
Definition EnumName.hpp:110
consteval std::string_view enum_name()
Definition EnumName.hpp:57
consteval auto make_names_impl(std::index_sequence< Is... >)
Definition EnumName.hpp:101
consteval std::size_t enum_count()
Definition EnumName.hpp:95
consteval auto make_names()
Definition EnumName.hpp:105
consteval bool is_valid_enum()
Definition EnumName.hpp:68
consteval std::size_t binary_search_count()
Definition EnumName.hpp:82
consteval std::size_t find_upper_bound()
Definition EnumName.hpp:73