1 // Copyright 2015 The Weave Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef LIBWEAVE_INCLUDE_WEAVE_ENUM_TO_STRING_H_
6 #define LIBWEAVE_INCLUDE_WEAVE_ENUM_TO_STRING_H_
7 
8 #include <string>
9 
10 #include <base/logging.h>
11 
12 namespace weave {
13 
14 // Helps to map enumeration to stings and back.
15 //
16 // Usage example:
17 // .h file:
18 // enum class MyEnum { kV1, kV2 };
19 //
20 // .cc file:
21 // template <>
22 // EnumToStringMap<MyEnum>::EnumToStringMap() : EnumToStringMap(kMap) { };
23 template <typename T>
24 class EnumToStringMap final {
25   static_assert(std::is_enum<T>::value, "The type must be an enumeration");
26 
27  public:
28   struct Map {
29     const T id;
30     const char* const name;
31   };
32 
33   EnumToStringMap();
34 
begin()35   const Map* begin() const { return begin_; }
end()36   const Map* end() const { return end_; }
37 
38  private:
39   template <size_t size>
EnumToStringMap(const Map (& map)[size])40   explicit EnumToStringMap(const Map (&map)[size])
41       : begin_(map), end_(map + size) {}
42 
43   const Map* begin_;
44   const Map* end_;
45 };
46 
47 template <typename T>
EnumToString(T id)48 std::string EnumToString(T id) {
49   for (const auto& m : EnumToStringMap<T>()) {
50     if (m.id == id) {
51       CHECK(m.name);
52       return m.name;
53     }
54   }
55   NOTREACHED() << static_cast<int>(id);
56   return std::string();
57 }
58 
59 template <typename T>
StringToEnum(const std::string & name,T * id)60 bool StringToEnum(const std::string& name, T* id) {
61   for (const auto& m : EnumToStringMap<T>()) {
62     if (m.name && m.name == name) {
63       *id = m.id;
64       return true;
65     }
66   }
67   return false;
68 }
69 
70 }  // namespace weave
71 
72 #endif  // LIBWEAVE_INCLUDE_WEAVE_ENUM_TO_STRING_H_
73