22#define MAGIC_CPP_ENUM_H
33
44#include " macro.h"
5- #include " string_view.h"
5+
6+ #ifdef MAGIC_CPP_20
7+ #include " raw_name.h"
68#include < array>
7- #include < iostream>
8- #include < type_traits>
99
1010#define ENUM_SEARCH_RANGE 32
1111namespace magic
1212{
1313 template <typename T>
1414 struct type_info ;
15-
16- template <auto value>
17- requires std::is_enum_v<decltype (value)>
18- constexpr auto name_of ()
19- {
20- // clang-format off
21- string_view name = MAGIC_CPP_FUNCTION_NAME;
22- #if __clang__ || __GNUC__
23- std::size_t r1 = name.rfind (" ::" );
24- std::size_t r2 = name.rfind (" value = " );
25- std::size_t last = name.rfind (" ]" );
26- name = (r1 != string_view::npos && r1 > r2) ? name.substr (r1 + 2 , last) : name.substr (r2 + 8 , last);
27- return name.find (" )" ) != string_view::npos ? " " : name;
28- #elif _MSC_VER
29- std::size_t r1 = name.rfind (" ::" );
30- std::size_t r2 = name.rfind (" name_of<" );
31- std::size_t last = name.rfind (" >" );
32- name = (r1 != string_view::npos && r1 > r2) ? name.substr (r1 + 2 , last) : name.substr (r2 + 8 , last);
33- return name.find (" )" ) != string_view::npos ? " " : name;
34- #else
35- static_assert (false , " not supported compiler" );
36- #endif
37- // clang-format on
38- }
3915} // namespace magic
4016
4117namespace magic ::details
4218{
4319 template <typename T, std::ptrdiff_t N = 0 >
4420 consteval std::ptrdiff_t search_possible_enum_start ()
4521 {
46- if constexpr (name_of <static_cast <T>(N)>() != " " )
22+ if constexpr (raw_name_of_enum <static_cast <T>(N)>() != " " )
4723 {
4824 return N;
4925 }
5026 else if constexpr (std::is_signed_v<std::underlying_type_t <T>>)
5127 {
52- if constexpr (name_of <static_cast <T>(-N)>() != " " )
28+ if constexpr (raw_name_of_enum <static_cast <T>(-N)>() != " " )
5329 {
5430 return -N;
5531 }
@@ -68,7 +44,7 @@ namespace magic::details
6844 consteval std::ptrdiff_t search_possible_continuous_enum_max ()
6945 {
7046 constexpr auto is_end = []<std::size_t ... Is>(std::index_sequence<Is...>)
71- { return (name_of <static_cast <T>(N + Is)>().empty () && ...); }(std::make_index_sequence<8 >{});
47+ { return (raw_name_of_enum <static_cast <T>(N + Is)>().empty () && ...); }(std::make_index_sequence<8 >{});
7248
7349 if constexpr (is_end)
7450 {
@@ -130,9 +106,9 @@ namespace magic::details
130106 consteval auto search_possible_bit_field_enum_length ()
131107 {
132108 constexpr auto max = sizeof (T) * 8 ;
133- std::size_t result = name_of <static_cast <T>(0 )>() != " " ;
109+ std::size_t result = raw_name_of_enum <static_cast <T>(0 )>() != " " ;
134110 [&]<std::size_t ... Is>(std::index_sequence<Is...>)
135- { ((name_of <static_cast <T>(1 << Is)>() != " " ? result++ : result), ...); }(std::make_index_sequence<max>{});
111+ { ((raw_name_of_enum <static_cast <T>(1 << Is)>() != " " ? result++ : result), ...); }(std::make_index_sequence<max>{});
136112 return result;
137113 }
138114
@@ -163,23 +139,23 @@ namespace magic::details
163139 constexpr auto start = enum_start<T>();
164140 constexpr auto max = enum_max<T>();
165141 constexpr auto length = max - start + 1 ;
166- std::array<string_view, length> names{};
167- split_initialize<T, length>([&]<std::size_t I>() { names[I] = name_of <static_cast <T>(start + I)>(); });
142+ std::array<std:: string_view, length> names{};
143+ split_initialize<T, length>([&]<std::size_t I>() { names[I] = raw_name_of_enum <static_cast <T>(start + I)>(); });
168144 return names;
169145 }
170146 else
171147 {
172148 constexpr auto length = search_possible_bit_field_enum_length<T>();
173- std::array<string_view, length> names{};
174- constexpr auto has_zero = name_of <static_cast <T>(0 )>() != " " ;
149+ std::array<std:: string_view, length> names{};
150+ constexpr auto has_zero = raw_name_of_enum <static_cast <T>(0 )>() != " " ;
175151 if constexpr (has_zero)
176152 {
177- names[0 ] = name_of <static_cast <T>(0 )>();
178- split_initialize<T, length - 1 >([&]<std::size_t I>() { names[I + 1 ] = name_of <static_cast <T>(1 << I)>(); });
153+ names[0 ] = raw_name_of_enum <static_cast <T>(0 )>();
154+ split_initialize<T, length - 1 >([&]<std::size_t I>() { names[I + 1 ] = raw_name_of_enum <static_cast <T>(1 << I)>(); });
179155 }
180156 else
181157 {
182- split_initialize<T, length>([&]<std::size_t I>() { names[I] = name_of <static_cast <T>(1 << I)>(); });
158+ split_initialize<T, length>([&]<std::size_t I>() { names[I] = raw_name_of_enum <static_cast <T>(1 << I)>(); });
183159 }
184160 return names;
185161 }
@@ -196,13 +172,13 @@ namespace magic::details
196172 requires std::is_enum_v<T>
197173 struct Field
198174 {
199- constexpr static string_view name () { return name_of <static_cast <T>(N)>(); }
175+ constexpr static std:: string_view name () { return raw_name_of_enum <static_cast <T>(N)>(); }
200176
201177 using type = T;
202178
203179 constexpr static std::ptrdiff_t value () { return N; }
204180
205- constexpr static string_view type_name () { return name_of <T>(); }
181+ constexpr static std:: string_view type_name () { return raw_name_of_enum <T>(); }
206182 };
207183
208184 template <typename T>
@@ -220,7 +196,7 @@ namespace magic::details
220196 else
221197 {
222198 constexpr auto length = search_possible_bit_field_enum_length<T>();
223- constexpr auto has_zero = name_of <static_cast <T>(0 )>() != " " ;
199+ constexpr auto has_zero = raw_name_of_enum <static_cast <T>(0 )>() != " " ;
224200 if constexpr (has_zero)
225201 {
226202 f (Field<T, 0 >{});
@@ -248,11 +224,11 @@ namespace magic
248224
249225 template <typename T>
250226 requires std::is_enum_v<T>
251- constexpr auto & name_of (T value)
227+ constexpr auto & raw_name_of_enum (T value)
252228 {
253229 constexpr auto start = enum_start<T>();
254230 return details::enum_names_storage<T>::names[static_cast <std::size_t >(value + start)];
255231 }
256232} // namespace magic
257-
233+ # endif
258234#endif // MAGIC_CPP_ENUM_H
0 commit comments