My 3 cents, though this is not a complete match to what the op wants. Here is the relevant reference.
namespace enums
{
template
struct enums : std::integral_constant
{
static constexpr char const chars[sizeof...(Chars)]{Chars...};
};
template
constexpr auto make(std::index_sequence) noexcept
{
return enums();
}
#define ENUM(s, n) []() noexcept{\
struct S { char const (&chars)[sizeof(s)]{s}; };\
return enums::make(\
std::make_index_sequence());}()
#define ENUM_T(s, n)\
static constexpr auto s ## _tmp{ENUM(#s, n)};\
using s ## _enum_t = decltype(s ## _tmp)
template
inline auto map(char const (&s)[N]) noexcept
{
constexpr auto invalid(~T{});
auto r{invalid};
return
(
(
invalid == r ?
r = std::strncmp(A::chars, s, N) ? invalid : A{} :
r
),
...
);
}
}
int main()
{
ENUM_T(echo, 0);
ENUM_T(cat, 1);
ENUM_T(ls, 2);
std::cout << echo_enum_t{} << " " << echo_enum_t::chars << std::endl;
std::cout << enums::map("ls")) << std::endl;
return 0;
}
So you generate a type, that you can convert to an integer and/or a string.