1 #pragma once
2 
3 #include <mbgl/util/optional.hpp>
4 
5 #include <algorithm>
6 #include <cassert>
7 #include <string>
8 
9 namespace mbgl {
10 
11 template <typename T>
12 class Enum {
13 public:
14     using Type = T;
15     static const char * toString(T);
16     static optional<T> toEnum(const std::string&);
17 };
18 
19 #define MBGL_DEFINE_ENUM(T, values...)                                          \
20                                                                                 \
21 static const constexpr std::pair<const T, const char *> T##_names[] = values;   \
22                                                                                 \
23 template <>                                                                     \
24 const char * Enum<T>::toString(T t) {                                           \
25     auto it = std::find_if(std::begin(T##_names), std::end(T##_names),          \
26         [&] (const auto& v) { return t == v.first; });                          \
27     assert(it != std::end(T##_names)); return it->second;                       \
28 }                                                                               \
29                                                                                 \
30 template <>                                                                     \
31 optional<T> Enum<T>::toEnum(const std::string& s) {                             \
32     auto it = std::find_if(std::begin(T##_names), std::end(T##_names),          \
33         [&] (const auto& v) { return s == v.second; });                         \
34     return it == std::end(T##_names) ? optional<T>() : it->first;               \
35 }
36 
37 } // namespace mbgl
38