Introduce enum_array_t

Allows for indexing an array via an enum class.
This commit is contained in:
ridiculousfish 2019-02-11 20:23:15 -08:00
parent 78ed659151
commit ccc45235b0
2 changed files with 36 additions and 3 deletions

View File

@ -11,10 +11,17 @@
template <typename T>
struct enum_info_t {};
/// \return the count of an enum.
template <typename T>
class enum_set_t : private std::bitset<static_cast<size_t>(enum_info_t<T>::count)> {
constexpr size_t enum_count() {
return static_cast<size_t>(enum_info_t<T>::count);
}
/// A bit set indexed by an enum type.
template <typename T>
class enum_set_t : private std::bitset<enum_count<T>()> {
private:
using super = std::bitset<static_cast<size_t>(enum_info_t<T>::count)>;
using super = std::bitset<enum_count<T>()>;
static size_t index_of(T t) { return static_cast<size_t>(t); }
explicit enum_set_t(unsigned long raw) : super(raw) {}
@ -43,6 +50,21 @@ class enum_set_t : private std::bitset<static_cast<size_t>(enum_info_t<T>::count
bool operator!=(const enum_set_t &rhs) const { return super::operator!=(rhs); }
};
/// An array of Elem indexed by an enum class.
template <typename Elem, typename T>
class enum_array_t : public std::array<Elem, enum_count<T>()> {
using super = std::array<Elem, enum_count<T>()>;
using base_type_t = typename std::underlying_type<T>::type;
static int index_of(T t) { return static_cast<base_type_t>(t); }
public:
Elem &at(T t) { return super::at(index_of(t)); }
const Elem &at(T t) const { return super::at(index_of(t)); }
Elem &operator[](T t) { return super::operator[](index_of(t)); }
const Elem &operator[](T t) const { return super::operator[](index_of(t)); }
};
/// A counting iterator for an enum class.
/// This enumerates the values of an enum class from 0 up to (not including) count.
/// Example:
@ -81,5 +103,5 @@ class enum_iter_t {
public:
iterator_t begin() const { return iterator_t{0}; }
iterator_t end() const { return iterator_t{static_cast<base_type_t>(enum_info_t<T>::count)}; }
iterator_t end() const { return iterator_t{static_cast<base_type_t>(enum_count<T>())}; }
};

View File

@ -318,6 +318,16 @@ static void test_enum_set() {
do_test(static_cast<unsigned>(test_enum::COUNT) == idx);
}
static void test_enum_array() {
say(L"Testing enum array");
enum_array_t<std::string, test_enum> es{};
do_test(es.size() == enum_count<test_enum>());
es[test_enum::beta] = "abc";
do_test(es[test_enum::beta] == "abc");
es.at(test_enum::gamma) = "def";
do_test(es.at(test_enum::gamma) == "def");
}
/// Test sane escapes.
static void test_unescape_sane() {
const struct test_t {
@ -5115,6 +5125,7 @@ int main(int argc, char **argv) {
if (should_test_function("env_vars")) test_env_vars();
if (should_test_function("str_to_num")) test_str_to_num();
if (should_test_function("enum")) test_enum_set();
if (should_test_function("enum")) test_enum_array();
if (should_test_function("highlighting")) test_highlighting();
if (should_test_function("new_parser_ll2")) test_new_parser_ll2();
if (should_test_function("new_parser_fuzzing"))