From 2d08a533d13930e81c5b34a961e8b2efc5e6ba4f Mon Sep 17 00:00:00 2001 From: Charles Dang Date: Fri, 27 May 2022 22:58:48 -0400 Subject: [PATCH] Refined string_enum - Cleaned up code and documentation - Made both overloads of get_enum constexpr (one now takes a string_view instead of a string) - Used type deduction for the values array. For existing uses this will deduce the same as before (const char*) This also means it's not explicit, and some classes can use string_view. --- src/enum_base.hpp | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/enum_base.hpp b/src/enum_base.hpp index 53c3c2de373..70fc6589757 100644 --- a/src/enum_base.hpp +++ b/src/enum_base.hpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include namespace string_enums @@ -30,48 +30,52 @@ namespace string_enums template struct enum_base : public T { + using enum_type = typename T::type; + // check that all implementations of this are scoped enums - static_assert(std::is_enum::value && !std::is_convertible::value, "Enum is not a scoped enum"); + // TODO: C++23 std::is_scoped_enum + static_assert(std::is_enum_v && !std::is_convertible_v, "Enum is not a scoped enum"); /** - * Uses the int value of the provided enum to get the associated index of the @a values array in the implementing class. + * Converts a enum to its string equivalent. * - * @param key The enum value to get the equivalent string for. - * @return The string value associated to the enum value. + * @param key The enum value to get the equivalent string for. + * @return The string value associated with the enum value. */ - static std::string get_string(typename T::type key) + static std::string get_string(enum_type key) { return std::string{T::values[static_cast(key)]}; } /** - * Convert a string into its enum equivalent. + * Converts a string into its enum equivalent. * - * @param value The string value to convert. - * @return The equivalent enum or std::nullopt. + * @param value The string value to convert. + * @return The equivalent enum or std::nullopt. */ - static std::optional get_enum(const std::string value) + static constexpr std::optional get_enum(const std::string_view value) { - for(unsigned int i = 0; i < T::values.size(); i++) { + for(unsigned int i = 0; i < size(); i++) { if(value == T::values[i]) { - return static_cast(i); + return static_cast(i); } } return std::nullopt; } /** - * Convert an int into its enum equivalent. + * Converts an int into its enum equivalent. * - * @param value The string value to convert. - * @return The equivalent enum or std::nullopt. + * @param value The string value to convert. + * @return The equivalent enum or std::nullopt. */ - static std::optional get_enum(unsigned long value) + static constexpr std::optional get_enum(unsigned long value) { - if(value < T::values.size()) { - return static_cast(value); + if(value < size()) { + return static_cast(value); + } else { + return std::nullopt; } - return std::nullopt; } /** @@ -85,11 +89,10 @@ struct enum_base : public T #define ENUM_AND_ARRAY(...) \ enum class type { __VA_ARGS__ }; \ + static constexpr std::array values{__VA_ARGS__}; \ \ /** Provide a alias template for an array of matching size. */ \ template \ - using sized_array = std::array::value>; \ - \ - static constexpr sized_array values{__VA_ARGS__}; + using sized_array = std::array; } // namespace string_enums