Euphoria
enum.cc
Go to the documentation of this file.
1 #include "core/enum.h"
2 
3 #include <iostream>
4 #include <set>
5 #include <utility>
6 
7 #include "assert/assert.h"
8 
9 #include "log/log.h"
10 
11 #include "base/stringmerger.h"
12 #include "base/stringutils.h"
13 
14 #include "files/enum.h"
15 #include "io/vfs_path.h"
16 
17 
18 #ifdef assert
19 #undef assert
20 #endif
21 
22 
23 
24 namespace eu::core
25 {
26  EnumType::EnumType(std::string name)
27  : type_name(std::move(name))
28  , is_adding(true)
29  , next_index(1)
30  {
31  }
32 
33 
35  {
36  ASSERT(!is_adding);
37  }
38 
39 
40  std::string
41  EnumType::to_string(size_t v) const
42  {
43  ASSERT(v < next_index);
44  auto f = value_to_name.find(v);
45  if(f != value_to_name.end())
46  {
47  return f->second;
48  }
49 
50  // ASSERT(false && "Invalid index");
51  const auto values = string_mergers::english_or.merge
52  (
54  );
55 
56  return fmt::format("<invalid value {} of {}>", v, values);
57  }
58 
59 
60  EnumValue
61  EnumType::to_enum(const std::string& name)
62  {
63  auto r = name_to_value.find(name);
64  if(r != name_to_value.end())
65  {
66  return {this, r->second};
67  }
68 
69  if(!is_adding)
70  {
71  LOG_ERROR("Enum value doesnt exist, {0}", name);
72  return {this, 0};
73  }
74  const size_t id = next_index;
75  add_enum(name);
76  return {this, id};
77  }
78 
79 
80  void
81  EnumType::add_enums(const std::vector<std::string>& names)
82  {
84  std::set<std::string> valid_names;
85  for(const auto& name: names)
86  {
87  add_enum(name);
88  valid_names.insert(name);
89  }
90 
91  // validate all names against true names
92  for(const auto& name: name_to_value)
93  {
94  const bool missing
95  = valid_names.find(name.first) == valid_names.end();
96  if(missing)
97  {
98  LOG_ERROR
99  (
100  "Enum {0} was registered with name {1} but that is invalid.",
101  type_name,
102  name.first
103  );
104  }
105  }
106 
107  is_adding = false;
108  }
109 
110 
111  void
112  EnumType::add_enum(const std::string& name)
113  {
114  ASSERT(is_adding);
115  auto r = name_to_value.find(name);
116  if(r != name_to_value.end())
117  {
118  return;
119  }
120  const size_t id = next_index;
121  ++next_index;
122  value_to_name.insert(ValueToNameMap::value_type(id, name));
123  name_to_value.insert(NameToValueMap::value_type(name, id));
124  }
125 
126 
127 
129  // Enum Value
130 
132  : type(t)
133  , value(v)
134  {
135  }
136 
137 
138  std::string
140  {
141  return type->to_string(value);
142  }
143 
144 
145  size_t
147  {
148  return value;
149  }
150 
151 
152  bool
153  EnumValue::operator==(const EnumValue& other) const
154  {
155  ASSERT(type == other.type);
156  return value == other.value;
157  }
158 
159 
160  bool
161  EnumValue::operator!=(const EnumValue& other) const
162  {
163  return !(*this == other);
164  }
165 
166 
167  bool
168  EnumValue::operator<(const EnumValue& other) const
169  {
170  ASSERT(type == other.type);
171  return value < other.value;
172  }
173 
174 
175  std::string to_string(const EnumValue& v)
176  {
177  return v.to_string();
178  }
179 
180 
181  void
183  (
184  EnumType* type,
185  io::FileSystem* fs,
186  const io::FilePath& path
187  )
188  {
189  ASSERT(type);
190 
191  const auto loaded = read_json_file(fs, path);
192  if (!loaded)
193  {
194  // todo(Gustav): handle enum errors better...
195  LOG_ERROR("failed to read {}: {}", path, loaded.get_error().display);
196  return;
197  }
198 
199  files::enums::Root root;
200  const auto& json = loaded.get_value();
201 
202  if (false == files::enums::parse(log::get_global_logger(), &root, json.root, &json.doc))
203  {
204  return;
205  }
206 
207  type->add_enums(root.names);
208  }
209 
210 }
#define ASSERT(x)
Definition: assert.h:29
std::vector< std::string > to_string_vector(const std::map< TKey, TValue > &map)
Definition: stringutils.h:164
#define LOG_ERROR(...)
Definition: log.h:9
std::string to_string(const EnumValue &v)
Definition: enum.cc:175
void load_enum_type(EnumType *type, io::FileSystem *fs, const io::FilePath &path)
Definition: enum.cc:183
JsonResult read_json_file(FileSystem *fs, const FilePath &file_name)
Definition: json.cc:58
Logger * get_global_logger()
Definition: log.cc:34
constexpr StringMerger english_or
Definition: stringmerger.h:90
String utility functions.
std::string merge(const std::vector< std::string > &strings) const
Definition: stringmerger.cc:11
Represents a dynamically loaded "enum type".
Definition: enum.h:28
NameToValueMap name_to_value
Definition: enum.h:34
EnumValue to_enum(const std::string &name)
Definition: enum.cc:61
void add_enum(const std::string &name)
Definition: enum.cc:112
void add_enums(const std::vector< std::string > &names)
Definition: enum.cc:81
std::string type_name
Definition: enum.h:32
EnumType(std::string name)
Definition: enum.cc:26
bool is_adding
Definition: enum.h:35
std::string to_string(size_t v) const
Definition: enum.cc:41
ValueToNameMap value_to_name
Definition: enum.h:33
size_t next_index
Definition: enum.h:36
EnumType * type
Definition: enum.h:56
size_t to_value() const
Definition: enum.cc:146
bool operator<(const EnumValue &other) const
Definition: enum.cc:168
bool operator==(const EnumValue &other) const
Definition: enum.cc:153
bool operator!=(const EnumValue &other) const
Definition: enum.cc:161
EnumValue(EnumType *t, size_t v)
Definition: enum.cc:131
std::string to_string() const
Definition: enum.cc:139
size_t value
Definition: enum.h:57
std::vector< std::string > names
Definition: enum.h:9