Euphoria
enumtostring.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 #include <map>
5 #include <type_traits>
6 
7 
8 #include "assert/assert.h"
9 
10 #include "base/stringutils.h"
12 
13 #include "magic_enum/magic_enum.hpp"
14 
15 
16 namespace eu
17 {
18  template <typename T>
19  struct MatchedEnum
20  {
21  bool single_match = false;
22  std::vector<std::string> names;
23  std::vector<T> values;
24  };
25 
26  template <typename T>
28  {
29  std::map<T, std::string> enum_to_string;
30  std::map<std::string, T> string_to_enum;
31  int size = 0;
32 
33  // todo(Gustav): replace with initializer list?
35  add(const std::string& name, T t)
36  {
37  enum_to_string.insert(std::make_pair(t, name));
38  string_to_enum.insert(std::make_pair(to_lower(name), t));
39  size += 1;
40  return *this;
41  }
42 
43  [[nodiscard]] std::string to_string(T t) const
44  {
45  auto found = enum_to_string.find(t);
46  if(found != enum_to_string.end())
47  {
48  return found->second;
49  }
50  DIE("Enum not added");
51  return "???";
52  }
53 
54  [[nodiscard]] MatchedEnum<T>
55  match(const std::string& input, size_t max_size) const
56  {
57  auto found = string_to_enum.find(to_lower(input));
58  if(found != string_to_enum.end())
59  {
60  return MatchedEnum<T> {true, {input}, {found->second}};
61  }
62 
63  struct Match : search::Match
64  {
65  T t;
66 
67  Match(const std::string& str, T tt, const std::string& input)
68  : search::Match(str, input)
69  , t(tt)
70  {
71  }
72  };
73 
74  const auto matches = search::find_closest<Match>
75  (
76  max_size, enum_to_string,
77  [&](const auto& entry) -> Match
78  {
79  return {entry.second, entry.first, input};
80  }
81  );
82 
83  auto ret = MatchedEnum<T> {};
84  for(const auto& m: matches)
85  {
86  ret.names.emplace_back(m.name);
87  ret.values.emplace_back(m.t);
88  }
89  return ret;
90  }
91 
92  [[nodiscard]] std::vector<std::string>
94  {
95  std::vector<std::string> ret;
96  for(auto entry: enum_to_string)
97  {
98  ret.emplace_back(entry.second);
99  }
100  return ret;
101  }
102 
103  [[nodiscard]] std::vector<T>
105  {
106  std::vector<T> ret;
107  for(auto entry: enum_to_string)
108  {
109  ret.emplace_back(entry.first);
110  }
111  return ret;
112  }
113  };
114 
115  template <typename T>
116  [[nodiscard]] std::string from_enum_to_string(T t)
117  {
118  return std::string{ magic_enum::enum_name(t) };
119  }
120 
121  template<typename T>
122  [[nodiscard]] EnumToStringImplementation<T>
124  {
125  const auto values = magic_enum::enum_values<T>();
126 
128  for (const auto v : values)
129  {
130  r.add(from_enum_to_string(v), v);
131  }
132 
133  return r;
134  }
135 
136 
137  template <typename T>
138  MatchedEnum<T>
139  from_string_to_enum(const std::string& input, size_t max_size = 5)
140  {
141  return get_enum_to_string_implementation_from_enum<T>().match(input, max_size);
142  }
143 
144 
145  template <typename T>
146  [[nodiscard]] std::vector<std::string>
147  from_enum_to_string(const std::vector<T>& ts)
148  {
149  std::vector<std::string> ret;
150  for(auto t: ts)
151  {
152  ret.emplace_back(from_enum_to_string<T>(t));
153  }
154  return ret;
155  }
156 
157 
158  template <typename T>
159  [[nodiscard]] std::vector<std::string>
161  {
162  return get_enum_to_string_implementation_from_enum<T>().get_list_of_names();
163  }
164 
165  template <typename T>
166  [[nodiscard]] std::vector<T>
168  {
169  const auto values = magic_enum::enum_values<T>();
170  return values;
171  }
172 }
173 
174 using namespace magic_enum::ostream_operators; // NOLINT
175 
176 
177 template<typename TEnum>
178 struct fmt::formatter
179  <
180  TEnum,
181  char,
182  std::enable_if_t<std::is_enum_v<TEnum>, void>
183  >
184  : fmt::formatter<std::string>
185 {
186  template <typename FormatContext>
187  auto format(const TEnum& e, FormatContext& ctx) const
188  {
189  const auto str = eu::from_enum_to_string<TEnum>(e);
190  return fmt::formatter<std::string>::format(str, ctx);
191  }
192 };
#define DIE(message)
Definition: assert.h:67
std::string to_lower(const std::string &str)
Generate a string containing only lower characters.
Definition: stringutils.cc:143
Definition: assert.h:90
std::string from_enum_to_string(T t)
Definition: enumtostring.h:116
MatchedEnum< T > from_string_to_enum(const std::string &input, size_t max_size=5)
Definition: enumtostring.h:139
std::vector< T > get_all_values_from_enum()
Definition: enumtostring.h:167
EnumToStringImplementation< T > get_enum_to_string_implementation_from_enum()
Definition: enumtostring.h:123
std::vector< std::string > get_all_names_from_enum()
Definition: enumtostring.h:160
String utility functions.
EnumToStringImplementation< T > & add(const std::string &name, T t)
Definition: enumtostring.h:35
std::map< T, std::string > enum_to_string
Definition: enumtostring.h:29
MatchedEnum< T > match(const std::string &input, size_t max_size) const
Definition: enumtostring.h:55
std::vector< T > get_list_of_values() const
Definition: enumtostring.h:104
std::map< std::string, T > string_to_enum
Definition: enumtostring.h:30
std::string to_string(T t) const
Definition: enumtostring.h:43
std::vector< std::string > get_list_of_names() const
Definition: enumtostring.h:93
std::vector< T > values
Definition: enumtostring.h:23
std::vector< std::string > names
Definition: enumtostring.h:22