UBC-Thunderbots / Software

Robot Soccer Playing AI
http://www.ubcthunderbots.ca
GNU Lesser General Public License v3.0
47 stars 98 forks source link

Update `MAKE_ENUM` to generate compile-time, template-friendly reflective enum #3241

Closed williamckha closed 9 hours ago

williamckha commented 4 days ago

Description

MAKE_ENUM currently generates functions with custom names that cannot be accessed in templates:

MAKE_ENUM(MyEnum, FOO, BAR, BAZ);

std::vector<MyEnum> values = allValuesMyEnum(); // This is OK

template <typename E>
struct MyClass
{
    std::vector<E> values = ??? // No way to access allValues of enum E
}

This PR changes MAKE_ENUM to emit specializations for templated functions under the namespace reflective_enum. These templated functions accept the enum type as an argument and can be used in templates without issue. All enum value arrays and string arrays are evaluated at compile time and can be used in constexpr functions and variables.

MAKE_ENUM(MyEnum, FOO, BAR, BAZ);

static_assert(reflective_enum::is_reflective_enum<FooEnum>::value); // True

constexpr size_t enum_size = reflective_enum::size<MyEnum>(); // Returns num of values in MyEnum
constexpr auto values = reflective_enum::values<MyEnum>(); // Returns array of all MyEnum values
constexpr auto value_names = reflective_enum::valueNames<MyEnum>(); // Returns array of string representations of MyEnum values
constexpr MyEnum value = reflective_enum::fromName<MyEnum>("FOO"); // value holds MyEnum::FOO

LOG(INFO) << value; // Prints "FOO"

We require enums with reflection for the Q-learning PR #3210

Testing Done

Added and updated tests in make_enum_test.cpp

Resolved Issues

Length Justification and Key Files to Review

Review Checklist

It is the reviewers responsibility to also make sure every item here has been covered