1 #pragma once
2 #include <string>
3 #include <map>
4 #include <optional>
5 
6 namespace horizon {
7 
8 /**
9  * Trivial bidirectional map for mapping strings to enums.
10  * Used for serializing and derserializing objects to/from json.
11  */
12 template <typename T> class LutEnumStr {
13     static_assert(std::is_enum<T>::value, "Must be an enum type");
14 
15 public:
LutEnumStr(std::initializer_list<std::pair<const std::string,const T>> s)16     LutEnumStr(std::initializer_list<std::pair<const std::string, const T>> s)
17     {
18         for (auto it : s) {
19             fwd.insert(it);
20             rev.insert(std::make_pair(it.second, it.first));
21         }
22     }
23     /**
24      * @returns the enum corresponding to string \p s
25      */
lookup(const std::string & s) const26     const T lookup(const std::string &s) const
27     {
28         return fwd.at(s);
29     }
30 
lookup_opt(const std::string & s) const31     const std::optional<T> lookup_opt(const std::string &s) const
32     {
33         if (fwd.count(s))
34             return fwd.at(s);
35         else
36             return {};
37     }
38 
lookup(const std::string & s,T def) const39     const T lookup(const std::string &s, T def) const
40     {
41         if (fwd.count(s))
42             return fwd.at(s);
43         else
44             return def;
45     }
46 
47     /**
48      * @returns the string corresponding to enum \p s
49      */
lookup_reverse(const T s) const50     const std::string &lookup_reverse(const T s) const
51     {
52         return rev.at(s);
53     }
54 
55 private:
56     std::map<std::string, T> fwd;
57     std::map<T, std::string> rev;
58 };
59 } // namespace horizon
60