I am reading an enum
value from a binary file and would like to check if the value is really part of the enum
values. How can I do it?
Yet another way to do it:
#include
#include
#include
template
struct enum_traits { static constexpr void* values = nullptr; };
namespace detail
{
template
constexpr bool is_value_of(int, void*) { return false; }
template
constexpr bool is_value_of(int v, U)
{
using std::begin; using std::end;
return std::find_if(begin(enum_traits::values), end(enum_traits::values),
[=](auto value){ return value == static_cast(v); }
) != end(enum_traits::values);
}
}
template
constexpr bool is_value_of(int v)
{ return detail::is_value_of(v, decltype(enum_traits::values) { }); }
////////////////////
enum Abc { A = 4, B = 8, C = 12 };
template<>
struct enum_traits { static constexpr auto values = { A, B, C }; };
decltype(enum_traits::values) enum_traits::values;
enum class Def { D = 1, E = 3, F = 5 };
int main()
{
std::cout << "Abc:";
for(int i = 0; i < 10; ++i)
if(is_value_of(i)) std::cout << " " << i;
std::cout << std::endl;
std::cout << "Def:";
for(int i = 0; i < 10; ++i)
if(is_value_of(i)) std::cout << " " << i;
std::cout << std::endl;
return 0;
}
The "ugly" part of this approach IMHO is having to define:
decltype(enum_traits::values) enum_traits::values
If you are not opposed to macros, you can wrap it inside a macro:
#define REGISTER_ENUM_VALUES(name, ...) \
template<> struct enum_traits { static constexpr auto values = { __VA_ARGS__ }; }; \
decltype(enum_traits::values) enum_traits::values;