13 #include <type_traits>
19 template <
typename E,
size_t N>
23 using int_type =
typename std::make_signed<typename std::underlying_type<E>::type>::type;
27 template <
size_t... LN>
28 explicit constexpr
EnumTags(
const char (&...literals)[LN]) :
_tags{{literals...}} {}
31 constexpr
const char*
tag(
int_type idx)
const {
return _tags[idx]; }
33 constexpr
const char*
operator[](E etag)
const {
return tag(etag); }
36 bool etag(
const char* tag, E& result)
const;
37 E etagOr(
const char* tag, E other)
const;
38 int_type idx(
const char* tag)
const;
40 const std::array<const char*, num_tags>&
tags()
const {
return _tags; }
51 static constexpr
size_t size() {
return num_tags; }
54 const std::array<const char*, num_tags>
_tags;
57 template <
typename E,
size_t... N>
59 return EnumTags<E,
sizeof...(N)>(literals...);
62 template <
typename E,
size_t N>
64 for (
size_t i = 0; i < _tags.size(); ++i) {
65 if (std::strcmp(_tags[i], tag) == 0) {
72 template <
typename E,
size_t N>
82 template <
typename E,
size_t N>
85 return (i >= 0) ? E(i) : other;