$darkmode
enum.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
23 #pragma once
24 #ifndef FABLE_ENUM_HPP_
25 #define FABLE_ENUM_HPP_
26 
27 #include <map> // for map<>
28 #include <string> // for string
29 #include <type_traits> // for enable_if_t<>, is_enum<>
30 #include <utility> // for make_pair, move
31 
32 #include <fable/json.hpp>
33 
52 #define ENUM_SERIALIZATION(xType, xMap) \
53  inline const std::map<xType, std::string>& enum_serialization(xType) { \
54  static std::map<xType, std::string> data xMap; \
55  return data; \
56  } \
57  inline const std::map<std::string, xType>& enum_deserialization(xType) { \
58  static const std::map<std::string, xType> data = ::fable::invert(enum_serialization(xType())); \
59  return data; \
60  } \
61  inline void to_json(::fable::Json& j, const xType& v) { j = enum_serialization(v).at(v); } \
62  inline void from_json(const ::fable::Json& j, xType& v) { \
63  v = enum_deserialization(v).at(j.get<std::string>()); \
64  }
65 
66 #define FABLE_ENUM_SERIALIZATION(xType, xMap) \
67  namespace fable { \
68  template <> \
69  struct EnumSerializer<xType> { \
70  static const std::map<xType, std::string>& serialization() { \
71  static const std::map<xType, std::string> ser xMap; \
72  return ser; \
73  } \
74  static const std::map<std::string, xType>& deserialization() { \
75  static std::map<std::string, xType> de = \
76  ::fable::invert(EnumSerializer<xType>::serialization()); \
77  return de; \
78  } \
79  }; \
80  } \
81  namespace nlohmann { \
82  template <> \
83  struct adl_serializer<xType> { \
84  static void to_json(json& j, const xType& e) { j = ::fable::to_string(e); } \
85  static void from_json(const json& j, xType& e) { \
86  e = ::fable::from_string<xType>(j.get<std::string>()); \
87  } \
88  }; \
89  }
90 
91 namespace fable {
92 
101 template <typename X, typename Y>
102 std::map<Y, X> invert(const std::map<X, Y>& m) {
103  std::map<Y, X> m_prime;
104  for (const auto& kv : m) {
105  m_prime.insert(std::make_pair(kv.second, kv.first));
106  }
107  return m_prime;
108 }
109 
110 template <typename T>
112  // Implement:
113  // static const std::map<T, std::string>& serialization();
114 
115  // Implement:
116  // static const std::map<std::string, T>& deserialization();
117 };
118 
119 template <typename T>
121  using one = char;
122  using two = struct { char x[2]; };
123 
124  template <typename C>
125  static one test(decltype(&::fable::EnumSerializer<C>::serialization));
126  template <typename C>
127  static two test(...);
128 
129  public:
130  enum { value = sizeof(test<T>(0)) == sizeof(one) };
131 };
132 
133 template <typename T, bool EnumSerializerPresent>
135 
136 template <typename T>
137 struct EnumSerializerImpl<T, true> {
138  static const std::map<T, std::string>& serialization_impl() {
140  }
141  static const std::map<std::string, T>& deserialization_impl() {
143  }
144 };
145 
146 template <typename T>
147 struct EnumSerializerImpl<T, false> {
148  static const std::map<T, std::string>& serialization_impl() { return enum_serialization(T()); }
149  static const std::map<std::string, T>& deserialization_impl() {
150  return enum_deserialization(T());
151  }
152 };
153 
154 template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
155 const std::map<T, std::string>& enum_serialization() {
156  return EnumSerializerImpl<T, has_enum_serializer<T>::value>::serialization_impl();
157 }
158 
159 template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
160 const std::map<std::string, T>& enum_deserialization() {
161  return EnumSerializerImpl<T, has_enum_serializer<T>::value>::deserialization_impl();
162 }
163 
164 template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
165 std::string to_string(T x) {
166  return enum_serialization<T>().at(x);
167 }
168 
169 template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
170 T from_string(const std::string& s) {
171  return enum_deserialization<T>().at(s);
172 }
173 
174 } // namespace fable
175 
176 #endif // FABLE_ENUM_HPP_
Definition: enum.hpp:120
std::map< Y, X > invert(const std::map< X, Y > &m)
Definition: enum.hpp:102
Definition: conf.hpp:70
Definition: enum.hpp:111
Definition: enum.hpp:134