magic_enum.hpp
Go to the documentation of this file.
1 // __ __ _ ______ _____
2 // | \/ | (_) | ____| / ____|_ _
3 // | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_
4 // | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _|
5 // | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_|
6 // |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____|
7 // __/ | https://github.com/Neargye/magic_enum
8 // |___/ version 0.9.3
9 //
10 // Licensed under the MIT License <http://opensource.org/licenses/MIT>.
11 // SPDX-License-Identifier: MIT
12 // Copyright (c) 2019 - 2023 Daniil Goncharov <neargye@gmail.com>.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to deal
16 // in the Software without restriction, including without limitation the rights
17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 // copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included in all
22 // copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 
32 #ifndef NEARGYE_MAGIC_ENUM_HPP
33 #define NEARGYE_MAGIC_ENUM_HPP
34 
35 #define MAGIC_ENUM_VERSION_MAJOR 0
36 #define MAGIC_ENUM_VERSION_MINOR 9
37 #define MAGIC_ENUM_VERSION_PATCH 3
38 
39 #include <array>
40 #include <cstddef>
41 #include <cstdint>
42 #include <functional>
43 #include <limits>
44 #include <type_traits>
45 #include <utility>
46 
47 #if defined(MAGIC_ENUM_CONFIG_FILE)
48 # include MAGIC_ENUM_CONFIG_FILE
49 #endif
50 
51 #if !defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL)
52 # include <optional>
53 #endif
54 #if !defined(MAGIC_ENUM_USING_ALIAS_STRING)
55 # include <string>
56 #endif
57 #if !defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW)
58 # include <string_view>
59 #endif
60 
61 #if defined(MAGIC_ENUM_NO_ASSERT)
62 # define MAGIC_ENUM_ASSERT(...) static_cast<void>(0)
63 #else
64 # include <cassert>
65 # define MAGIC_ENUM_ASSERT(...) assert((__VA_ARGS__))
66 #endif
67 
68 #if defined(__clang__)
69 # pragma clang diagnostic push
70 # pragma clang diagnostic ignored "-Wunknown-warning-option"
71 # pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
72 #elif defined(__GNUC__)
73 # pragma GCC diagnostic push
74 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'.
75 #elif defined(_MSC_VER)
76 # pragma warning(push)
77 # pragma warning(disable : 26495) // Variable 'static_str<N>::chars_' is uninitialized.
78 # pragma warning(disable : 28020) // Arithmetic overflow: Using operator '-' on a 4 byte value and then casting the result to a 8 byte value.
79 # pragma warning(disable : 26451) // The expression '0<=_Param_(1)&&_Param_(1)<=1-1' is not true at this call.
80 # pragma warning(disable : 4514) // Unreferenced inline function has been removed.
81 #endif
82 
83 // Checks magic_enum compiler compatibility.
84 #if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910 || defined(__RESHARPER__)
85 # undef MAGIC_ENUM_SUPPORTED
86 # define MAGIC_ENUM_SUPPORTED 1
87 #endif
88 
89 // Checks magic_enum compiler aliases compatibility.
90 #if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920
91 # undef MAGIC_ENUM_SUPPORTED_ALIASES
92 # define MAGIC_ENUM_SUPPORTED_ALIASES 1
93 #endif
94 
95 // Enum value must be greater or equals than MAGIC_ENUM_RANGE_MIN. By default MAGIC_ENUM_RANGE_MIN = -128.
96 // If need another min range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN.
97 #if !defined(MAGIC_ENUM_RANGE_MIN)
98 # define MAGIC_ENUM_RANGE_MIN -128
99 #endif
100 
101 // Enum value must be less or equals than MAGIC_ENUM_RANGE_MAX. By default MAGIC_ENUM_RANGE_MAX = 128.
102 // If need another max range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MAX.
103 #if !defined(MAGIC_ENUM_RANGE_MAX)
104 # define MAGIC_ENUM_RANGE_MAX 127
105 #endif
106 
107 // Improve ReSharper C++ intellisense performance with builtins, avoiding unnecessary template instantiations.
108 #if defined(__RESHARPER__)
109 # undef MAGIC_ENUM_GET_ENUM_NAME_BUILTIN
110 # undef MAGIC_ENUM_GET_TYPE_NAME_BUILTIN
111 # if __RESHARPER__ >= 20230100
112 # define MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V) __rscpp_enumerator_name(V)
113 # define MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(T) __rscpp_type_name<T>()
114 # else
115 # define MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V) nullptr
116 # define MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(T) nullptr
117 # endif
118 #endif
119 
120 namespace magic_enum {
121 
122 // If need another optional type, define the macro MAGIC_ENUM_USING_ALIAS_OPTIONAL.
123 #if defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL)
124 MAGIC_ENUM_USING_ALIAS_OPTIONAL
125 #else
126 using std::optional;
127 #endif
128 
129 // If need another string_view type, define the macro MAGIC_ENUM_USING_ALIAS_STRING_VIEW.
130 #if defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW)
131 MAGIC_ENUM_USING_ALIAS_STRING_VIEW
132 #else
133 using std::string_view;
134 #endif
135 
136 // If need another string type, define the macro MAGIC_ENUM_USING_ALIAS_STRING.
137 #if defined(MAGIC_ENUM_USING_ALIAS_STRING)
138 MAGIC_ENUM_USING_ALIAS_STRING
139 #else
140 using std::string;
141 #endif
142 
143 using char_type = string_view::value_type;
144 static_assert(std::is_same_v<string_view::value_type, string::value_type>, "magic_enum::customize requires same string_view::value_type and string::value_type");
145 static_assert([] {
146  if constexpr (std::is_same_v<char_type, wchar_t>) {
147  constexpr const char c[] = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789|";
148  constexpr const wchar_t wc[] = L"abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789|";
149  static_assert(std::size(c) == std::size(wc), "magic_enum::customize identifier characters are multichars in wchar_t.");
150 
151  for (std::size_t i = 0; i < std::size(c); ++i) {
152  if (c[i] != wc[i]) {
153  return false;
154  }
155  }
156  }
157  return true;
158 } (), "magic_enum::customize wchar_t is not compatible with ASCII.");
159 
160 namespace customize {
161 
162 // Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128.
163 // If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX.
164 // If need another range for specific enum type, add specialization enum_range for necessary enum type.
165 template <typename E>
166 struct enum_range {
167  static_assert(std::is_enum_v<E>, "magic_enum::customize::enum_range requires enum type.");
168  static constexpr int min = MAGIC_ENUM_RANGE_MIN;
169  static constexpr int max = MAGIC_ENUM_RANGE_MAX;
170  static_assert(max > min, "magic_enum::customize::enum_range requires max > min.");
171 };
172 
173 static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN.");
174 static_assert((MAGIC_ENUM_RANGE_MAX - MAGIC_ENUM_RANGE_MIN) < (std::numeric_limits<std::uint16_t>::max)(), "MAGIC_ENUM_RANGE must be less than UINT16_MAX.");
175 
176 namespace detail {
177 
178 enum class customize_tag {
179  default_tag,
180  invalid_tag,
181  custom_tag
182 };
183 
184 } // namespace magic_enum::customize::detail
185 
186 class customize_t : public std::pair<detail::customize_tag, string_view> {
187  public:
188  constexpr customize_t(string_view srt) : std::pair<detail::customize_tag, string_view>{detail::customize_tag::custom_tag, srt} {}
189  constexpr customize_t(const char_type* srt) : customize_t{string_view{srt}} {}
190  constexpr customize_t(detail::customize_tag tag) : std::pair<detail::customize_tag, string_view>{tag, string_view{}} {
192  }
193 };
194 
195 // Default customize.
197 // Invalid customize.
199 
200 // If need custom names for enum, add specialization enum_name for necessary enum type.
201 template <typename E>
202 constexpr customize_t enum_name(E) noexcept {
203  return default_tag;
204 }
205 
206 // If need custom type name for enum, add specialization enum_type_name for necessary enum type.
207 template <typename E>
208 constexpr customize_t enum_type_name() noexcept {
209  return default_tag;
210 }
211 
212 } // namespace magic_enum::customize
213 
214 namespace detail {
215 
216 template <typename T>
217 struct supported
218 #if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || defined(MAGIC_ENUM_NO_CHECK_SUPPORT)
219  : std::true_type {};
220 #else
221  : std::false_type {};
222 #endif
223 
224 template <auto V, typename E = std::decay_t<decltype(V)>, std::enable_if_t<std::is_enum_v<E>, int> = 0>
225 using enum_constant = std::integral_constant<E, V>;
226 
227 template <typename... T>
228 inline constexpr bool always_false_v = false;
229 
230 template <typename T, typename = void>
231 struct has_is_flags : std::false_type {};
232 
233 template <typename T>
234 struct has_is_flags<T, std::void_t<decltype(customize::enum_range<T>::is_flags)>> : std::bool_constant<std::is_same_v<bool, std::decay_t<decltype(customize::enum_range<T>::is_flags)>>> {};
235 
236 template <typename T, typename = void>
237 struct range_min : std::integral_constant<int, MAGIC_ENUM_RANGE_MIN> {};
238 
239 template <typename T>
240 struct range_min<T, std::void_t<decltype(customize::enum_range<T>::min)>> : std::integral_constant<decltype(customize::enum_range<T>::min), customize::enum_range<T>::min> {};
241 
242 template <typename T, typename = void>
243 struct range_max : std::integral_constant<int, MAGIC_ENUM_RANGE_MAX> {};
244 
245 template <typename T>
246 struct range_max<T, std::void_t<decltype(customize::enum_range<T>::max)>> : std::integral_constant<decltype(customize::enum_range<T>::max), customize::enum_range<T>::max> {};
247 
248 struct str_view {
249  const char* str_ = nullptr;
250  std::size_t size_ = 0;
251 };
252 
253 template <std::uint16_t N>
254 class static_str {
255  public:
256  constexpr explicit static_str(str_view str) noexcept : static_str{str.str_, std::make_integer_sequence<std::uint16_t, N>{}} {
257  MAGIC_ENUM_ASSERT(str.size_ == N);
258  }
259 
260  constexpr explicit static_str(string_view str) noexcept : static_str{str.data(), std::make_integer_sequence<std::uint16_t, N>{}} {
261  MAGIC_ENUM_ASSERT(str.size() == N);
262  }
263 
264  constexpr const char_type* data() const noexcept { return chars_; }
265 
266  constexpr std::uint16_t size() const noexcept { return N; }
267 
268  constexpr operator string_view() const noexcept { return {data(), size()}; }
269 
270  private:
271  template <std::uint16_t... I>
272  constexpr static_str(const char* str, std::integer_sequence<std::uint16_t, I...>) noexcept : chars_{static_cast<char_type>(str[I])..., static_cast<char_type>('\0')} {}
273 
274  template <std::uint16_t... I>
275  constexpr static_str(string_view str, std::integer_sequence<std::uint16_t, I...>) noexcept : chars_{str[I]..., static_cast<char_type>('\0')} {}
276 
277  char_type chars_[static_cast<std::size_t>(N) + 1];
278 };
279 
280 template <>
281 class static_str<0> {
282  public:
283  constexpr explicit static_str() = default;
284 
285  constexpr explicit static_str(str_view) noexcept {}
286 
287  constexpr explicit static_str(string_view) noexcept {}
288 
289  constexpr const char_type* data() const noexcept { return nullptr; }
290 
291  constexpr std::uint16_t size() const noexcept { return 0; }
292 
293  constexpr operator string_view() const noexcept { return {}; }
294 };
295 
296 template <typename Op = std::equal_to<>>
298  static constexpr char_type to_lower(char_type c) noexcept {
299  return (c >= static_cast<char_type>('A') && c <= static_cast<char_type>('Z')) ? static_cast<char_type>(c + (static_cast<char_type>('a') - static_cast<char_type>('A'))) : c;
300  }
301 
302  public:
303  template <typename L, typename R>
304  constexpr auto operator()(L lhs,R rhs) const noexcept -> std::enable_if_t<std::is_same_v<std::decay_t<L>, char_type> && std::is_same_v<std::decay_t<R>, char_type>, bool> {
305  return Op{}(to_lower(lhs), to_lower(rhs));
306  }
307 };
308 
309 constexpr std::size_t find(string_view str, char_type c) noexcept {
310 #if defined(__clang__) && __clang_major__ < 9 && defined(__GLIBCXX__) || defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__)
311 // https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc
312 // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html
313  constexpr bool workaround = true;
314 #else
315  constexpr bool workaround = false;
316 #endif
317 
318  if constexpr (workaround) {
319  for (std::size_t i = 0; i < str.size(); ++i) {
320  if (str[i] == c) {
321  return i;
322  }
323  }
324 
325  return string_view::npos;
326  } else {
327  return str.find(c);
328  }
329 }
330 
331 template <typename BinaryPredicate>
332 constexpr bool is_default_predicate() noexcept {
333  return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
334  std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<>>;
335 }
336 
337 template <typename BinaryPredicate>
338 constexpr bool is_nothrow_invocable() {
339  return is_default_predicate<BinaryPredicate>() ||
340  std::is_nothrow_invocable_r_v<bool, BinaryPredicate, char_type, char_type>;
341 }
342 
343 template <typename BinaryPredicate>
344 constexpr bool cmp_equal(string_view lhs, string_view rhs, [[maybe_unused]] BinaryPredicate&& p) noexcept(is_nothrow_invocable<BinaryPredicate>()) {
345 #if defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__)
346  // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html
347  // https://developercommunity.visualstudio.com/content/problem/232218/c-constexpr-string-view.html
348  constexpr bool workaround = true;
349 #else
350  constexpr bool workaround = false;
351 #endif
352 
353  if constexpr (!is_default_predicate<BinaryPredicate>() || workaround) {
354  if (lhs.size() != rhs.size()) {
355  return false;
356  }
357 
358  const auto size = lhs.size();
359  for (std::size_t i = 0; i < size; ++i) {
360  if (!p(lhs[i], rhs[i])) {
361  return false;
362  }
363  }
364 
365  return true;
366  } else {
367  return lhs == rhs;
368  }
369 }
370 
371 template <typename L, typename R>
372 constexpr bool cmp_less(L lhs, R rhs) noexcept {
373  static_assert(std::is_integral_v<L> && std::is_integral_v<R>, "magic_enum::detail::cmp_less requires integral type.");
374 
375  if constexpr (std::is_signed_v<L> == std::is_signed_v<R>) {
376  // If same signedness (both signed or both unsigned).
377  return lhs < rhs;
378  } else if constexpr (std::is_same_v<L, bool>) { // bool special case
379  return static_cast<R>(lhs) < rhs;
380  } else if constexpr (std::is_same_v<R, bool>) { // bool special case
381  return lhs < static_cast<L>(rhs);
382  } else if constexpr (std::is_signed_v<R>) {
383  // If 'right' is negative, then result is 'false', otherwise cast & compare.
384  return rhs > 0 && lhs < static_cast<std::make_unsigned_t<R>>(rhs);
385  } else {
386  // If 'left' is negative, then result is 'true', otherwise cast & compare.
387  return lhs < 0 || static_cast<std::make_unsigned_t<L>>(lhs) < rhs;
388  }
389 }
390 
391 template <typename I>
392 constexpr I log2(I value) noexcept {
393  static_assert(std::is_integral_v<I>, "magic_enum::detail::log2 requires integral type.");
394 
395  if constexpr (std::is_same_v<I, bool>) { // bool special case
396  return MAGIC_ENUM_ASSERT(false), value;
397  } else {
398  auto ret = I{0};
399  for (; value > I{1}; value >>= I{1}, ++ret) {}
400 
401  return ret;
402  }
403 }
404 
405 #if defined(__cpp_lib_array_constexpr) && __cpp_lib_array_constexpr >= 201603L
406 # define MAGIC_ENUM_ARRAY_CONSTEXPR 1
407 #else
408 template <typename T, std::size_t N, std::size_t... I>
409 constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N], std::index_sequence<I...>) noexcept {
410  return {{a[I]...}};
411 }
412 #endif
413 
414 template <typename T>
415 inline constexpr bool is_enum_v = std::is_enum_v<T> && std::is_same_v<T, std::decay_t<T>>;
416 
417 template <typename E>
418 constexpr auto n() noexcept {
419  static_assert(is_enum_v<E>, "magic_enum::detail::n requires enum type.");
420 
421  if constexpr (supported<E>::value) {
422 #if defined(MAGIC_ENUM_GET_TYPE_NAME_BUILTIN)
423  constexpr auto name_ptr = MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(E);
424  constexpr auto name = name_ptr ? str_view{name_ptr, std::char_traits<char>::length(name_ptr)} : str_view{};
425 #elif defined(__clang__)
426  auto name = str_view{__PRETTY_FUNCTION__ + 34, sizeof(__PRETTY_FUNCTION__) - 36};
427 #elif defined(__GNUC__)
428  auto name = str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1};
429  if (name.str_[name.size_ - 1] == ']') {
430  name.size_ -= 50;
431  name.str_ += 49;
432  } else {
433  name.size_ -= 40;
434  name.str_ += 37;
435  }
436 #elif defined(_MSC_VER)
437  auto name = str_view{__FUNCSIG__ + 40, sizeof(__FUNCSIG__) - 57};
438 #else
439  auto name = str_view{};
440 #endif
441  std::size_t p = 0;
442  for (std::size_t i = name.size_; i > 0; --i) {
443  if (name.str_[i] == ':') {
444  p = i + 1;
445  break;
446  }
447  }
448  if (p > 0) {
449  name.size_ -= p;
450  name.str_ += p;
451  }
452  return name;
453  } else {
454  return str_view{}; // Unsupported compiler or Invalid customize.
455  }
456 }
457 
458 template <typename E>
459 constexpr auto type_name() noexcept {
460  [[maybe_unused]] constexpr auto custom = customize::enum_type_name<E>();
461  static_assert(std::is_same_v<std::decay_t<decltype(custom)>, customize::customize_t>, "magic_enum::customize requires customize_t type.");
462  if constexpr (custom.first == customize::detail::customize_tag::custom_tag) {
463  constexpr auto name = custom.second;
464  static_assert(!name.empty(), "magic_enum::customize requires not empty string.");
465  return static_str<name.size()>{name};
466  } else if constexpr (custom.first == customize::detail::customize_tag::invalid_tag) {
467  return static_str<0>{};
468  } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) {
469  constexpr auto name = n<E>();
470  return static_str<name.size_>{name};
471  } else {
472  static_assert(always_false_v<E>, "magic_enum::customize invalid.");
473  }
474 }
475 
476 template <typename E>
477 inline constexpr auto type_name_v = type_name<E>();
478 
479 template <auto V>
480 constexpr auto n() noexcept {
481  static_assert(is_enum_v<decltype(V)>, "magic_enum::detail::n requires enum type.");
482 
483  if constexpr (supported<decltype(V)>::value) {
484 #if defined(MAGIC_ENUM_GET_ENUM_NAME_BUILTIN)
485  constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V);
486  auto name = name_ptr ? str_view{name_ptr, std::char_traits<char>::length(name_ptr)} : str_view{};
487 #elif defined(__clang__)
488  auto name = str_view{__PRETTY_FUNCTION__ + 34, sizeof(__PRETTY_FUNCTION__) - 36};
489  if (name.size_ > 22 && name.str_[0] == '(' && name.str_[1] == 'a' && name.str_[10] == ' ' && name.str_[22] == ':') {
490  name.size_ -= 23;
491  name.str_ += 23;
492  }
493  if (name.str_[0] == '(' || name.str_[0] == '-' || (name.str_[0] >= '0' && name.str_[0] <= '9')) {
494  name = str_view{};
495  }
496 #elif defined(__GNUC__)
497  auto name = str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1};
498  if (name.str_[name.size_ - 1] == ']') {
499  name.size_ -= 55;
500  name.str_ += 54;
501  } else {
502  name.size_ -= 40;
503  name.str_ += 37;
504  }
505  if (name.str_[0] == '(') {
506  name = str_view{};
507  }
508 #elif defined(_MSC_VER)
509  str_view name;
510  if ((__FUNCSIG__[5] == '_' && __FUNCSIG__[35] != '(') || (__FUNCSIG__[5] == 'c' && __FUNCSIG__[41] != '(')) {
511  name = str_view{__FUNCSIG__ + 35, sizeof(__FUNCSIG__) - 52};
512  }
513 #else
514  auto name = str_view{};
515 #endif
516  std::size_t p = 0;
517  for (std::size_t i = name.size_; i > 0; --i) {
518  if (name.str_[i] == ':') {
519  p = i + 1;
520  break;
521  }
522  }
523  if (p > 0) {
524  name.size_ -= p;
525  name.str_ += p;
526  }
527  return name;
528  } else {
529  return str_view{}; // Unsupported compiler or Invalid customize.
530  }
531 }
532 
533 #if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920
534 # define MAGIC_ENUM_VS_2017_WORKAROUND 1
535 #endif
536 
537 #if defined(MAGIC_ENUM_VS_2017_WORKAROUND)
538 template <typename E, E V>
539 constexpr auto n() noexcept {
540  static_assert(is_enum_v<E>, "magic_enum::detail::n requires enum type.");
541 
542 # if defined(MAGIC_ENUM_GET_ENUM_NAME_BUILTIN)
543  constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V);
544  auto name = name_ptr ? str_view{name_ptr, std::char_traits<char>::length(name_ptr)} : str_view{};
545 # else
546  str_view name = str_view{__FUNCSIG__, sizeof(__FUNCSIG__) - 17};
547  std::size_t p = 0;
548  for (std::size_t i = name.size_; i > 0; --i) {
549  if (name.str_[i] == ',' || name.str_[i] == ':') {
550  p = i + 1;
551  break;
552  }
553  }
554  if (p > 0) {
555  name.size_ -= p;
556  name.str_ += p;
557  }
558  if (name.str_[0] == '(' || name.str_[0] == '-' || (name.str_[0] >= '0' && name.str_[0] <= '9')) {
559  name = str_view{};
560  }
561  return name;
562 # endif
563 }
564 #endif
565 
566 template <typename E, E V>
567 constexpr auto enum_name() noexcept {
568  [[maybe_unused]] constexpr auto custom = customize::enum_name<E>(V);
569  static_assert(std::is_same_v<std::decay_t<decltype(custom)>, customize::customize_t>, "magic_enum::customize requires customize_t type.");
570  if constexpr (custom.first == customize::detail::customize_tag::custom_tag) {
571  constexpr auto name = custom.second;
572  static_assert(!name.empty(), "magic_enum::customize requires not empty string.");
573  return static_str<name.size()>{name};
574  } else if constexpr (custom.first == customize::detail::customize_tag::invalid_tag) {
575  return static_str<0>{};
576  } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) {
577 #if defined(MAGIC_ENUM_VS_2017_WORKAROUND)
578  constexpr auto name = n<E, V>();
579 #else
580  constexpr auto name = n<V>();
581 #endif
582  return static_str<name.size_>{name};
583  } else {
584  static_assert(always_false_v<E>, "magic_enum::customize invalid.");
585  }
586 }
587 
588 template <typename E, E V>
589 inline constexpr auto enum_name_v = enum_name<E, V>();
590 
591 template <typename E, auto V>
592 constexpr bool is_valid() noexcept {
593 #if defined(__clang__) && __clang_major__ >= 16
594  // https://reviews.llvm.org/D130058, https://reviews.llvm.org/D131307
595  constexpr E v = __builtin_bit_cast(E, V);
596 #else
597  constexpr E v = static_cast<E>(V);
598 #endif
599  [[maybe_unused]] constexpr auto custom = customize::enum_name<E>(v);
600  static_assert(std::is_same_v<std::decay_t<decltype(custom)>, customize::customize_t>, "magic_enum::customize requires customize_t type.");
601  if constexpr (custom.first == customize::detail::customize_tag::custom_tag) {
602  constexpr auto name = custom.second;
603  static_assert(!name.empty(), "magic_enum::customize requires not empty string.");
604  return name.size() != 0;
605  } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) {
606 #if defined(MAGIC_ENUM_VS_2017_WORKAROUND)
607  return n<E, v>().size_ != 0;
608 #else
609  return n<v>().size_ != 0;
610 #endif
611  } else {
612  return false;
613  }
614 }
615 
616 enum class enum_subtype {
617  common,
618  flags
619 };
620 
621 template <typename E, int O, enum_subtype S, typename U = std::underlying_type_t<E>>
622 constexpr U ualue(std::size_t i) noexcept {
623  if constexpr (std::is_same_v<U, bool>) { // bool special case
624  static_assert(O == 0, "magic_enum::detail::ualue requires valid offset.");
625 
626  return static_cast<U>(i);
627  } else if constexpr (S == enum_subtype::flags) {
628  return static_cast<U>(U{1} << static_cast<U>(static_cast<int>(i) + O));
629  } else {
630  return static_cast<U>(static_cast<int>(i) + O);
631  }
632 }
633 
634 template <typename E, int O, enum_subtype S, typename U = std::underlying_type_t<E>>
635 constexpr E value(std::size_t i) noexcept {
636  return static_cast<E>(ualue<E, O, S>(i));
637 }
638 
639 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
640 constexpr int reflected_min() noexcept {
641  if constexpr (S == enum_subtype::flags) {
642  return 0;
643  } else {
644  constexpr auto lhs = range_min<E>::value;
645  constexpr auto rhs = (std::numeric_limits<U>::min)();
646 
647  if constexpr (cmp_less(rhs, lhs)) {
648  return lhs;
649  } else {
650  return rhs;
651  }
652  }
653 }
654 
655 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
656 constexpr int reflected_max() noexcept {
657  if constexpr (S == enum_subtype::flags) {
658  return std::numeric_limits<U>::digits - 1;
659  } else {
660  constexpr auto lhs = range_max<E>::value;
661  constexpr auto rhs = (std::numeric_limits<U>::max)();
662 
663  if constexpr (cmp_less(lhs, rhs)) {
664  return lhs;
665  } else {
666  return rhs;
667  }
668  }
669 }
670 
671 #define MAGIC_ENUM_FOR_EACH_256(T) \
672  T( 0)T( 1)T( 2)T( 3)T( 4)T( 5)T( 6)T( 7)T( 8)T( 9)T( 10)T( 11)T( 12)T( 13)T( 14)T( 15)T( 16)T( 17)T( 18)T( 19)T( 20)T( 21)T( 22)T( 23)T( 24)T( 25)T( 26)T( 27)T( 28)T( 29)T( 30)T( 31) \
673  T( 32)T( 33)T( 34)T( 35)T( 36)T( 37)T( 38)T( 39)T( 40)T( 41)T( 42)T( 43)T( 44)T( 45)T( 46)T( 47)T( 48)T( 49)T( 50)T( 51)T( 52)T( 53)T( 54)T( 55)T( 56)T( 57)T( 58)T( 59)T( 60)T( 61)T( 62)T( 63) \
674  T( 64)T( 65)T( 66)T( 67)T( 68)T( 69)T( 70)T( 71)T( 72)T( 73)T( 74)T( 75)T( 76)T( 77)T( 78)T( 79)T( 80)T( 81)T( 82)T( 83)T( 84)T( 85)T( 86)T( 87)T( 88)T( 89)T( 90)T( 91)T( 92)T( 93)T( 94)T( 95) \
675  T( 96)T( 97)T( 98)T( 99)T(100)T(101)T(102)T(103)T(104)T(105)T(106)T(107)T(108)T(109)T(110)T(111)T(112)T(113)T(114)T(115)T(116)T(117)T(118)T(119)T(120)T(121)T(122)T(123)T(124)T(125)T(126)T(127) \
676  T(128)T(129)T(130)T(131)T(132)T(133)T(134)T(135)T(136)T(137)T(138)T(139)T(140)T(141)T(142)T(143)T(144)T(145)T(146)T(147)T(148)T(149)T(150)T(151)T(152)T(153)T(154)T(155)T(156)T(157)T(158)T(159) \
677  T(160)T(161)T(162)T(163)T(164)T(165)T(166)T(167)T(168)T(169)T(170)T(171)T(172)T(173)T(174)T(175)T(176)T(177)T(178)T(179)T(180)T(181)T(182)T(183)T(184)T(185)T(186)T(187)T(188)T(189)T(190)T(191) \
678  T(192)T(193)T(194)T(195)T(196)T(197)T(198)T(199)T(200)T(201)T(202)T(203)T(204)T(205)T(206)T(207)T(208)T(209)T(210)T(211)T(212)T(213)T(214)T(215)T(216)T(217)T(218)T(219)T(220)T(221)T(222)T(223) \
679  T(224)T(225)T(226)T(227)T(228)T(229)T(230)T(231)T(232)T(233)T(234)T(235)T(236)T(237)T(238)T(239)T(240)T(241)T(242)T(243)T(244)T(245)T(246)T(247)T(248)T(249)T(250)T(251)T(252)T(253)T(254)T(255)
680 
681 template <typename E, enum_subtype S, std::size_t Size, int Min, std::size_t I>
682 constexpr void valid_count(bool* valid, std::size_t& count) noexcept {
683 #define MAGIC_ENUM_V(O) \
684  if constexpr ((I + O) < Size) { \
685  if constexpr (is_valid<E, ualue<E, Min, S>(I + O)>()) { \
686  valid[I + O] = true; \
687  ++count; \
688  } \
689  }
690 
692 
693  if constexpr ((I + 256) < Size) {
694  valid_count<E, S, Size, Min, I + 256>(valid, count);
695  }
696 #undef MAGIC_ENUM_V
697 }
698 
699 template <std::size_t N>
701  std::size_t count = 0;
702  bool valid[N] = {};
703 };
704 
705 template <typename E, enum_subtype S, std::size_t Size, int Min>
706 constexpr auto valid_count() noexcept {
708  valid_count<E, S, Size, Min, 0>(vc.valid, vc.count);
709  return vc;
710 }
711 
712 template <typename E, enum_subtype S, std::size_t Size, int Min>
713 constexpr auto values() noexcept {
714  constexpr auto vc = valid_count<E, S, Size, Min>();
715 
716  if constexpr (vc.count > 0) {
717 #if defined(MAGIC_ENUM_ARRAY_CONSTEXPR)
718  std::array<E, vc.count> values = {};
719 #else
720  E values[vc.count] = {};
721 #endif
722  for (std::size_t i = 0, v = 0; v < vc.count; ++i) {
723  if (vc.valid[i]) {
724  values[v++] = value<E, Min, S>(i);
725  }
726  }
727 #if defined(MAGIC_ENUM_ARRAY_CONSTEXPR)
728  return values;
729 #else
730  return to_array(values, std::make_index_sequence<vc.count>{});
731 #endif
732  } else {
733  return std::array<E, 0>{};
734  }
735 }
736 
737 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
738 constexpr auto values() noexcept {
739  constexpr auto min = reflected_min<E, S>();
740  constexpr auto max = reflected_max<E, S>();
741  constexpr auto range_size = max - min + 1;
742  static_assert(range_size > 0, "magic_enum::enum_range requires valid size.");
743  static_assert(range_size < (std::numeric_limits<std::uint16_t>::max)(), "magic_enum::enum_range requires valid size.");
744 
745  return values<E, S, range_size, min>();
746 }
747 
748 template <typename E, typename U = std::underlying_type_t<E>>
749 constexpr enum_subtype subtype(std::true_type) noexcept {
750  if constexpr (std::is_same_v<U, bool>) { // bool special case
751  return enum_subtype::common;
752  } else if constexpr (has_is_flags<E>::value) {
754  } else {
755 #if defined(MAGIC_ENUM_AUTO_IS_FLAGS)
756  constexpr auto flags_values = values<E, enum_subtype::flags>();
757  constexpr auto default_values = values<E, enum_subtype::common>();
758  if (flags_values.size() == 0 || default_values.size() > flags_values.size()) {
759  return enum_subtype::common;
760  }
761  for (std::size_t i = 0; i < default_values.size(); ++i) {
762  const auto v = static_cast<U>(default_values[i]);
763  if (v != 0 && (v & (v - 1)) != 0) {
764  return enum_subtype::common;
765  }
766  }
767  return enum_subtype::flags;
768 #else
769  return enum_subtype::common;
770 #endif
771  }
772 }
773 
774 template <typename T>
775 constexpr enum_subtype subtype(std::false_type) noexcept {
776  // For non-enum type return default common subtype.
777  return enum_subtype::common;
778 }
779 
780 template <typename E, typename D = std::decay_t<E>>
781 inline constexpr auto subtype_v = subtype<D>(std::is_enum<D>{});
782 
783 template <typename E, enum_subtype S>
784 inline constexpr auto values_v = values<E, S>();
785 
786 template <typename E, enum_subtype S, typename D = std::decay_t<E>>
787 using values_t = decltype((values_v<D, S>));
788 
789 template <typename E, enum_subtype S>
790 inline constexpr auto count_v = values_v<E, S>.size();
791 
792 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
793 inline constexpr auto min_v = (count_v<E, S> > 0) ? static_cast<U>(values_v<E, S>.front()) : U{0};
794 
795 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
796 inline constexpr auto max_v = (count_v<E, S> > 0) ? static_cast<U>(values_v<E, S>.back()) : U{0};
797 
798 template <typename E, enum_subtype S, std::size_t... I>
799 constexpr auto names(std::index_sequence<I...>) noexcept {
800  return std::array<string_view, sizeof...(I)>{{enum_name_v<E, values_v<E, S>[I]>...}};
801 }
802 
803 template <typename E, enum_subtype S>
804 inline constexpr auto names_v = names<E, S>(std::make_index_sequence<count_v<E, S>>{});
805 
806 template <typename E, enum_subtype S, typename D = std::decay_t<E>>
807 using names_t = decltype((names_v<D, S>));
808 
809 template <typename E, enum_subtype S, std::size_t... I>
810 constexpr auto entries(std::index_sequence<I...>) noexcept {
811  return std::array<std::pair<E, string_view>, sizeof...(I)>{{{values_v<E, S>[I], enum_name_v<E, values_v<E, S>[I]>}...}};
812 }
813 
814 template <typename E, enum_subtype S>
815 inline constexpr auto entries_v = entries<E, S>(std::make_index_sequence<count_v<E, S>>{});
816 
817 template <typename E, enum_subtype S, typename D = std::decay_t<E>>
818 using entries_t = decltype((entries_v<D, S>));
819 
820 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
821 constexpr bool is_sparse() noexcept {
822  if constexpr (count_v<E, S> == 0) {
823  return false;
824  } else if constexpr (std::is_same_v<U, bool>) { // bool special case
825  return false;
826  } else {
827  constexpr auto max = (S == enum_subtype::flags) ? log2(max_v<E, S>) : max_v<E, S>;
828  constexpr auto min = (S == enum_subtype::flags) ? log2(min_v<E, S>) : min_v<E, S>;
829  constexpr auto range_size = max - min + 1;
830 
831  return range_size != count_v<E, S>;
832  }
833 }
834 
835 template <typename E, enum_subtype S = subtype_v<E>>
836 inline constexpr bool is_sparse_v = is_sparse<E, S>();
837 
838 template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
839 constexpr U values_ors() noexcept {
840  static_assert(S == enum_subtype::flags, "magic_enum::detail::values_ors requires valid subtype.");
841 
842  auto ors = U{0};
843  for (std::size_t i = 0; i < count_v<E, S>; ++i) {
844  ors |= static_cast<U>(values_v<E, S>[i]);
845  }
846 
847  return ors;
848 }
849 
850 template <bool, typename R>
851 struct enable_if_enum {};
852 
853 template <typename R>
854 struct enable_if_enum<true, R> {
855  using type = R;
856  static_assert(supported<R>::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility).");
857 };
858 
859 template <typename T, typename R, typename BinaryPredicate = std::equal_to<>, typename D = std::decay_t<T>>
860 using enable_if_t = typename enable_if_enum<std::is_enum_v<D> && std::is_invocable_r_v<bool, BinaryPredicate, char_type, char_type>, R>::type;
861 
862 template <typename T, std::enable_if_t<std::is_enum_v<std::decay_t<T>>, int> = 0>
863 using enum_concept = T;
864 
865 template <typename T, bool = std::is_enum_v<T>>
866 struct is_scoped_enum : std::false_type {};
867 
868 template <typename T>
869 struct is_scoped_enum<T, true> : std::bool_constant<!std::is_convertible_v<T, std::underlying_type_t<T>>> {};
870 
871 template <typename T, bool = std::is_enum_v<T>>
872 struct is_unscoped_enum : std::false_type {};
873 
874 template <typename T>
875 struct is_unscoped_enum<T, true> : std::bool_constant<std::is_convertible_v<T, std::underlying_type_t<T>>> {};
876 
877 template <typename T, bool = std::is_enum_v<std::decay_t<T>>>
878 struct underlying_type {};
879 
880 template <typename T>
881 struct underlying_type<T, true> : std::underlying_type<std::decay_t<T>> {};
882 
883 #if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH)
884 
885 template <typename Value, typename = void>
886 struct constexpr_hash_t;
887 
888 template <typename Value>
889 struct constexpr_hash_t<Value, std::enable_if_t<is_enum_v<Value>>> {
890  constexpr auto operator()(Value value) const noexcept {
891  using U = typename underlying_type<Value>::type;
892  if constexpr (std::is_same_v<U, bool>) { // bool special case
893  return static_cast<std::size_t>(value);
894  } else {
895  return static_cast<U>(value);
896  }
897  }
898  using secondary_hash = constexpr_hash_t;
899 };
900 
901 template <typename Value>
902 struct constexpr_hash_t<Value, std::enable_if_t<std::is_same_v<Value, string_view>>> {
903  static constexpr std::uint32_t crc_table[256] {
904  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
905  0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
906  0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
907  0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
908  0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
909  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
910  0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
911  0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
912  0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
913  0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
914  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
915  0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
916  0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
917  0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
918  0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
919  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
920  0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
921  0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
922  0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
923  0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
924  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
925  0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
926  0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
927  0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
928  0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
929  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
930  0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
931  0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
932  0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
933  0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
934  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
935  0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
936  };
937  constexpr std::uint32_t operator()(string_view value) const noexcept {
938  auto crc = static_cast<std::uint32_t>(0xffffffffL);
939  for (const auto c : value) {
940  crc = (crc >> 8) ^ crc_table[(crc ^ static_cast<std::uint32_t>(c)) & 0xff];
941  }
942  return crc ^ 0xffffffffL;
943  }
944 
945  struct secondary_hash {
946  constexpr std::uint32_t operator()(string_view value) const noexcept {
947  auto acc = static_cast<std::uint64_t>(2166136261ULL);
948  for (const auto c : value) {
949  acc = ((acc ^ static_cast<std::uint64_t>(c)) * static_cast<std::uint64_t>(16777619ULL)) & (std::numeric_limits<std::uint32_t>::max)();
950  }
951  return static_cast<std::uint32_t>(acc);
952  }
953  };
954 };
955 
956 template <typename Hash>
957 inline constexpr Hash hash_v{};
958 
959 template <auto* GlobValues, typename Hash>
960 constexpr auto calculate_cases(std::size_t Page) noexcept {
961  constexpr std::array values = *GlobValues;
962  constexpr std::size_t size = values.size();
963 
964  using switch_t = std::invoke_result_t<Hash, typename decltype(values)::value_type>;
965  static_assert(std::is_integral_v<switch_t> && !std::is_same_v<switch_t, bool>);
966  const std::size_t values_to = (std::min)(static_cast<std::size_t>(256), size - Page);
967 
968  std::array<switch_t, 256> result{};
969  auto fill = result.begin();
970  {
971  auto first = values.begin() + static_cast<std::ptrdiff_t>(Page);
972  auto last = values.begin() + static_cast<std::ptrdiff_t>(Page + values_to);
973  while (first != last) {
974  *fill++ = hash_v<Hash>(*first++);
975  }
976  }
977 
978  // dead cases, try to avoid case collisions
979  for (switch_t last_value = result[values_to - 1]; fill != result.end() && last_value != (std::numeric_limits<switch_t>::max)(); *fill++ = ++last_value) {
980  }
981 
982  {
983  auto it = result.begin();
984  auto last_value = (std::numeric_limits<switch_t>::min)();
985  for (; fill != result.end(); *fill++ = last_value++) {
986  while (last_value == *it) {
987  ++last_value, ++it;
988  }
989  }
990  }
991 
992  return result;
993 }
994 
995 template <typename R, typename F, typename... Args>
996 constexpr R invoke_r(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_r_v<R, F, Args...>) {
997  if constexpr (std::is_void_v<R>) {
998  std::forward<F>(f)(std::forward<Args>(args)...);
999  } else {
1000  return static_cast<R>(std::forward<F>(f)(std::forward<Args>(args)...));
1001  }
1002 }
1003 
1004 enum class case_call_t {
1005  index,
1006  value
1007 };
1008 
1009 template <typename T = void>
1010 inline constexpr auto default_result_type_lambda = []() noexcept(std::is_nothrow_default_constructible_v<T>) { return T{}; };
1011 
1012 template <>
1013 inline constexpr auto default_result_type_lambda<void> = []() noexcept {};
1014 
1015 template <auto* Arr, typename Hash>
1016 constexpr bool has_duplicate() noexcept {
1017  using value_t = std::decay_t<decltype((*Arr)[0])>;
1018  using hash_value_t = std::invoke_result_t<Hash, value_t>;
1019  std::array<hash_value_t, Arr->size()> hashes{};
1020  std::size_t size = 0;
1021  for (auto elem : *Arr) {
1022  hashes[size] = hash_v<Hash>(elem);
1023  for (auto i = size++; i > 0; --i) {
1024  if (hashes[i] < hashes[i - 1]) {
1025  auto tmp = hashes[i];
1026  hashes[i] = hashes[i - 1];
1027  hashes[i - 1] = tmp;
1028  } else if (hashes[i] == hashes[i - 1]) {
1029  return false;
1030  } else {
1031  break;
1032  }
1033  }
1034  }
1035  return true;
1036 }
1037 
1038 #define MAGIC_ENUM_CASE(val) \
1039  case cases[val]: \
1040  if constexpr ((val) + Page < size) { \
1041  if (!pred(values[val + Page], searched)) { \
1042  break; \
1043  } \
1044  if constexpr (CallValue == case_call_t::index) { \
1045  if constexpr (std::is_invocable_r_v<result_t, Lambda, std::integral_constant<std::size_t, val + Page>>) { \
1046  return detail::invoke_r<result_t>(std::forward<Lambda>(lambda), std::integral_constant<std::size_t, val + Page>{}); \
1047  } else if constexpr (std::is_invocable_v<Lambda, std::integral_constant<std::size_t, val + Page>>) { \
1048  MAGIC_ENUM_ASSERT(false && "magic_enum::detail::constexpr_switch wrong result type."); \
1049  } \
1050  } else if constexpr (CallValue == case_call_t::value) { \
1051  if constexpr (std::is_invocable_r_v<result_t, Lambda, enum_constant<values[val + Page]>>) { \
1052  return detail::invoke_r<result_t>(std::forward<Lambda>(lambda), enum_constant<values[val + Page]>{}); \
1053  } else if constexpr (std::is_invocable_r_v<result_t, Lambda, enum_constant<values[val + Page]>>) { \
1054  MAGIC_ENUM_ASSERT(false && "magic_enum::detail::constexpr_switch wrong result type."); \
1055  } \
1056  } \
1057  break; \
1058  } else [[fallthrough]];
1059 
1060 template <auto* GlobValues,
1061  case_call_t CallValue,
1062  std::size_t Page = 0,
1063  typename Hash = constexpr_hash_t<typename std::decay_t<decltype(*GlobValues)>::value_type>,
1064  typename BinaryPredicate = std::equal_to<>,
1065  typename Lambda,
1066  typename ResultGetterType>
1067 constexpr decltype(auto) constexpr_switch(
1068  Lambda&& lambda,
1069  typename std::decay_t<decltype(*GlobValues)>::value_type searched,
1070  ResultGetterType&& def,
1071  BinaryPredicate&& pred = {}) {
1072  using result_t = std::invoke_result_t<ResultGetterType>;
1073  using hash_t = std::conditional_t<has_duplicate<GlobValues, Hash>(), Hash, typename Hash::secondary_hash>;
1074  static_assert(has_duplicate<GlobValues, hash_t>(), "magic_enum::detail::constexpr_switch duplicated hash found, please report it: https://github.com/Neargye/magic_enum/issues.");
1075  constexpr std::array values = *GlobValues;
1076  constexpr std::size_t size = values.size();
1077  constexpr std::array cases = calculate_cases<GlobValues, hash_t>(Page);
1078 
1079  switch (hash_v<hash_t>(searched)) {
1080  MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_CASE)
1081  default:
1082  if constexpr (size > 256 + Page) {
1083  return constexpr_switch<GlobValues, CallValue, Page + 256, Hash>(std::forward<Lambda>(lambda), searched, std::forward<ResultGetterType>(def));
1084  }
1085  break;
1086  }
1087  return def();
1088 }
1089 
1090 #undef MAGIC_ENUM_CASE
1091 
1092 #endif
1093 
1094 } // namespace magic_enum::detail
1095 
1096 // Checks is magic_enum supported compiler.
1098 
1099 template <typename T>
1101 
1102 // Checks whether T is an Unscoped enumeration type.
1103 // Provides the member constant value which is equal to true, if T is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration) type. Otherwise, value is equal to false.
1104 template <typename T>
1106 
1107 template <typename T>
1109 
1110 // Checks whether T is an Scoped enumeration type.
1111 // Provides the member constant value which is equal to true, if T is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations) type. Otherwise, value is equal to false.
1112 template <typename T>
1114 
1115 template <typename T>
1117 
1118 // If T is a complete enumeration type, provides a member typedef type that names the underlying type of T.
1119 // Otherwise, if T is not an enumeration type, there is no member type. Otherwise (T is an incomplete enumeration type), the program is ill-formed.
1120 template <typename T>
1122 
1123 template <typename T>
1125 
1126 template <auto V>
1128 
1129 // Returns type name of enum.
1130 template <typename E>
1131 [[nodiscard]] constexpr auto enum_type_name() noexcept -> detail::enable_if_t<E, string_view> {
1132  constexpr string_view name = detail::type_name_v<std::decay_t<E>>;
1133  static_assert(!name.empty(), "magic_enum::enum_type_name enum type does not have a name.");
1134 
1135  return name;
1136 }
1137 
1138 // Returns number of enum values.
1139 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1140 [[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_t<E, std::size_t> {
1141  return detail::count_v<std::decay_t<E>, S>;
1142 }
1143 
1144 // Returns enum value at specified index.
1145 // No bounds checking is performed: the behavior is undefined if index >= number of enum values.
1146 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1147 [[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_t<E, std::decay_t<E>> {
1148  using D = std::decay_t<E>;
1149 
1150  if constexpr (detail::is_sparse_v<D, S>) {
1151  return MAGIC_ENUM_ASSERT(index < detail::count_v<D, S>), detail::values_v<D, S>[index];
1152  } else {
1153  constexpr auto min = (S == detail::enum_subtype::flags) ? detail::log2(detail::min_v<D, S>) : detail::min_v<D, S>;
1154 
1155  return MAGIC_ENUM_ASSERT(index < detail::count_v<D, S>), detail::value<D, min, S>(index);
1156  }
1157 }
1158 
1159 // Returns enum value at specified index.
1160 template <typename E, std::size_t I, detail::enum_subtype S = detail::subtype_v<E>>
1161 [[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_t<E, std::decay_t<E>> {
1162  using D = std::decay_t<E>;
1163  static_assert(I < detail::count_v<D, S>, "magic_enum::enum_value out of range.");
1164 
1165  return enum_value<D, S>(I);
1166 }
1167 
1168 // Returns std::array with enum values, sorted by enum value.
1169 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1170 [[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_t<E, detail::values_t<E, S>> {
1171  return detail::values_v<std::decay_t<E>, S>;
1172 }
1173 
1174 // Returns integer value from enum value.
1175 template <typename E>
1176 [[nodiscard]] constexpr auto enum_integer(E value) noexcept -> detail::enable_if_t<E, underlying_type_t<E>> {
1177  return static_cast<underlying_type_t<E>>(value);
1178 }
1179 
1180 // Returns underlying value from enum value.
1181 template <typename E>
1182 [[nodiscard]] constexpr auto enum_underlying(E value) noexcept -> detail::enable_if_t<E, underlying_type_t<E>> {
1183  return static_cast<underlying_type_t<E>>(value);
1184 }
1185 
1186 // Obtains index in enum values from enum value.
1187 // Returns optional with index.
1188 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1189 [[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> {
1190  using D = std::decay_t<E>;
1191  using U = underlying_type_t<D>;
1192 
1193  if constexpr (detail::count_v<D, S> == 0) {
1194  static_cast<void>(value);
1195  return {}; // Empty enum.
1196  } else if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) {
1197 #if defined(MAGIC_ENUM_ENABLE_HASH)
1198  return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::index>(
1199  [](std::size_t i) { return optional<std::size_t>{i}; },
1200  value,
1201  detail::default_result_type_lambda<optional<std::size_t>>);
1202 #else
1203  for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
1204  if (enum_value<D, S>(i) == value) {
1205  return i;
1206  }
1207  }
1208  return {}; // Invalid value or out of range.
1209 #endif
1210  } else {
1211  const auto v = static_cast<U>(value);
1212  if (v >= detail::min_v<D, S> && v <= detail::max_v<D, S>) {
1213  return static_cast<std::size_t>(v - detail::min_v<D, S>);
1214  }
1215  return {}; // Invalid value or out of range.
1216  }
1217 }
1218 
1219 // Obtains index in enum values from enum value.
1220 // Returns optional with index.
1221 template <detail::enum_subtype S, typename E>
1222 [[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> {
1223  using D = std::decay_t<E>;
1224 
1225  return enum_index<D, S>(value);
1226 }
1227 
1228 // Obtains index in enum values from static storage enum variable.
1229 template <auto V, detail::enum_subtype S = detail::subtype_v<std::decay_t<decltype(V)>>>
1230 [[nodiscard]] constexpr auto enum_index() noexcept -> detail::enable_if_t<decltype(V), std::size_t> {
1231  constexpr auto index = enum_index<std::decay_t<decltype(V)>, S>(V);
1232  static_assert(index, "magic_enum::enum_index enum value does not have a index.");
1233 
1234  return *index;
1235 }
1236 
1237 // Returns name from static storage enum variable.
1238 // This version is much lighter on the compile times and is not restricted to the enum_range limitation.
1239 template <auto V>
1240 [[nodiscard]] constexpr auto enum_name() noexcept -> detail::enable_if_t<decltype(V), string_view> {
1241  constexpr string_view name = detail::enum_name_v<std::decay_t<decltype(V)>, V>;
1242  static_assert(!name.empty(), "magic_enum::enum_name enum value does not have a name.");
1243 
1244  return name;
1245 }
1246 
1247 // Returns name from enum value.
1248 // If enum value does not have name or value out of range, returns empty string.
1249 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1250 [[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_t<E, string_view> {
1251  using D = std::decay_t<E>;
1252 
1253  if (const auto i = enum_index<D, S>(value)) {
1254  return detail::names_v<D, S>[*i];
1255  }
1256  return {};
1257 }
1258 
1259 // Returns name from enum value.
1260 // If enum value does not have name or value out of range, returns empty string.
1261 template <detail::enum_subtype S, typename E>
1262 [[nodiscard]] constexpr auto enum_name(E value) -> detail::enable_if_t<E, string_view> {
1263  using D = std::decay_t<E>;
1264 
1265  return enum_name<D, S>(value);
1266 }
1267 
1268 // Returns std::array with names, sorted by enum value.
1269 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1270 [[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_t<E, detail::names_t<E, S>> {
1271  return detail::names_v<std::decay_t<E>, S>;
1272 }
1273 
1274 // Returns std::array with pairs (value, name), sorted by enum value.
1275 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1276 [[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_t<E, detail::entries_t<E, S>> {
1277  return detail::entries_v<std::decay_t<E>, S>;
1278 }
1279 
1280 // Allows you to write magic_enum::enum_cast<foo>("bar", magic_enum::case_insensitive);
1282 
1283 // Obtains enum value from integer value.
1284 // Returns optional with enum value.
1285 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1287  using D = std::decay_t<E>;
1288 
1289  if constexpr (detail::count_v<D, S> == 0) {
1290  static_cast<void>(value);
1291  return {}; // Empty enum.
1292  } else {
1293  if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) {
1294 #if defined(MAGIC_ENUM_ENABLE_HASH)
1295  return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::value>(
1296  [](D v) { return optional<D>{v}; },
1297  static_cast<D>(value),
1298  detail::default_result_type_lambda<optional<D>>);
1299 #else
1300  for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
1301  if (value == static_cast<underlying_type_t<D>>(enum_value<D, S>(i))) {
1302  return static_cast<D>(value);
1303  }
1304  }
1305  return {}; // Invalid value or out of range.
1306 #endif
1307  } else {
1308  if (value >= detail::min_v<D, S> && value <= detail::max_v<D, S>) {
1309  return static_cast<D>(value);
1310  }
1311  return {}; // Invalid value or out of range.
1312  }
1313  }
1314 }
1315 
1316 // Obtains enum value from name.
1317 // Returns optional with enum value.
1318 template <typename E, detail::enum_subtype S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
1319 [[nodiscard]] constexpr auto enum_cast(string_view value, [[maybe_unused]] BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable<BinaryPredicate>()) -> detail::enable_if_t<E, optional<std::decay_t<E>>, BinaryPredicate> {
1320  using D = std::decay_t<E>;
1321 
1322  if constexpr (detail::count_v<D, S> == 0) {
1323  static_cast<void>(value);
1324  return {}; // Empty enum.
1325 #if defined(MAGIC_ENUM_ENABLE_HASH)
1326  } else if constexpr (detail::is_default_predicate<BinaryPredicate>()) {
1327  return detail::constexpr_switch<&detail::names_v<D, S>, detail::case_call_t::index>(
1328  [](std::size_t i) { return optional<D>{detail::values_v<D, S>[i]}; },
1329  value,
1330  detail::default_result_type_lambda<optional<D>>,
1331  [&p](string_view lhs, string_view rhs) { return detail::cmp_equal(lhs, rhs, p); });
1332 #endif
1333  } else {
1334  for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
1335  if (detail::cmp_equal(value, detail::names_v<D, S>[i], p)) {
1336  return enum_value<D, S>(i);
1337  }
1338  }
1339  return {}; // Invalid value or out of range.
1340  }
1341 }
1342 
1343 // Checks whether enum contains value with such value.
1344 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1345 [[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t<E, bool> {
1346  using D = std::decay_t<E>;
1347  using U = underlying_type_t<D>;
1348 
1349  return static_cast<bool>(enum_cast<D, S>(static_cast<U>(value)));
1350 }
1351 
1352 // Checks whether enum contains value with such value.
1353 template <detail::enum_subtype S, typename E>
1354 [[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t<E, bool> {
1355  using D = std::decay_t<E>;
1356  using U = underlying_type_t<D>;
1357 
1358  return static_cast<bool>(enum_cast<D, S>(static_cast<U>(value)));
1359 }
1360 
1361 // Checks whether enum contains value with such integer value.
1362 template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
1363 [[nodiscard]] constexpr auto enum_contains(underlying_type_t<E> value) noexcept -> detail::enable_if_t<E, bool> {
1364  using D = std::decay_t<E>;
1365 
1366  return static_cast<bool>(enum_cast<D, S>(value));
1367 }
1368 
1369 // Checks whether enum contains enumerator with such name.
1370 template <typename E, detail::enum_subtype S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
1371 [[nodiscard]] constexpr auto enum_contains(string_view value, BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable<BinaryPredicate>()) -> detail::enable_if_t<E, bool, BinaryPredicate> {
1372  using D = std::decay_t<E>;
1373 
1374  return static_cast<bool>(enum_cast<D, S>(value, std::move(p)));
1375 }
1376 
1377 template <bool AsFlags = true>
1379 
1380 template <bool AsFlags = true>
1382 
1383 namespace bitwise_operators {
1384 
1385 template <typename E, detail::enable_if_t<E, int> = 0>
1386 constexpr E operator~(E rhs) noexcept {
1387  return static_cast<E>(~static_cast<underlying_type_t<E>>(rhs));
1388 }
1389 
1390 template <typename E, detail::enable_if_t<E, int> = 0>
1391 constexpr E operator|(E lhs, E rhs) noexcept {
1392  return static_cast<E>(static_cast<underlying_type_t<E>>(lhs) | static_cast<underlying_type_t<E>>(rhs));
1393 }
1394 
1395 template <typename E, detail::enable_if_t<E, int> = 0>
1396 constexpr E operator&(E lhs, E rhs) noexcept {
1397  return static_cast<E>(static_cast<underlying_type_t<E>>(lhs) & static_cast<underlying_type_t<E>>(rhs));
1398 }
1399 
1400 template <typename E, detail::enable_if_t<E, int> = 0>
1401 constexpr E operator^(E lhs, E rhs) noexcept {
1402  return static_cast<E>(static_cast<underlying_type_t<E>>(lhs) ^ static_cast<underlying_type_t<E>>(rhs));
1403 }
1404 
1405 template <typename E, detail::enable_if_t<E, int> = 0>
1406 constexpr E& operator|=(E& lhs, E rhs) noexcept {
1407  return lhs = (lhs | rhs);
1408 }
1409 
1410 template <typename E, detail::enable_if_t<E, int> = 0>
1411 constexpr E& operator&=(E& lhs, E rhs) noexcept {
1412  return lhs = (lhs & rhs);
1413 }
1414 
1415 template <typename E, detail::enable_if_t<E, int> = 0>
1416 constexpr E& operator^=(E& lhs, E rhs) noexcept {
1417  return lhs = (lhs ^ rhs);
1418 }
1419 
1420 } // namespace magic_enum::bitwise_operators
1421 
1422 } // namespace magic_enum
1423 
1424 #if defined(__clang__)
1425 # pragma clang diagnostic pop
1426 #elif defined(__GNUC__)
1427 # pragma GCC diagnostic pop
1428 #elif defined(_MSC_VER)
1429 # pragma warning(pop)
1430 #endif
1431 
1432 #undef MAGIC_ENUM_GET_ENUM_NAME_BUILTIN
1433 #undef MAGIC_ENUM_GET_TYPE_NAME_BUILTIN
1434 #undef MAGIC_ENUM_VS_2017_WORKAROUND
1435 #undef MAGIC_ENUM_ARRAY_CONSTEXPR
1436 #undef MAGIC_ENUM_FOR_EACH_256
1437 
1438 #endif // NEARGYE_MAGIC_ENUM_HPP
magic_enum::as_flags
constexpr auto as_flags
Definition: magic_enum.hpp:1378
magic_enum::detail::enable_if_enum< true, R >::type
R type
Definition: magic_enum.hpp:855
magic_enum::customize::detail::customize_tag::default_tag
@ default_tag
magic_enum::is_unscoped_enum
Definition: magic_enum.hpp:1105
magic_enum::detail::values_t
decltype((values_v< D, S >)) values_t
Definition: magic_enum.hpp:787
ColorMap::Value
Value
Color maps that associate a color to every float from [0..1].
Definition: color.h:16
magic_enum::detail::static_str< 0 >::size
constexpr std::uint16_t size() const noexcept
Definition: magic_enum.hpp:291
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:43
armarx::aron::ret
ReaderT::InputType T & ret
Definition: rw.h:13
MAGIC_ENUM_RANGE_MAX
#define MAGIC_ENUM_RANGE_MAX
Definition: magic_enum.hpp:104
magic_enum::detail::enum_name
constexpr auto enum_name() noexcept
Definition: magic_enum.hpp:567
magic_enum::detail::underlying_type
Definition: magic_enum.hpp:878
magic_enum::detail::static_str< 0 >::static_str
constexpr static_str(str_view) noexcept
Definition: magic_enum.hpp:285
magic_enum::detail::cmp_equal
constexpr bool cmp_equal(string_view lhs, string_view rhs, [[maybe_unused]] BinaryPredicate &&p) noexcept(is_nothrow_invocable< BinaryPredicate >())
Definition: magic_enum.hpp:344
magic_enum::detail::is_default_predicate
constexpr bool is_default_predicate() noexcept
Definition: magic_enum.hpp:332
magic_enum::customize::enum_name
constexpr customize_t enum_name(E) noexcept
Definition: magic_enum.hpp:202
index
uint8_t index
Definition: EtherCATFrame.h:59
magic_enum::customize::customize_t::customize_t
constexpr customize_t(string_view srt)
Definition: magic_enum.hpp:188
magic_enum::detail::is_sparse
constexpr bool is_sparse() noexcept
Definition: magic_enum.hpp:821
MAGIC_ENUM_V
#define MAGIC_ENUM_V(O)
magic_enum::detail::static_str< 0 >::static_str
constexpr static_str(string_view) noexcept
Definition: magic_enum.hpp:287
magic_enum::case_insensitive
constexpr auto case_insensitive
Definition: magic_enum.hpp:1281
magic_enum::as_common
constexpr auto as_common
Definition: magic_enum.hpp:1381
magic_enum::detail::is_nothrow_invocable
constexpr bool is_nothrow_invocable()
Definition: magic_enum.hpp:338
magic_enum::customize::detail::customize_tag
customize_tag
Definition: magic_enum.hpp:178
magic_enum::detail::valid_count
constexpr void valid_count(bool *valid, std::size_t &count) noexcept
Definition: magic_enum.hpp:682
magic_enum::bitwise_operators::operator|=
constexpr E & operator|=(E &lhs, E rhs) noexcept
Definition: magic_enum.hpp:1406
magic_enum::detail::subtype_v
constexpr auto subtype_v
Definition: magic_enum.hpp:781
magic_enum::detail::subtype
constexpr enum_subtype subtype(std::true_type) noexcept
Definition: magic_enum.hpp:749
magic_enum::customize::customize_t::customize_t
constexpr customize_t(const char_type *srt)
Definition: magic_enum.hpp:189
MAGIC_ENUM_RANGE_MIN
#define MAGIC_ENUM_RANGE_MIN
Definition: magic_enum.hpp:98
magic_enum::detail::names
constexpr auto names(std::index_sequence< I... >) noexcept
Definition: magic_enum.hpp:799
magic_enum::bitwise_operators::operator|
constexpr E operator|(E lhs, E rhs) noexcept
Definition: magic_enum.hpp:1391
magic_enum::detail::is_unscoped_enum
Definition: magic_enum.hpp:872
detail
Definition: OpenCVUtil.cpp:128
magic_enum::detail::case_insensitive
Definition: magic_enum.hpp:297
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
magic_enum::detail::static_str< 0 >
Definition: magic_enum.hpp:281
MAGIC_ENUM_FOR_EACH_256
#define MAGIC_ENUM_FOR_EACH_256(T)
Definition: magic_enum.hpp:671
magic_enum::detail::has_is_flags
Definition: magic_enum.hpp:231
magic_enum::bitwise_operators::operator^
constexpr E operator^(E lhs, E rhs) noexcept
Definition: magic_enum.hpp:1401
magic_enum::detail::entries_t
decltype((entries_v< D, S >)) entries_t
Definition: magic_enum.hpp:818
magic_enum::detail::valid_count_t::valid
bool valid[N]
Definition: magic_enum.hpp:702
magic_enum::bitwise_operators::operator^=
constexpr E & operator^=(E &lhs, E rhs) noexcept
Definition: magic_enum.hpp:1416
magic_enum::detail::value
constexpr E value(std::size_t i) noexcept
Definition: magic_enum.hpp:635
magic_enum::detail::type_name_v
constexpr auto type_name_v
Definition: magic_enum.hpp:477
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:418
magic_enum::customize::customize_t::customize_t
constexpr customize_t(detail::customize_tag tag)
Definition: magic_enum.hpp:190
magic_enum::bitwise_operators::operator&=
constexpr E & operator&=(E &lhs, E rhs) noexcept
Definition: magic_enum.hpp:1411
magic_enum::is_unscoped_enum_v
constexpr bool is_unscoped_enum_v
Definition: magic_enum.hpp:1108
magic_enum::detail::static_str::static_str
constexpr static_str(str_view str) noexcept
Definition: magic_enum.hpp:256
magic_enum::enum_count
constexpr auto enum_count() noexcept -> detail::enable_if_t< E, std::size_t >
Definition: magic_enum.hpp:1140
magic_enum::char_type
string_view::value_type char_type
Definition: magic_enum.hpp:143
magic_enum::detail::enum_concept
T enum_concept
Definition: magic_enum.hpp:863
magic_enum::enum_contains
constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t< E, bool >
Definition: magic_enum.hpp:1345
magic_enum::customize::detail::customize_tag::custom_tag
@ custom_tag
magic_enum::customize::enum_type_name
constexpr customize_t enum_type_name() noexcept
Definition: magic_enum.hpp:208
magic_enum::customize::invalid_tag
constexpr auto invalid_tag
Definition: magic_enum.hpp:198
magic_enum::detail::log2
constexpr I log2(I value) noexcept
Definition: magic_enum.hpp:392
magic_enum::detail::to_array
constexpr std::array< std::remove_cv_t< T >, N > to_array(T(&a)[N], std::index_sequence< I... >) noexcept
Definition: magic_enum.hpp:409
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
magic_enum::detail::count_v
constexpr auto count_v
Definition: magic_enum.hpp:790
magic_enum::detail::str_view::str_
const char * str_
Definition: magic_enum.hpp:249
magic_enum::detail::static_str
Definition: magic_enum.hpp:254
magic_enum::underlying_type_t
typename underlying_type< T >::type underlying_type_t
Definition: magic_enum.hpp:1124
magic_enum::detail::min_v
constexpr auto min_v
Definition: magic_enum.hpp:793
magic_enum::detail::values
constexpr auto values() noexcept
Definition: magic_enum.hpp:713
magic_enum::enum_value
constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_t< E, std::decay_t< E >>
Definition: magic_enum.hpp:1147
if
if(!yyvaluep)
Definition: Grammar.cpp:645
magic_enum::enum_constant
detail::enum_constant< V > enum_constant
Definition: magic_enum.hpp:1127
magic_enum::detail::enum_subtype::common
@ common
magic_enum::detail::enum_name_v
constexpr auto enum_name_v
Definition: magic_enum.hpp:589
magic_enum::detail::is_sparse_v
constexpr bool is_sparse_v
Definition: magic_enum.hpp:836
magic_enum::enum_underlying
constexpr auto enum_underlying(E value) noexcept -> detail::enable_if_t< E, underlying_type_t< E >>
Definition: magic_enum.hpp:1182
magic_enum::detail::entries
constexpr auto entries(std::index_sequence< I... >) noexcept
Definition: magic_enum.hpp:810
magic_enum::detail::enable_if_t
typename enable_if_enum< std::is_enum_v< D > &&std::is_invocable_r_v< bool, BinaryPredicate, char_type, char_type >, R >::type enable_if_t
Definition: magic_enum.hpp:860
magic_enum::customize::enum_range::max
static constexpr int max
Definition: magic_enum.hpp:169
magic_enum::detail::valid_count_t
Definition: magic_enum.hpp:700
magic_enum::detail::cmp_less
constexpr bool cmp_less(L lhs, R rhs) noexcept
Definition: magic_enum.hpp:372
magic_enum::detail::str_view
Definition: magic_enum.hpp:248
magic_enum::enum_entries
constexpr auto enum_entries() noexcept -> detail::enable_if_t< E, detail::entries_t< E, S >>
Definition: magic_enum.hpp:1276
MAGIC_ENUM_ASSERT
#define MAGIC_ENUM_ASSERT(...)
Definition: magic_enum.hpp:65
max
T max(T t1, T t2)
Definition: gdiam.h:51
magic_enum::enum_values
constexpr auto enum_values() noexcept -> detail::enable_if_t< E, detail::values_t< E, S >>
Definition: magic_enum.hpp:1170
magic_enum::detail::valid_count_t::count
std::size_t count
Definition: magic_enum.hpp:701
magic_enum::detail::entries_v
constexpr auto entries_v
Definition: magic_enum.hpp:815
magic_enum::detail::type_name
constexpr auto type_name() noexcept
Definition: magic_enum.hpp:459
magic_enum::is_magic_enum_supported
constexpr bool is_magic_enum_supported
Definition: magic_enum.hpp:1097
magic_enum::detail::case_insensitive::operator()
constexpr auto operator()(L lhs, R rhs) const noexcept -> std::enable_if_t< std::is_same_v< std::decay_t< L >, char_type > &&std::is_same_v< std::decay_t< R >, char_type >, bool >
Definition: magic_enum.hpp:304
magic_enum::bitwise_operators::operator~
constexpr E operator~(E rhs) noexcept
Definition: magic_enum.hpp:1386
magic_enum::detail::static_str::size
constexpr std::uint16_t size() const noexcept
Definition: magic_enum.hpp:266
magic_enum::detail::range_min
Definition: magic_enum.hpp:237
magic_enum::detail::enum_constant
std::integral_constant< E, V > enum_constant
Definition: magic_enum.hpp:225
magic_enum::detail::always_false_v
constexpr bool always_false_v
Definition: magic_enum.hpp:228
magic_enum::customize::enum_range
Definition: magic_enum.hpp:166
magic_enum::detail::str_view::size_
std::size_t size_
Definition: magic_enum.hpp:250
magic_enum::is_scoped_enum
Definition: magic_enum.hpp:1113
magic_enum::detail::ualue
constexpr U ualue(std::size_t i) noexcept
Definition: magic_enum.hpp:622
magic_enum::detail::enum_subtype
enum_subtype
Definition: magic_enum.hpp:616
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
magic_enum::customize::default_tag
constexpr auto default_tag
Definition: magic_enum.hpp:196
armarx::meta::void_t
void void_t
Helper for sfinae (is added in c++17)
Definition: TemplateMetaProgramming.h:62
magic_enum::customize::enum_range::min
static constexpr int min
Definition: magic_enum.hpp:168
magic_enum::detail::is_scoped_enum
Definition: magic_enum.hpp:866
magic_enum::customize::customize_t
Definition: magic_enum.hpp:186
magic_enum::enum_name
constexpr auto enum_name() noexcept -> detail::enable_if_t< decltype(V), string_view >
Definition: magic_enum.hpp:1240
magic_enum::detail::names_v
constexpr auto names_v
Definition: magic_enum.hpp:804
std
Definition: Application.h:66
magic_enum::detail::find
constexpr std::size_t find(string_view str, char_type c) noexcept
Definition: magic_enum.hpp:309
magic_enum::detail::reflected_max
constexpr int reflected_max() noexcept
Definition: magic_enum.hpp:656
magic_enum::detail::values_v
constexpr auto values_v
Definition: magic_enum.hpp:784
magic_enum::detail::static_str::static_str
constexpr static_str(string_view str) noexcept
Definition: magic_enum.hpp:260
magic_enum::detail::static_str::data
constexpr const char_type * data() const noexcept
Definition: magic_enum.hpp:264
magic_enum::enum_cast
constexpr auto enum_cast(underlying_type_t< E > value) noexcept -> detail::enable_if_t< E, optional< std::decay_t< E >>>
Definition: magic_enum.hpp:1286
magic_enum::detail::enable_if_enum
Definition: magic_enum.hpp:851
magic_enum::detail::max_v
constexpr auto max_v
Definition: magic_enum.hpp:796
magic_enum::enum_index
constexpr auto enum_index(E value) noexcept -> detail::enable_if_t< E, optional< std::size_t >>
Definition: magic_enum.hpp:1189
magic_enum::is_scoped_enum_v
constexpr bool is_scoped_enum_v
Definition: magic_enum.hpp:1116
magic_enum::detail::range_max
Definition: magic_enum.hpp:243
magic_enum::underlying_type
Definition: magic_enum.hpp:1121
magic_enum
Definition: magic_enum.hpp:120
magic_enum::enum_names
constexpr auto enum_names() noexcept -> detail::enable_if_t< E, detail::names_t< E, S >>
Definition: magic_enum.hpp:1270
magic_enum::detail::is_valid
constexpr bool is_valid() noexcept
Definition: magic_enum.hpp:592
magic_enum::detail::is_enum_v
constexpr bool is_enum_v
Definition: magic_enum.hpp:415
magic_enum::bitwise_operators::operator&
constexpr E operator&(E lhs, E rhs) noexcept
Definition: magic_enum.hpp:1396
magic_enum::Enum
detail::enum_concept< T > Enum
Definition: magic_enum.hpp:1100
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
min
T min(T t1, T t2)
Definition: gdiam.h:44
magic_enum::detail::reflected_min
constexpr int reflected_min() noexcept
Definition: magic_enum.hpp:640
magic_enum::detail::values_ors
constexpr U values_ors() noexcept
Definition: magic_enum.hpp:839
magic_enum::enum_type_name
constexpr auto enum_type_name() noexcept -> detail::enable_if_t< E, string_view >
Definition: magic_enum.hpp:1131
magic_enum::detail::supported
Definition: magic_enum.hpp:217
magic_enum::enum_integer
constexpr auto enum_integer(E value) noexcept -> detail::enable_if_t< E, underlying_type_t< E >>
Definition: magic_enum.hpp:1176
magic_enum::detail::enum_subtype::flags
@ flags
magic_enum::customize::detail::customize_tag::invalid_tag
@ invalid_tag
magic_enum::detail::names_t
decltype((names_v< D, S >)) names_t
Definition: magic_enum.hpp:807
magic_enum::detail::static_str< 0 >::data
constexpr const char_type * data() const noexcept
Definition: magic_enum.hpp:289