summaryrefslogtreecommitdiff
path: root/include/mbgl/util/enum.hpp
blob: 5d67e394ba0a45dbc6b1cde9fcff5d6751760e26 (plain)
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
#pragma once

#include <mbgl/util/optional.hpp>

#include <algorithm>
#include <cassert>
#include <string>

namespace mbgl {

template <typename T>
class Enum {
public:
    using Type = T;
    static const char* toString(T);
    static optional<T> toEnum(const std::string&);
};

#define MBGL_DEFINE_ENUM(T, ...)                                                                   \
                                                                                                   \
    static const constexpr std::pair<const T, const char*> T##_names[] = values;                   \
                                                                                                   \
    template <>                                                                                    \
    const char* Enum<T>::toString(T t) {                                                           \
        auto it = std::find_if(std::begin(T##_names), std::end(T##_names),                         \
                               [&](const auto& v) { return t == v.first; });                       \
        assert(it != std::end(T##_names));                                                         \
        return it->second;                                                                         \
    }                                                                                              \
                                                                                                   \
    template <>                                                                                    \
    optional<T> Enum<T>::toEnum(const std::string& s) {                                            \
        auto it = std::find_if(std::begin(T##_names), std::end(T##_names),                         \
                               [&](const auto& v) { return s == v.second; });                      \
        return it == std::end(T##_names) ? optional<T>() : it->first;                              \
    }

} // namespace mbgl