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
1819namespace 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 }
0 commit comments