1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#ifndef MBGL_UTIL_ENUM
#define MBGL_UTIL_ENUM
#include <iosfwd>
#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);
}
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; }
inline constexpr bool valid() const { return value != Type(-1); }
inline constexpr const char *c_str() const { return lookup_type(value, names, length); }
inline std::string str() const { return c_str(); }
inline constexpr operator Type() const { return value; }
};
#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(); }
} // namespace mbgl
#endif
|