From 282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 10 Jun 2016 21:17:23 -0700 Subject: =?UTF-8?q?[core]=20Make=20enum=20=E2=86=94=20string=20conversion?= =?UTF-8?q?=20more=20generic-friendly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite enum.hpp in such a way that parseConstant can be defined generically for all enumerated types. While there, properly validated enumerated property values. --- include/mbgl/util/enum.hpp | 60 +++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) (limited to 'include/mbgl/util/enum.hpp') diff --git a/include/mbgl/util/enum.hpp b/include/mbgl/util/enum.hpp index 3fbf313aed..48ffda463e 100644 --- a/include/mbgl/util/enum.hpp +++ b/include/mbgl/util/enum.hpp @@ -1,52 +1,36 @@ #pragma once -#include +#include + +#include +#include #include namespace mbgl { -template -struct EnumValue { - const Type value; - const char *name; -}; - -template *names, const size_t length> -struct Enum { - using Type = EnumName; - Type value; - static const constexpr size_t l = length; -private: - static constexpr inline bool compare(const char *a, const char *b) { - return *a == *b && (*a == '\0' || compare(a + 1, b + 1)); - } - static constexpr inline const char *lookup_type(Type e, EnumValue const * const list, size_t r) { - return r == 0 ? "" : list->value == e ? list->name : lookup_type(e, list + 1, r - 1); - } - static constexpr inline Type lookup_name(const char *n, EnumValue const * const list, size_t r) { - return r == 0 ? Type(-1) : compare(list->name, n) ? list->value : lookup_name(n, list + 1, r - 1); - } +template +class Enum { public: - inline constexpr Enum(const char *n) : value(lookup_name(n, names, length)) {} - inline constexpr Enum(const std::string &n) : value(lookup_name(n.c_str(), names, length)) {} - inline constexpr Enum(Type t) : value(t) {} - - inline void operator=(const char *n) { value = lookup_name(n, names, length); } - inline void operator=(const std::string &n) { *this = n.c_str(); } - inline void operator=(Type t) { value = t; } + using Value = std::pair; - inline constexpr bool valid() const { return value != Type(-1); } + static const char * toString(T t) { + auto it = std::find_if(begin, end, [&] (const auto& v) { return t == v.first; }); + assert(it != end); return it->second; + } - inline constexpr const char *c_str() const { return lookup_type(value, names, length); } - inline std::string str() const { return c_str(); } + static optional toEnum(const std::string& s) { + auto it = std::find_if(begin, end, [&] (const auto& v) { return s == v.second; }); + return it == end ? optional() : it->first; + } - inline constexpr operator Type() const { return value; } +private: + static const Value* begin; + static const Value* end; }; -#define MBGL_DEFINE_ENUM_CLASS(name, type, strings...) \ - const constexpr ::mbgl::EnumValue type##_names[] = strings; \ - using name = ::mbgl::Enum)>; \ - inline std::ostream& operator<<(std::ostream& os, type t) { return os << name(t).str(); } +#define MBGL_DEFINE_ENUM(type, strings...) \ +const constexpr Enum::Value type##_names[] = strings; \ +template <> const Enum::Value* Enum::begin = std::begin(type##_names); \ +template <> const Enum::Value* Enum::end = std::end(type##_names) } // namespace mbgl - -- cgit v1.2.1