diff options
author | hop311 <hop3114@gmail.com> | 2024-01-08 23:19:39 +0100 |
---|---|---|
committer | hop311 <hop3114@gmail.com> | 2024-01-08 23:19:39 +0100 |
commit | 83802dfead4938e6f98b4b9961b286e06ab78b18 (patch) | |
tree | b0b404a1826d455767b16d3e3ae1d6bf7516e06d /src/openvic-simulation/types | |
parent | 79b8b73304753fedab822e6aa859fa15673f52cc (diff) |
Added map_callback and expect_item_dictionary_reserve_length
Diffstat (limited to 'src/openvic-simulation/types')
-rw-r--r-- | src/openvic-simulation/types/HasIdentifier.hpp | 88 | ||||
-rw-r--r-- | src/openvic-simulation/types/IdentifierRegistry.hpp | 204 | ||||
-rw-r--r-- | src/openvic-simulation/types/OrderedContainers.hpp | 2 |
3 files changed, 200 insertions, 94 deletions
diff --git a/src/openvic-simulation/types/HasIdentifier.hpp b/src/openvic-simulation/types/HasIdentifier.hpp new file mode 100644 index 0000000..9457e75 --- /dev/null +++ b/src/openvic-simulation/types/HasIdentifier.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include <algorithm> +#include <cassert> +#include <ostream> + +#include "openvic-simulation/types/Colour.hpp" +#include "openvic-simulation/utility/Getters.hpp" + +namespace OpenVic { + constexpr bool valid_basic_identifier_char(char c) { + return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_'; + } + constexpr bool valid_basic_identifier(std::string_view identifier) { + return std::all_of(identifier.begin(), identifier.end(), valid_basic_identifier_char); + } + constexpr std::string_view extract_basic_identifier_prefix(std::string_view identifier) { + size_t len = 0; + while (len < identifier.size() && valid_basic_identifier_char(identifier[len])) { + ++len; + } + return { identifier.data(), len }; + } + + /* + * Base class for objects with a non-empty string identifier. Uniquely named instances of a type derived from this class + * can be entered into an IdentifierRegistry instance. + */ + class HasIdentifier { + const std::string PROPERTY(identifier); + + protected: + HasIdentifier(std::string_view new_identifier): identifier { new_identifier } { + assert(!identifier.empty()); + } + + public: + HasIdentifier(HasIdentifier const&) = delete; + HasIdentifier(HasIdentifier&&) = default; + HasIdentifier& operator=(HasIdentifier const&) = delete; + HasIdentifier& operator=(HasIdentifier&&) = delete; + }; + + inline std::ostream& operator<<(std::ostream& stream, HasIdentifier const& obj) { + return stream << obj.get_identifier(); + } + inline std::ostream& operator<<(std::ostream& stream, HasIdentifier const* obj) { + return obj != nullptr ? stream << *obj : stream << "<NULL>"; + } + + /* + * Base class for objects with associated colour information. + */ + template<IsColour ColourT> + class _HasColour { + const ColourT PROPERTY(colour); + + protected: + _HasColour(ColourT new_colour, bool cannot_be_null): colour { new_colour } { + assert(!cannot_be_null || !colour.is_null()); + } + + public: + _HasColour(_HasColour const&) = delete; + _HasColour(_HasColour&&) = default; + _HasColour& operator=(_HasColour const&) = delete; + _HasColour& operator=(_HasColour&&) = delete; + }; + + /* + * Base class for objects with a unique string identifier and associated colour information. + */ + template<IsColour ColourT> + class _HasIdentifierAndColour : public HasIdentifier, public _HasColour<ColourT> { + protected: + _HasIdentifierAndColour(std::string_view new_identifier, ColourT new_colour, bool cannot_be_null) + : HasIdentifier { new_identifier }, _HasColour<ColourT> { new_colour, cannot_be_null } {} + + public: + _HasIdentifierAndColour(_HasIdentifierAndColour const&) = delete; + _HasIdentifierAndColour(_HasIdentifierAndColour&&) = default; + _HasIdentifierAndColour& operator=(_HasIdentifierAndColour const&) = delete; + _HasIdentifierAndColour& operator=(_HasIdentifierAndColour&&) = delete; + }; + + using HasIdentifierAndColour = _HasIdentifierAndColour<colour_t>; + using HasIdentifierAndAlphaColour = _HasIdentifierAndColour<colour_argb_t>; +} diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp index 53a68a5..04198b0 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -1,93 +1,14 @@ #pragma once -#include <cassert> #include <vector> #include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/types/fixed_point/FixedPointMap.hpp" +#include "openvic-simulation/types/HasIdentifier.hpp" #include "openvic-simulation/utility/Getters.hpp" #include "openvic-simulation/utility/Logger.hpp" namespace OpenVic { - - constexpr bool valid_basic_identifier_char(char c) { - return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_'; - } - constexpr bool valid_basic_identifier(std::string_view identifier) { - return std::all_of(identifier.begin(), identifier.end(), valid_basic_identifier_char); - } - constexpr std::string_view extract_basic_identifier_prefix(std::string_view identifier) { - size_t len = 0; - while (len < identifier.size() && valid_basic_identifier_char(identifier[len])) { - ++len; - } - return { identifier.data(), len }; - } - - /* - * Base class for objects with a non-empty string identifier. Uniquely named instances of a type derived from this class - * can be entered into an IdentifierRegistry instance. - */ - class HasIdentifier { - const std::string PROPERTY(identifier); - - protected: - HasIdentifier(std::string_view new_identifier): identifier { new_identifier } { - assert(!identifier.empty()); - } - - public: - HasIdentifier(HasIdentifier const&) = delete; - HasIdentifier(HasIdentifier&&) = default; - HasIdentifier& operator=(HasIdentifier const&) = delete; - HasIdentifier& operator=(HasIdentifier&&) = delete; - }; - - inline std::ostream& operator<<(std::ostream& stream, HasIdentifier const& obj) { - return stream << obj.get_identifier(); - } - inline std::ostream& operator<<(std::ostream& stream, HasIdentifier const* obj) { - return obj != nullptr ? stream << *obj : stream << "<NULL>"; - } - - /* - * Base class for objects with associated colour information. - */ - template<IsColour ColourT> - class _HasColour { - const ColourT PROPERTY(colour); - - protected: - _HasColour(ColourT new_colour, bool cannot_be_null): colour { new_colour } { - assert(!cannot_be_null || !colour.is_null()); - } - - public: - _HasColour(_HasColour const&) = delete; - _HasColour(_HasColour&&) = default; - _HasColour& operator=(_HasColour const&) = delete; - _HasColour& operator=(_HasColour&&) = delete; - }; - - /* - * Base class for objects with a unique string identifier and associated colour information. - */ - template<IsColour ColourT> - class _HasIdentifierAndColour : public HasIdentifier, public _HasColour<ColourT> { - protected: - _HasIdentifierAndColour(std::string_view new_identifier, ColourT new_colour, bool cannot_be_null) - : HasIdentifier { new_identifier }, _HasColour<ColourT> { new_colour, cannot_be_null } {} - - public: - _HasIdentifierAndColour(_HasIdentifierAndColour const&) = delete; - _HasIdentifierAndColour(_HasIdentifierAndColour&&) = default; - _HasIdentifierAndColour& operator=(_HasIdentifierAndColour const&) = delete; - _HasIdentifierAndColour& operator=(_HasIdentifierAndColour&&) = delete; - }; - - using HasIdentifierAndColour = _HasIdentifierAndColour<colour_t>; - using HasIdentifierAndAlphaColour = _HasIdentifierAndColour<colour_argb_t>; - /* Callbacks for trying to add duplicate keys via UniqueKeyRegistry::add_item */ static bool duplicate_fail_callback(std::string_view registry_name, std::string_view duplicate_identifier) { Logger::error( @@ -199,9 +120,17 @@ namespace OpenVic { Logger::error("Failed to reserve space for ", size, " items in ", name, " registry - already locked!"); } else { items.reserve(size); + identifier_index_map.reserve(size); } } + static NodeTools::KeyValueCallback auto key_value_invalid_callback(std::string_view name) { + return [name](std::string_view key, ast::NodeCPtr) { + Logger::error("Invalid ", name, ": ", key); + return false; + }; + } + #define GETTERS(CONST) \ value_type CONST* get_item_by_identifier(std::string_view identifier) CONST { \ const typename decltype(identifier_index_map)::const_iterator it = identifier_index_map.find(identifier); \ @@ -235,12 +164,12 @@ namespace OpenVic { ) CONST { \ return NodeTools::expect_identifier(expect_item_str(callback, warn)); \ } \ - NodeTools::NodeCallback auto expect_item_dictionary_and_default( \ - NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback, \ - NodeTools::KeyValueCallback auto default_callback \ + NodeTools::NodeCallback auto expect_item_assign_and_default( \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ ) CONST { \ - return NodeTools::expect_dictionary( \ - [this, callback, default_callback](std::string_view key, ast::NodeCPtr value) -> bool { \ + return NodeTools::expect_assign( \ + [this, default_callback, callback](std::string_view key, ast::NodeCPtr value) -> bool { \ value_type CONST* item = get_item_by_identifier(key); \ if (item != nullptr) { \ return callback(*item, value); \ @@ -250,14 +179,70 @@ namespace OpenVic { } \ ); \ } \ + NodeTools::NodeCallback auto expect_item_assign( \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ + ) CONST { \ + return expect_item_assign_and_default(key_value_invalid_callback(name), callback); \ + } \ + NodeTools::NodeCallback auto expect_item_dictionary_and_length_and_default( \ + NodeTools::LengthCallback auto length_callback, \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ + ) CONST { \ + return NodeTools::expect_list_and_length( \ + length_callback, expect_item_assign_and_default(default_callback, callback) \ + ); \ + } \ + NodeTools::NodeCallback auto expect_item_dictionary_and_length( \ + NodeTools::LengthCallback auto length_callback, \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ + ) CONST { \ + return expect_item_dictionary_and_length_and_default( \ + length_callback, \ + key_value_invalid_callback(name), \ + callback \ + ); \ + } \ + NodeTools::NodeCallback auto expect_item_dictionary_and_default( \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ + ) CONST { \ + return expect_item_dictionary_and_length_and_default( \ + NodeTools::default_length_callback, \ + default_callback, \ + callback \ + ); \ + } \ NodeTools::NodeCallback auto expect_item_dictionary( \ NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ ) CONST { \ - return expect_item_dictionary_and_default( \ - callback, [this](std::string_view key, ast::NodeCPtr) -> bool { \ - Logger::error("Invalid ", name, ": ", key); \ - return false; \ - } \ + return expect_item_dictionary_and_length_and_default( \ + NodeTools::default_length_callback, \ + key_value_invalid_callback(name), \ + callback \ + ); \ + } \ + template<NodeTools::Reservable T> \ + NodeTools::NodeCallback auto expect_item_dictionary_reserve_length_and_default( \ + T& t, \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ + ) CONST { \ + return expect_item_dictionary_and_length_and_default( \ + NodeTools::reserve_length_callback(t), \ + default_callback, \ + callback \ + ); \ + } \ + template<NodeTools::Reservable T> \ + NodeTools::NodeCallback auto expect_item_dictionary_reserve_length( \ + T& t, \ + NodeTools::Callback<value_type CONST&, ast::NodeCPtr> auto callback \ + ) CONST { \ + return expect_item_dictionary_and_length_and_default( \ + NodeTools::reserve_length_callback(t), \ + key_value_invalid_callback(name), \ + callback \ ); \ } @@ -432,15 +417,48 @@ private: ) const_kw { \ return registry.expect_item_identifier(callback, warn); \ } \ + NodeTools::NodeCallback auto expect_##singular##_assign_and_default( \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ + ) const_kw { \ + return registry.expect_item_assign_and_default(default_callback, callback); \ + } \ + NodeTools::NodeCallback auto expect_##singular##_assign( \ + NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ + ) const_kw { \ + return registry.expect_item_assign(callback); \ + } \ + NodeTools::NodeCallback auto expect_##singular##_dictionary_and_length_and_default( \ + NodeTools::LengthCallback auto length_callback, \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ + ) const_kw { \ + return registry.expect_item_dictionary_and_length_and_default(length_callback, default_callback, callback); \ + } \ NodeTools::NodeCallback auto expect_##singular##_dictionary_and_default( \ - NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback, \ - NodeTools::KeyValueCallback auto default_callback \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ ) const_kw { \ - return registry.expect_item_dictionary_and_default(callback, default_callback); \ + return registry.expect_item_dictionary_and_default(default_callback, callback); \ } \ NodeTools::NodeCallback auto expect_##singular##_dictionary( \ NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ ) const_kw { \ return registry.expect_item_dictionary(callback); \ + } \ + template<NodeTools::Reservable T> \ + NodeTools::NodeCallback auto expect_##singular##_dictionary_reserve_length_and_default( \ + T& t, \ + NodeTools::KeyValueCallback auto default_callback, \ + NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ + ) const_kw { \ + return registry.expect_item_dictionary_reserve_length_and_default(t, default_callback, callback); \ + } \ + template<NodeTools::Reservable T> \ + NodeTools::NodeCallback auto expect_##singular##_dictionary_reserve_length( \ + T& t, \ + NodeTools::Callback<decltype(registry)::value_type const_kw&, ast::NodeCPtr> auto callback \ + ) const_kw { \ + return registry.expect_item_dictionary_reserve_length(t, callback); \ } } diff --git a/src/openvic-simulation/types/OrderedContainers.hpp b/src/openvic-simulation/types/OrderedContainers.hpp index 1df9b10..e9f8717 100644 --- a/src/openvic-simulation/types/OrderedContainers.hpp +++ b/src/openvic-simulation/types/OrderedContainers.hpp @@ -146,7 +146,7 @@ namespace OpenVic { template<class Key, class T, class Allocator = std::allocator<std::pair<Key, T>>, class IndexType = std::uint_least32_t> using case_insensitive_deque_ordered_map = deque_ordered_map<Key, T, case_insensitive_string_hash, case_insensitive_string_equal, Allocator, IndexType>; - + template<class Key, class T, class Allocator = std::allocator<std::pair<Key, T>>, class IndexType = std::uint_least32_t> using case_insensitive_ordered_map = case_insensitive_vector_ordered_map<Key, T, Allocator, IndexType>; |