Skip to content

Commit c4b2f25

Browse files
committed
add EnumIndexedArray::for_each2 with 2-arg callback
1 parent 85ddb53 commit c4b2f25

2 files changed

Lines changed: 58 additions & 21 deletions

File tree

src/global/EnumIndexedArray.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,29 @@ class NODISCARD EnumIndexedArray : private MMapper::Array<T, SIZE_>
8282
callback(x);
8383
}
8484
}
85+
template<typename Callback>
86+
void for_each(Callback &&callback) const
87+
{
88+
for (const auto &x : *this) {
89+
callback(x);
90+
}
91+
}
92+
template<typename Callback>
93+
void for_each2(Callback &&callback)
94+
{
95+
for (size_t i = 0u; i < SIZE; ++i) {
96+
const auto e = static_cast<E>(i);
97+
callback(e, at(e));
98+
}
99+
}
100+
template<typename Callback>
101+
void for_each2(Callback &&callback) const
102+
{
103+
for (size_t i = 0u; i < SIZE; ++i) {
104+
const auto e = static_cast<E>(i);
105+
callback(e, at(e));
106+
}
107+
}
85108

86109
public:
87110
NODISCARD bool operator==(const EnumIndexedArray &other) const

src/mapstorage/XmlMapStorage.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939

4040
// clang-format off
4141

42-
4342
// ---------------------------- XmlMapStorage::TypeEnum ------------------------
4443
// list know enum types
4544
//
@@ -101,6 +100,11 @@ enum class NODISCARD TypeEnum : uint32_t {
101100
constexpr const size_t NUM_XMLMAPSTORAGE_TYPE = (XFOREACH_TYPE_ENUM(X_ADD));
102101
#undef X_ADD
103102

103+
NODISCARD bool isValid(const TypeEnum type)
104+
{
105+
return static_cast<uint32_t>(type) < NUM_XMLMAPSTORAGE_TYPE;
106+
}
107+
104108
#define X_SEP() ,
105109
#define X_DECL(_x, _xfor, _xdecl) _x
106110
enum class NODISCARD SanityCheckEnum : uint32_t { XFOREACH_CONVERTER(X_DECL, X_SEP) };
@@ -115,6 +119,14 @@ XFOREACH_CONVERTER(X_CHECK, X_SEP);
115119
#undef X_CHECK
116120
#undef X_SEP
117121

122+
#define X_SEP()
123+
#define X_ADD(_x, _xfor, _xdecl) +1 // NOLINT
124+
constexpr const size_t NUM_SANITYCHECK = (XFOREACH_CONVERTER(X_ADD, X_SEP));
125+
#undef X_ADD
126+
#undef X_SEP
127+
128+
static_assert(NUM_SANITYCHECK == NUM_XMLMAPSTORAGE_TYPE);
129+
118130
// define a bunch of methods
119131
// static constexpr TypeEnum enumToType(RoomAlignEnum) { return TypeEnum::RoomAlign; }
120132
// static constexpr TypeEnum enumToType(DoorFlagEnum) { return TypeEnum::DoorFlag; }
@@ -153,15 +165,20 @@ static_assert(to_c_string(TypeEnum::RoomAlign) == std::string_view{"RoomAlignEnu
153165
static_assert(to_c_string(TypeEnum::RoomTerrain) == std::string_view{"RoomTerrainEnum"});
154166
static_assert(to_c_string(TypeEnum::Type) == std::string_view{"TypeEnum"});
155167

156-
NODISCARD std::vector<std::vector<QString>> make_enum_to_strings_table()
168+
template<typename T>
169+
using TypeEnumArray = EnumIndexedArray<T, TypeEnum, NUM_XMLMAPSTORAGE_TYPE>;
170+
171+
using EnumToStrings = TypeEnumArray<std::vector<QString>>;
172+
173+
NODISCARD EnumToStrings initEnumToStrings()
157174
{
158175
#define X_SEP() ,
159176
#define X_DECL_SINGLE(_x) /*QString*/ {#_x},
160177
#define X_DECL_MULTI(_x, ...) /*QString*/ {#_x},
161178
#define X_DECL_TYPE_ENUM(_x) /*QString*/ {TYPE_NAME_C_STRING(_x)},
162-
#define X_CONVERT(_x, _xfor, _xdecl) /*std::vector<QString>*/ {_xfor(_xdecl)}
179+
#define X_CONVERT(_x, _xfor, _xdecl) (std::vector<QString>{_xfor(_xdecl)})
163180

164-
return {XFOREACH_CONVERTER(X_CONVERT, X_SEP)};
181+
return EnumToStrings{XFOREACH_CONVERTER(X_CONVERT, X_SEP)};
165182

166183
#undef X_DECL_SINGLE
167184
#undef X_DECL_MULTI
@@ -174,12 +191,13 @@ NODISCARD std::vector<std::vector<QString>> make_enum_to_strings_table()
174191
class NODISCARD Converter final
175192
{
176193
private:
177-
std::vector<std::vector<QString>> m_enumToStrings = make_enum_to_strings_table();
178-
std::vector<QHash<QStringView, uint32_t>> m_stringToEnums;
194+
EnumToStrings m_enumToStrings = initEnumToStrings();
195+
TypeEnumArray<QHash<QStringView, uint32_t>> m_stringToEnums;
179196

180197
public:
181-
Converter();
198+
explicit Converter();
182199
~Converter() = default;
200+
DELETE_CTORS_AND_ASSIGN_OPS(Converter);
183201

184202
// parse string containing a signed or unsigned number.
185203
template<typename T>
@@ -222,8 +240,8 @@ Converter::Converter()
222240
}
223241

224242
// create the maps string -> enum value for each enum type listed above
225-
for (auto &vec : m_enumToStrings) {
226-
auto &map = m_stringToEnums.emplace_back();
243+
m_enumToStrings.for_each2([this](const TypeEnum e, auto &vec) {
244+
auto &map = m_stringToEnums[e];
227245
uint32_t val = 0;
228246
for (auto &str : vec) {
229247
if (str == "UNDEFINED") {
@@ -237,22 +255,20 @@ Converter::Converter()
237255
}
238256
++val;
239257
}
240-
}
258+
});
241259
}
242260

243261
const QString &Converter::enumToString(const TypeEnum type, const uint32_t val) const
244262
{
245-
const auto index = static_cast<uint32_t>(type);
246-
if (index < m_enumToStrings.size()) {
247-
const auto &tmp = m_enumToStrings[index];
248-
if (val < tmp.size()) {
263+
if (isValid(type)) {
264+
if (const auto &tmp = m_enumToStrings[type]; val < tmp.size()) {
249265
return tmp[val];
250266
}
251267
}
252268

253269
qWarning().noquote().nospace()
254-
<< "Attempt to save an invalid enum type = " << toString(type) << ", value = " << val
255-
<< ". Either the current map is damaged, or there is a bug";
270+
<< "WARNING: Attempt to save an invalid enum type = " << toString(type)
271+
<< ", value = " << val << ". Either the current map is damaged, or there is a bug.";
256272

257273
static const QString g_empty{};
258274
assert(g_empty.isEmpty());
@@ -261,11 +277,9 @@ const QString &Converter::enumToString(const TypeEnum type, const uint32_t val)
261277

262278
std::optional<uint32_t> Converter::stringToEnum(const TypeEnum type, const QStringView str) const
263279
{
264-
const auto index = static_cast<uint32_t>(type);
265-
if (index < m_stringToEnums.size()) {
266-
const auto &tmp = m_stringToEnums[index];
267-
const auto iter = tmp.find(str);
268-
if (iter != tmp.end()) {
280+
if (isValid(type)) {
281+
const auto &tmp = m_stringToEnums[type];
282+
if (const auto iter = tmp.find(str); iter != tmp.end()) {
269283
return iter.value();
270284
}
271285
}

0 commit comments

Comments
 (0)