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 {
101100constexpr 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
106110enum 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
153165static_assert (to_c_string(TypeEnum::RoomTerrain) == std::string_view{" RoomTerrainEnum" });
154166static_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()
174191class NODISCARD Converter final
175192{
176193private:
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
180197public:
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
243261const 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
262278std::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