SPH
EnumMap.h
Go to the documentation of this file.
1 #pragma once
2 
7 
9 #include <typeindex>
10 
12 
13 struct EnumValue {
15  std::string value;
16 
18  std::string desc;
19 };
20 
23 
28 
29 template <typename TEnum>
31  TEnum id;
32  std::string value;
33  std::string desc;
34 };
35 
36 class EnumMap {
37 private:
38  struct CompareEnums {
39  INLINE bool operator()(const EnumIndex& key1, const EnumIndex& key2) const {
40  if (key1 && key2) {
41  return key1.value() < key2.value();
42  } else if (key2) {
43  return true;
44  } else {
45  return false;
46  }
47  }
48  };
49 
51 
52 public:
53  template <typename TEnum>
55  EnumMap& instance = getInstance();
56  // convert enum values to ints to get rid of the type
58  for (auto value : input) {
59  map.insert(int(value.id), EnumValue{ value.value, value.desc });
60  }
61  const EnumIndex index = std::type_index(typeid(TEnum));
62  instance.records.insert(index, std::move(map));
63  return instance;
64  }
65 
66  template <typename TEnum>
67  static std::string toString(const TEnum value) {
68  return toString(int(value), std::type_index(typeid(TEnum)));
69  }
70 
71  static std::string toString(const int value, const EnumIndex& index) {
72  EnumMap& instance = getInstance();
73  Optional<EnumRecord&> record = instance.records.tryGet(index);
74  SPH_ASSERT(record);
75  if (Optional<EnumValue&> e = record->tryGet(value)) {
76  // this is one of the enum values, return the text value
77  return e->value;
78  } else {
79  // the value is not directly in the enum, but can be composed of flags
80  std::string result;
81  for (int i = 1; i <= value; i *= 2) {
82  if ((value & i) == 0) {
83  continue;
84  }
85  Optional<EnumValue&> pair = record->tryGet(i);
86  SPH_ASSERT(pair, i, value);
87  if (!result.empty()) {
88  result += " | ";
89  }
90  result += pair->value;
91  }
92  if (result.empty()) {
93  // empty flags, represent by 0
94  result += '0';
95  }
96  return result;
97  }
98  }
99 
100  template <typename TEnum>
101  static Optional<TEnum> fromString(const std::string& value) {
102  Optional<int> id = fromString(value, std::type_index(typeid(TEnum)));
103  return optionalCast<TEnum>(id);
104  }
105 
106  static Optional<int> fromString(const std::string& value, const EnumIndex& index) {
107  EnumMap& instance = getInstance();
108  Optional<EnumRecord&> record = instance.records.tryGet(index);
109  SPH_ASSERT(record);
110  for (auto pair : record.value()) {
111  if (pair.value.value == value) { // erm ...
112  return pair.key;
113  }
114  }
115  return NOTHING;
116  }
117 
118  template <typename TEnum>
119  static std::string getDesc() {
120  return getDesc(std::type_index(typeid(TEnum)));
121  }
122 
123  static std::string getDesc(const EnumIndex& index) {
124  EnumMap& instance = getInstance();
125  Optional<EnumRecord&> record = instance.records.tryGet(index);
126  SPH_ASSERT(record);
127  std::string desc;
128  Size idx = 0;
129  for (auto pair : record.value()) {
130  if (idx > 0) {
131  desc += "\n";
132  }
133  desc += " - " + pair.value.value + ": " + pair.value.desc;
134  ++idx;
135  }
136  return desc;
137  }
138 
139  template <typename TEnum>
140  static Array<TEnum> getAll() {
141  EnumMap& instance = getInstance();
142  const EnumIndex index = std::type_index(typeid(TEnum));
143  Optional<EnumRecord&> record = instance.records.tryGet(index);
144  SPH_ASSERT(record);
145 
146  Array<TEnum> enums;
147  for (auto pair : record.value()) {
148  enums.push(TEnum(pair.key));
149  }
150  return enums;
151  }
152 
153 
154  static Array<int> getAll(const EnumIndex& index) {
155  EnumMap& instance = getInstance();
156  Optional<EnumRecord&> record = instance.records.tryGet(index);
157  SPH_ASSERT(record);
158 
159  Array<int> enums;
160  for (auto pair : record.value()) {
161  enums.push(pair.key);
162  }
163  return enums;
164  }
165 
166 private:
167  static EnumMap& getInstance() {
168  static EnumMap instance;
169  return instance;
170  }
171 };
172 
174 template <typename TEnum>
175 struct RegisterEnum {
176 public:
178  EnumMap::addEnum(std::move(input));
179  }
180 };
181 
182 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Key-value associative container implemented as a sorted array.
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
const NothingType NOTHING
Definition: Optional.h:16
Generic dynamically allocated resizable storage.
Definition: Array.h:43
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
static Array< TEnum > getAll()
Definition: EnumMap.h:140
static std::string toString(const int value, const EnumIndex &index)
Definition: EnumMap.h:71
static Optional< TEnum > fromString(const std::string &value)
Definition: EnumMap.h:101
static std::string toString(const TEnum value)
Definition: EnumMap.h:67
static std::string getDesc()
Definition: EnumMap.h:119
static std::string getDesc(const EnumIndex &index)
Definition: EnumMap.h:123
static Optional< int > fromString(const std::string &value, const EnumIndex &index)
Definition: EnumMap.h:106
static EnumMap & addEnum(Array< EnumInputValue< TEnum >> &&input)
Definition: EnumMap.h:54
static Array< int > getAll(const EnumIndex &index)
Definition: EnumMap.h:154
Container of key-value pairs.
Definition: FlatMap.h:19
INLINE TValue & insert(const TKey &key, const TValue &value)
Adds a new element into the map or sets new value of element with the same key.
Definition: FlatMap.h:65
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
std::string value
Definition: EnumMap.h:32
TEnum id
Definition: EnumMap.h:31
std::string desc
Definition: EnumMap.h:33
std::string desc
Description.
Definition: EnumMap.h:18
std::string value
Text of the value.
Definition: EnumMap.h:15
Helper class for adding individual enums to the enum map.
Definition: EnumMap.h:175
RegisterEnum(Array< EnumInputValue< TEnum >> &&input)
Definition: EnumMap.h:177