Quantcast
Channel: User HolyBlackCat - Stack Overflow
Viewing all articles
Browse latest Browse all 1287

Answer by HolyBlackCat for how to know an enum class is sorted

$
0
0

There's no way to check the declaration order. Best you can do is check that the constants are contiguous (i.e. there are no gaps in the numbering).

First you start with __PRETTY_FUNCTION__/__FUNSIG__. This lets you check if the enum has a constant with a specific value:

template <auto X>constexpr const auto &PrettyFuncForValue(){    #ifdef _MSC_VER    return __FUNCSIG__;    #else    return __PRETTY_FUNCTION__;    #endif}
enum class E{    a = 10,    b = 20,    c = 21,    d = 22,};// Those outputs here are from Clang, other compilers have something similar.std::cout << PrettyFuncForValue<E::a>() << '\n'; // const auto &PrettyFuncForValue() [X = E::a]std::cout << PrettyFuncForValue<E(10)>() << '\n'; // const auto &PrettyFuncForValue() [X = E::a]std::cout << PrettyFuncForValue<E(11)>() << '\n'; // const auto &PrettyFuncForValue() [X = (E)11]

As you can see, values with associated names result in a different string pattern.

You can then search for this pattern:

template <auto X>inline constexpr bool enum_constant_is_valid =    std::string_view(PrettyFuncForValue<X>()).rfind(        #ifdef _MSC_VER"<(enum "        #else"X = ("        #endif    ) == std::string_view::npos;
std::cout << enum_constant_is_valid<E::a> << '\n'; // 1std::cout << enum_constant_is_valid<E(10)> << '\n'; // 1std::cout << enum_constant_is_valid<E(11)> << '\n'; // 0

Lastly you slap std::integer_sequence onto it to check a range of values:

template <auto A, auto B>requires std::same_as<decltype(A), decltype(B)>inline constexpr bool enum_range_is_valid =    []<std::underlying_type_t<decltype(A)> ...I>(std::integer_sequence<std::underlying_type_t<decltype(A)>, I...>){        return (enum_constant_is_valid<decltype(A)(std::to_underlying(A) + I)> && ...);    }(std::make_integer_sequence<std::underlying_type_t<decltype(A)>, std::to_underlying(B) - std::to_underlying(A) + 1>{});std::cout << enum_range_is_valid<E::a, E::a> << '\n'; // 1std::cout << enum_range_is_valid<E::a, E::b> << '\n'; // 0std::cout << enum_range_is_valid<E::b, E::d> << '\n'; // 1

Godbolt link with the full code.


Viewing all articles
Browse latest Browse all 1287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>