#pragma once #include #include #include #include #include namespace mln { template class Enum { public: using Type = T; static const char* toString(T); static std::optional toEnum(const std::string&); }; #define MBGL_DEFINE_ENUM(T, ...) \ \ static const constexpr std::pair T##_names[] = __VA_ARGS__; \ \ template <> \ const char* Enum::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 <> \ std::optional Enum::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) ? std::optional() : it->first; \ } } // namespace mln