Skip to content

Commit 14ba953

Browse files
committed
Added StringMapCase and case insensitive expect_dictionary_keys
1 parent 3e2ee2c commit 14ba953

File tree

12 files changed

+253
-214
lines changed

12 files changed

+253
-214
lines changed

src/openvic-simulation/dataloader/NodeTools.cpp

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "NodeTools.hpp"
22

33
#include "openvic-simulation/types/Colour.hpp"
4-
#include "openvic-simulation/utility/TslHelper.hpp"
54

65
using namespace OpenVic;
76
using namespace OpenVic::NodeTools;
@@ -70,7 +69,7 @@ node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_vi
7069
}
7170

7271
node_callback_t NodeTools::expect_bool(callback_t<bool> callback) {
73-
static const case_insensitive_string_map_t<bool> bool_map = { { "yes", true }, { "no", false } };
72+
static const case_insensitive_string_map_t<bool> bool_map { { "yes", true }, { "no", false } };
7473
return expect_identifier(expect_mapped_string(bool_map, callback));
7574
}
7675

@@ -324,82 +323,6 @@ node_callback_t NodeTools::expect_dictionary(key_value_callback_t callback) {
324323
return expect_dictionary_and_length(default_length_callback, callback);
325324
}
326325

327-
bool NodeTools::add_key_map_entry(
328-
key_map_t& key_map, std::string_view key, dictionary_entry_t::expected_count_t expected_count, node_callback_t callback
329-
) {
330-
if (!key_map.contains(key)) {
331-
key_map.emplace(key, dictionary_entry_t { expected_count, callback });
332-
return true;
333-
}
334-
Logger::error("Duplicate expected dictionary key: ", key);
335-
return false;
336-
}
337-
338-
bool NodeTools::remove_key_map_entry(key_map_t& key_map, std::string_view key) {
339-
if (key_map.erase(key) == 0) {
340-
Logger::error("Failed to find dictionary key to remove: ", key);
341-
return false;
342-
}
343-
return true;
344-
}
345-
346-
key_value_callback_t NodeTools::dictionary_keys_callback(key_map_t& key_map, key_value_callback_t default_callback) {
347-
return [&key_map, default_callback](std::string_view key, ast::NodeCPtr value) -> bool {
348-
key_map_t::iterator it = key_map.find(key);
349-
if (it == key_map.end()) {
350-
return default_callback(key, value);
351-
}
352-
dictionary_entry_t& entry = it.value();
353-
if (++entry.count > 1 && !entry.can_repeat()) {
354-
Logger::error("Invalid repeat of dictionary key: ", key);
355-
return false;
356-
}
357-
if (entry.callback(value)) {
358-
return true;
359-
} else {
360-
Logger::error("Callback failed for dictionary key: ", key);
361-
return false;
362-
}
363-
};
364-
}
365-
366-
bool NodeTools::check_key_map_counts(key_map_t& key_map) {
367-
bool ret = true;
368-
for (auto key_entry : mutable_iterator(key_map)) {
369-
dictionary_entry_t& entry = key_entry.second;
370-
if (entry.must_appear() && entry.count < 1) {
371-
Logger::error("Mandatory dictionary key not present: ", key_entry.first);
372-
ret = false;
373-
}
374-
entry.count = 0;
375-
}
376-
return ret;
377-
}
378-
379-
node_callback_t NodeTools::expect_dictionary_key_map_and_length_and_default(
380-
key_map_t key_map, length_callback_t length_callback, key_value_callback_t default_callback
381-
) {
382-
return [length_callback, default_callback, key_map = std::move(key_map)](ast::NodeCPtr node) mutable -> bool {
383-
bool ret = expect_dictionary_and_length(length_callback, dictionary_keys_callback(key_map, default_callback))(node);
384-
ret &= check_key_map_counts(key_map);
385-
return ret;
386-
};
387-
}
388-
389-
node_callback_t NodeTools::expect_dictionary_key_map_and_length(key_map_t key_map, length_callback_t length_callback) {
390-
return expect_dictionary_key_map_and_length_and_default(std::move(key_map), length_callback, key_value_invalid_callback);
391-
}
392-
393-
node_callback_t NodeTools::expect_dictionary_key_map_and_default(key_map_t key_map, key_value_callback_t default_callback) {
394-
return expect_dictionary_key_map_and_length_and_default(std::move(key_map), default_length_callback, default_callback);
395-
}
396-
397-
node_callback_t NodeTools::expect_dictionary_key_map(key_map_t key_map) {
398-
return expect_dictionary_key_map_and_length_and_default(
399-
std::move(key_map), default_length_callback, key_value_invalid_callback
400-
);
401-
}
402-
403326
node_callback_t NodeTools::name_list_callback(callback_t<name_list_t&&> callback) {
404327
return [callback](ast::NodeCPtr node) -> bool {
405328
name_list_t list;

src/openvic-simulation/dataloader/NodeTools.hpp

Lines changed: 135 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,11 @@
1414
#include "openvic-simulation/types/HasIdentifier.hpp"
1515
#include "openvic-simulation/types/OrderedContainers.hpp"
1616
#include "openvic-simulation/types/Vector.hpp"
17+
#include "openvic-simulation/utility/TslHelper.hpp"
1718

1819
namespace OpenVic {
1920
namespace ast = ovdl::v2script::ast;
2021

21-
/* Template for map from strings to Ts, in which string_views can be
22-
* searched for without needing to be copied into a string */
23-
template<typename T, class Hash = container_hash<std::string>, class KeyEqual = std::equal_to<>>
24-
using string_map_t = ordered_map<std::string, T, Hash, KeyEqual>;
25-
template<typename T>
26-
using case_insensitive_string_map_t = string_map_t<T, case_insensitive_string_hash, case_insensitive_string_equal>;
27-
28-
/* String set type supporting heterogeneous key lookup */
29-
using string_set_t = ordered_set<std::string>;
30-
using case_insensitive_string_set_t = case_insensitive_ordered_set<std::string>;
31-
3222
using name_list_t = std::vector<std::string>;
3323
std::ostream& operator<<(std::ostream& stream, name_list_t const& name_list);
3424

@@ -178,66 +168,162 @@ namespace OpenVic {
178168
}
179169
};
180170
using enum dictionary_entry_t::expected_count_t;
181-
using key_map_t = string_map_t<dictionary_entry_t>;
182171

172+
template<StringMapCase Case>
173+
using template_key_map_t = template_string_map_t<dictionary_entry_t, Case>;
174+
175+
using key_map_t = template_key_map_t<StringMapCaseSensitive>;
176+
using case_insensitive_key_map_t = template_key_map_t<StringMapCaseInsensitive>;
177+
178+
template<StringMapCase Case>
183179
bool add_key_map_entry(
184-
key_map_t& key_map, std::string_view key, dictionary_entry_t::expected_count_t expected_count,
185-
node_callback_t callback
186-
);
187-
bool remove_key_map_entry(key_map_t& key_map, std::string_view key);
188-
key_value_callback_t dictionary_keys_callback(key_map_t& key_map, key_value_callback_t default_callback);
189-
bool check_key_map_counts(key_map_t& key_map);
180+
template_key_map_t<Case>& key_map, std::string_view key, dictionary_entry_t::expected_count_t expected_count,
181+
NodeCallback auto callback
182+
) {
183+
if (!key_map.contains(key)) {
184+
key_map.emplace(key, dictionary_entry_t { expected_count, callback });
185+
return true;
186+
}
187+
Logger::error("Duplicate expected dictionary key: ", key);
188+
return false;
189+
}
190190

191-
constexpr bool add_key_map_entries(key_map_t& key_map) {
191+
template<StringMapCase Case>
192+
bool remove_key_map_entry(template_key_map_t<Case>& key_map, std::string_view key) {
193+
if (key_map.erase(key) == 0) {
194+
Logger::error("Failed to find dictionary key to remove: ", key);
195+
return false;
196+
}
192197
return true;
193198
}
194-
template<typename... Args>
199+
200+
template<StringMapCase Case>
201+
KeyValueCallback auto dictionary_keys_callback(
202+
template_key_map_t<Case>& key_map, KeyValueCallback auto default_callback
203+
) {
204+
return [&key_map, default_callback](std::string_view key, ast::NodeCPtr value) -> bool {
205+
typename template_key_map_t<Case>::iterator it = key_map.find(key);
206+
if (it == key_map.end()) {
207+
return default_callback(key, value);
208+
}
209+
dictionary_entry_t& entry = it.value();
210+
if (++entry.count > 1 && !entry.can_repeat()) {
211+
Logger::error("Invalid repeat of dictionary key: ", key);
212+
return false;
213+
}
214+
if (entry.callback(value)) {
215+
return true;
216+
} else {
217+
Logger::error("Callback failed for dictionary key: ", key);
218+
return false;
219+
}
220+
};
221+
}
222+
223+
template<StringMapCase Case>
224+
bool check_key_map_counts(template_key_map_t<Case>& key_map) {
225+
bool ret = true;
226+
for (auto key_entry : mutable_iterator(key_map)) {
227+
dictionary_entry_t& entry = key_entry.second;
228+
if (entry.must_appear() && entry.count < 1) {
229+
Logger::error("Mandatory dictionary key not present: ", key_entry.first);
230+
ret = false;
231+
}
232+
entry.count = 0;
233+
}
234+
return ret;
235+
}
236+
237+
template<StringMapCase Case>
238+
constexpr bool add_key_map_entries(template_key_map_t<Case>& key_map) {
239+
return true;
240+
}
241+
242+
template<StringMapCase Case, typename... Args>
195243
bool add_key_map_entries(
196-
key_map_t& key_map, std::string_view key, dictionary_entry_t::expected_count_t expected_count,
244+
template_key_map_t<Case>& key_map, std::string_view key, dictionary_entry_t::expected_count_t expected_count,
197245
NodeCallback auto callback, Args... args
198246
) {
199247
bool ret = add_key_map_entry(key_map, key, expected_count, callback);
200248
ret &= add_key_map_entries(key_map, args...);
201249
return ret;
202250
}
203251

204-
node_callback_t expect_dictionary_key_map_and_length_and_default(
205-
key_map_t key_map, length_callback_t length_callback, key_value_callback_t default_callback
206-
);
207-
node_callback_t expect_dictionary_key_map_and_length(key_map_t key_map, length_callback_t length_callback);
208-
node_callback_t expect_dictionary_key_map_and_default(key_map_t key_map, key_value_callback_t default_callback);
209-
node_callback_t expect_dictionary_key_map(key_map_t key_map);
252+
template<StringMapCase Case>
253+
NodeCallback auto expect_dictionary_key_map_and_length_and_default(
254+
template_key_map_t<Case> key_map, LengthCallback auto length_callback, KeyValueCallback auto default_callback
255+
) {
256+
return [length_callback, default_callback, key_map = std::move(key_map)](ast::NodeCPtr node) mutable -> bool {
257+
bool ret = expect_dictionary_and_length(
258+
length_callback, dictionary_keys_callback(key_map, default_callback)
259+
)(node);
260+
ret &= check_key_map_counts(key_map);
261+
return ret;
262+
};
263+
}
210264

211-
template<typename... Args>
265+
template<StringMapCase Case>
266+
NodeCallback auto expect_dictionary_key_map_and_length(
267+
template_key_map_t<Case> key_map, LengthCallback auto length_callback
268+
) {
269+
return expect_dictionary_key_map_and_length_and_default(
270+
std::move(key_map), length_callback, key_value_invalid_callback
271+
);
272+
}
273+
274+
template<StringMapCase Case>
275+
NodeCallback auto expect_dictionary_key_map_and_default(
276+
template_key_map_t<Case> key_map, KeyValueCallback auto default_callback
277+
) {
278+
return expect_dictionary_key_map_and_length_and_default(
279+
std::move(key_map), default_length_callback, default_callback
280+
);
281+
}
282+
283+
template<StringMapCase Case>
284+
NodeCallback auto expect_dictionary_key_map(template_key_map_t<Case> key_map) {
285+
return expect_dictionary_key_map_and_length_and_default(
286+
std::move(key_map), default_length_callback, key_value_invalid_callback
287+
);
288+
}
289+
290+
template<StringMapCase Case, typename... Args>
212291
NodeCallback auto expect_dictionary_key_map_and_length_and_default(
213-
key_map_t key_map, length_callback_t length_callback, key_value_callback_t default_callback, Args... args
292+
template_key_map_t<Case> key_map, LengthCallback auto length_callback, KeyValueCallback auto default_callback,
293+
Args... args
214294
) {
215295
// TODO - pass return value back up (part of big key_map_t rewrite?)
216296
add_key_map_entries(key_map, args...);
217297
return expect_dictionary_key_map_and_length_and_default(std::move(key_map), length_callback, default_callback);
218298
}
219299

220-
template<typename... Args>
300+
template<StringMapCase Case = StringMapCaseSensitive, typename... Args>
221301
NodeCallback auto expect_dictionary_keys_and_length_and_default(
222302
LengthCallback auto length_callback, KeyValueCallback auto default_callback, Args... args
223303
) {
224-
return expect_dictionary_key_map_and_length_and_default({}, length_callback, default_callback, args...);
304+
return expect_dictionary_key_map_and_length_and_default(
305+
template_key_map_t<Case> {}, length_callback, default_callback, args...
306+
);
225307
}
226308

227-
template<typename... Args>
309+
template<StringMapCase Case = StringMapCaseSensitive, typename... Args>
228310
NodeCallback auto expect_dictionary_keys_and_length(LengthCallback auto length_callback, Args... args) {
229-
return expect_dictionary_key_map_and_length_and_default({}, length_callback, key_value_invalid_callback, args...);
311+
return expect_dictionary_key_map_and_length_and_default(
312+
template_key_map_t<Case> {}, length_callback, key_value_invalid_callback, args...
313+
);
230314
}
231315

232-
template<typename... Args>
316+
template<StringMapCase Case = StringMapCaseSensitive, typename... Args>
233317
NodeCallback auto expect_dictionary_keys_and_default(KeyValueCallback auto default_callback, Args... args) {
234-
return expect_dictionary_key_map_and_length_and_default({}, default_length_callback, default_callback, args...);
318+
return expect_dictionary_key_map_and_length_and_default(
319+
template_key_map_t<Case> {}, default_length_callback, default_callback, args...
320+
);
235321
}
236322

237-
template<typename... Args>
323+
template<StringMapCase Case = StringMapCaseSensitive, typename... Args>
238324
NodeCallback auto expect_dictionary_keys(Args... args) {
239325
return expect_dictionary_key_map_and_length_and_default(
240-
{}, default_length_callback, key_value_invalid_callback, args...
326+
template_key_map_t<Case> {}, default_length_callback, key_value_invalid_callback, args...
241327
);
242328
}
243329

@@ -253,41 +339,42 @@ namespace OpenVic {
253339
NodeCallback auto expect_dictionary_reserve_length(Reservable auto& reservable, KeyValueCallback auto callback) {
254340
return expect_dictionary_and_length(reserve_length_callback(reservable), callback);
255341
}
256-
template<typename... Args>
342+
template<StringMapCase Case, typename... Args>
257343
NodeCallback auto expect_dictionary_key_map_reserve_length_and_default(
258-
Reservable auto& reservable, key_map_t key_map, KeyValueCallback auto default_callback, Args... args
344+
Reservable auto& reservable, template_key_map_t<Case> key_map, KeyValueCallback auto default_callback,
345+
Args... args
259346
) {
260347
return expect_dictionary_key_map_and_length_and_default(
261348
std::move(key_map), reserve_length_callback(reservable), default_callback, args...
262349
);
263350
}
264-
template<typename... Args>
351+
template<StringMapCase Case, typename... Args>
265352
NodeCallback auto expect_dictionary_key_map_reserve_length(
266-
Reservable auto& reservable, key_map_t key_map, Args... args
353+
Reservable auto& reservable, template_key_map_t<Case> key_map, Args... args
267354
) {
268355
return expect_dictionary_key_map_and_length(std::move(key_map), reserve_length_callback(reservable), args...);
269356
}
270-
template<typename... Args>
357+
template<StringMapCase Case = StringMapCaseSensitive, typename... Args>
271358
NodeCallback auto expect_dictionary_keys_reserve_length_and_default(
272359
Reservable auto& reservable, KeyValueCallback auto default_callback, Args... args
273360
) {
274-
return expect_dictionary_keys_and_length_and_default(
361+
return expect_dictionary_keys_and_length_and_default<Case>(
275362
reserve_length_callback(reservable), default_callback, args...
276363
);
277364
}
278-
template<typename... Args>
365+
template<StringMapCase Case = StringMapCaseSensitive, typename... Args>
279366
NodeCallback auto expect_dictionary_keys_reserve_length(Reservable auto& reservable, Args... args) {
280-
return expect_dictionary_keys_and_length(reserve_length_callback(reservable), args...);
367+
return expect_dictionary_keys_and_length<Case>(reserve_length_callback(reservable), args...);
281368
}
282369

283370
node_callback_t name_list_callback(callback_t<name_list_t&&> callback);
284371

285-
template<typename T, class Hash, class KeyEqual>
372+
template<typename T, StringMapCase Case>
286373
Callback<std::string_view> auto expect_mapped_string(
287-
string_map_t<T, Hash, KeyEqual> const& map, Callback<T> auto callback
374+
template_string_map_t<T, Case> const& map, Callback<T> auto callback
288375
) {
289376
return [&map, callback](std::string_view string) -> bool {
290-
const typename string_map_t<T, Hash, KeyEqual>::const_iterator it = map.find(string);
377+
const typename template_string_map_t<T, Case>::const_iterator it = map.find(string);
291378
if (it != map.end()) {
292379
return callback(it->second);
293380
}

src/openvic-simulation/economy/ProductionType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ bool ProductionTypeManager::load_production_types_file(
230230
{ "factory", FACTORY }, { "rgo", RGO }, { "artisan", ARTISAN }
231231
};
232232

233-
const auto parse_node = expect_dictionary_keys(
233+
auto parse_node = expect_dictionary_keys(
234234
"template", ZERO_OR_ONE, success_callback, /* Already parsed using expect_key in Pass #1 above. */
235235
"bonus", ZERO_OR_MORE, [&bonuses](ast::NodeCPtr bonus_node) -> bool {
236236
ConditionScript trigger { scope_t::STATE, scope_t::NO_SCOPE, scope_t::NO_SCOPE };

0 commit comments

Comments
 (0)