repr 0.1
Reconstructable string representations and more
Loading...
Searching...
No Matches
enum/util.h
Go to the documentation of this file.
1#pragma once
2#include <bit>
3#include <concepts>
4#include <cstddef>
5#include <type_traits>
6
9#include <librepr/ctvi/ctvi.h>
11
12namespace librepr::ctei {
13enum class EnumKind : unsigned char { Linear, Flags, Empty };
14
15template <typename T, EnumKind Kind>
16[[nodiscard]] constexpr auto to_underlying(auto idx) noexcept -> std::underlying_type_t<T> {
17 using underlying = std::underlying_type_t<T>;
18 if constexpr (Kind == EnumKind::Flags) {
19 if (idx == 0) {
20 return 0;
21 } else {
22 return underlying{1} << static_cast<underlying>(idx - 1);
23 }
24 } else {
25 return static_cast<underlying>(idx);
26 }
27}
28
29template <typename T, auto Value>
30[[nodiscard]] constexpr T to_enum() noexcept {
31 if constexpr (std::same_as<T, decltype(Value)>) {
32 return Value;
33 } else {
34 using underlying = std::underlying_type_t<T>;
35 // https://discourse.llvm.org/t/clang-16-notice-of-potentially-breaking-changes/65562
36 // GCC seems to warn for this as well
37 // TODO use this new diagnostic for search once https://github.com/llvm/llvm-project/issues/57176 is fixed
38
39 // library UB does not need to be diagnosed
40 // (https://eel.is/c++draft/expr.const#5.31) hence we can use std::bit_cast
41 // here to bypass the miscompile and possible warnings
42 return std::bit_cast<T>(static_cast<underlying>(Value));
43 }
44}
45
46#if USING(LIBREPR_COMPILER_CLANG) && __has_warning("-Wenum-constexpr-conversion")
48// https://github.com/llvm/llvm-project/issues/68489
49LIBREPR_WARNING_DISABLE_CLANG("-Wenum-constexpr-conversion")
50#endif
51
52namespace detail {
53template <typename T, auto Value>
54[[nodiscard]] constexpr auto get_enum_name() noexcept {
55 constexpr auto name = ctvi::value<to_enum<T, Value>()>;
56 if constexpr (!name.empty() && name[0] != '(') {
57 return name;
58 } else {
59 return const_string<0>{};
60 }
61}
62} // namespace detail
63
64template <typename T, auto Value>
65inline constexpr auto enum_name = detail::get_enum_name<T, Value>();
66
67template <auto V>
68[[nodiscard]] consteval auto dump_quick() noexcept {
69#if defined(_MSC_VER)
70 constexpr auto signature = std::string_view{__FUNCSIG__};
71 // TODO find prefix for MSVC
72 constexpr std::size_t start = sizeof("__cdecl librepr::ctei::dump_quick<") - 1;
73#else
75#if defined(__clang__)
76 //
77 constexpr std::size_t start = sizeof("auto librepr::ctei::dump_quick() [V = ") - 1;
78#elif defined(__GNUC__)
79 //
80 constexpr std::size_t start = sizeof("consteval auto librepr::ctei::dump_quick() [with auto V = ") - 1;
81#elif defined(_MSC_VER)
82#endif
83#endif
84 constexpr std::size_t end = signature.length() - 1;
85
86 return signature.substr(start, end - start);
87}
88
89template <auto... V>
90[[nodiscard]] consteval auto dump_list() noexcept {
91#if defined(_MSC_VER)
92 constexpr auto signature = std::string_view{__FUNCSIG__};
93 // TODO find prefix for MSVC
94 constexpr std::size_t start = sizeof("__cdecl librepr::ctei::dump_list<") - 1;
95#else
97#if defined(__clang__)
98 constexpr std::size_t start = sizeof("auto librepr::ctei::dump_list() [V = <") - 1;
99#elif defined(__GNUC__)
100 constexpr std::size_t start = sizeof("consteval auto librepr::ctei::dump_list() [with auto ...V = {") - 1;
101#endif
102#endif
103 constexpr std::size_t end = signature.length() - 2;
104
105 return signature.substr(start, end - start);
106}
107
108template <typename T, auto Value>
109[[nodiscard]] constexpr bool is_enum_value() {
110 // accessing the underlying array here directly seems to perform slightly better
111 // constexpr auto name = detail::enum_name_raw<T, Value>;
112 constexpr auto name = dump_quick<std::bit_cast<T>(static_cast<std::underlying_type_t<T>>(Value))>();
113 return !name.empty() && name[0] != '(';
114}
115
116#if USING(LIBREPR_COMPILER_CLANG) && __has_warning("-Wenum-constexpr-conversion")
118#endif
119
120} // namespace librepr::ctei
constexpr auto get_enum_name() noexcept
Definition enum/util.h:54
Definition accessor.h:14
consteval auto dump_quick() noexcept
Definition enum/util.h:68
constexpr bool is_enum_value()
Definition enum/util.h:109
constexpr auto to_underlying(auto idx) noexcept -> std::underlying_type_t< T >
Definition enum/util.h:16
constexpr T to_enum() noexcept
Definition enum/util.h:30
consteval auto dump_list() noexcept
Definition enum/util.h:90
EnumKind
Definition enum/util.h:13
constexpr auto enum_name
Definition enum/util.h:65
std::string code_for()
Definition repr:39
Definition const_string.h:9
#define LIBREPR_WARNING_DISABLE_CLANG(...)
Definition warning.h:24