class Foo {
enum Color { kRed, kGreen, kBlue };
static constexpr const char* const kColorStr[] = { "Red", "Green", "Blue" };
};constexpr const char* const Foo::kColorStr[];static constexpr auto kColorStr = make_array("Red"sv, "Green"sv, "Blue"sv);
//decltype(kColorStr) == std::array<string_view, 3>//Assumes E starts from 0 and is contiguous
template <typename E>
std::optional<E> enum_to_str(string_view s, carray_view<string_view> tags) {
for(int i = 0; i < int(tags.size()); ++i) {
if(s == tags[i]) {
return E(i);
}
}
return {};
}
assert(enum_to_str<Foo::Color>("Red", Foo::kColorStr) == Foo::Red);template <typename... Args>
constexpr std::array<string_view,sizeof...(Args)> string_view::make_literal_array(Args... args) {
return std::array<string_view,sizeof...(Args)>(string_view(args, sizeof(args)-1)...);
}
class Foo {
enum Color { kRed, kGreen, kBlue };
static constexpr auto kColorStr = string_view::make_literal_array("Red", "Green", "Blue");
};constexpr decltype(Foo::kColorStr) Foo::kColorStr;I found this looking for the same problem.
There is just a minor bug with your implementation of make_literal_array :
Args should be passed as forwarding reference (is this the official term?) else the char[] arrays decays into char*
during expansion of the parameter pack, and sizeof(args) will become sizeof(char*) which
may more often than not produce unexpected results.
template <size_t N>
constexpr string_view sv(const char (&literal)[N]) {
return string_view(literal, N - 1);
}
template <size_t... N>
constexpr std::array<string_view, sizeof...(N)> sva(
const char (&... literals)[N]) {
return {{sv(literals)...}};
}
constexpr auto colors = sva("Red", "Green", "Blue");