diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-10 21:17:23 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-13 17:22:05 -0700 |
commit | 282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a (patch) | |
tree | f83ef7974687a84341dd616b364b2aa5a9c012a8 /include/mbgl/util/enum.hpp | |
parent | 36bef2157595e1455aa55c64c6c526f096dd1c8e (diff) | |
download | qtlocation-mapboxgl-282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a.tar.gz |
[core] Make enum ↔ string conversion more generic-friendly
Rewrite enum.hpp in such a way that parseConstant can be defined generically for all enumerated types.
While there, properly validated enumerated property values.
Diffstat (limited to 'include/mbgl/util/enum.hpp')
-rw-r--r-- | include/mbgl/util/enum.hpp | 60 |
1 files changed, 22 insertions, 38 deletions
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 <iosfwd> +#include <mbgl/util/optional.hpp> + +#include <algorithm> +#include <cassert> #include <string> namespace mbgl { -template <typename Type> -struct EnumValue { - const Type value; - const char *name; -}; - -template <typename EnumName, const EnumValue<EnumName> *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<Type> 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<Type> 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 <typename T> +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<const T, const char *>; - 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<T> toEnum(const std::string& s) { + auto it = std::find_if(begin, end, [&] (const auto& v) { return s == v.second; }); + return it == end ? optional<T>() : 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> type##_names[] = strings; \ - using name = ::mbgl::Enum<type, type##_names, sizeof(type##_names) / sizeof(::mbgl::EnumValue<type>)>; \ - inline std::ostream& operator<<(std::ostream& os, type t) { return os << name(t).str(); } +#define MBGL_DEFINE_ENUM(type, strings...) \ +const constexpr Enum<type>::Value type##_names[] = strings; \ +template <> const Enum<type>::Value* Enum<type>::begin = std::begin(type##_names); \ +template <> const Enum<type>::Value* Enum<type>::end = std::end(type##_names) } // namespace mbgl - |