From d26f9c2fb5a9666822a0f702d76b764600a390d7 Mon Sep 17 00:00:00 2001 From: hop311 Date: Fri, 13 Oct 2023 22:04:12 +0100 Subject: Further CLI and modifier reading work --- .../types/IdentifierRegistry.hpp | 162 ++++++++++----------- 1 file changed, 76 insertions(+), 86 deletions(-) (limited to 'src/openvic-simulation/types/IdentifierRegistry.hpp') diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp index b2f52b2..1a03e75 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -103,11 +103,10 @@ namespace OpenVic { return true; } - template - using get_identifier_func_t = std::string_view(T::*)(void) const; - - template _Type, get_identifier_func_t<_Base> get_identifier, - typename _Storage, _Type* (*get_ptr)(_Storage&), _Type const* (*get_cptr)(_Storage const&)> + /* _GetIdentifier - takes _Type const* and returns std::string_view + * _GetPointer - takes _Storage [const]& and returns T [const]* + */ + template class UniqueKeyRegistry { const std::string name; @@ -116,12 +115,15 @@ namespace OpenVic { bool locked = false; string_map_t identifier_index_map; + _GetIdentifier GetIdentifier; + _GetPointer GetPointer; + public: using value_type = _Type; using storage_type = _Storage; - UniqueKeyRegistry(std::string_view new_name, bool new_log_lock = true) - : name { new_name }, log_lock { new_log_lock } {} + UniqueKeyRegistry(std::string_view new_name, bool new_log_lock = true, _GetIdentifier new_GetIdentifier = {}, _GetPointer new_GetPointer = {}) + : name { new_name }, log_lock { new_log_lock }, GetIdentifier { new_GetIdentifier }, GetPointer { new_GetPointer } {} std::string_view get_name() const { return name; @@ -132,8 +134,7 @@ namespace OpenVic { Logger::error("Cannot add item to the ", name, " registry - locked!"); return false; } - value_type const* new_item = (*get_cptr)(item); - const std::string_view new_identifier = (new_item->*get_identifier)(); + const std::string_view new_identifier = GetIdentifier(GetPointer(item)); value_type const* old_item = get_item_by_identifier(new_identifier); if (old_item != nullptr) { return duplicate_callback(name, new_identifier); @@ -178,30 +179,47 @@ namespace OpenVic { } } - value_type* get_item_by_identifier(std::string_view identifier) { - const typename decltype(identifier_index_map)::const_iterator it = identifier_index_map.find(identifier); - if (it != identifier_index_map.end()) return (*get_ptr)(items[it->second]); - return nullptr; +#define GETTERS \ + 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); \ + if (it != identifier_index_map.end()) return GetPointer(items[it->second]); \ + return nullptr; \ + } \ + value_type _const* get_item_by_index(size_t index) _const { \ + return index < items.size() ? &items[index] : nullptr; \ + } \ + NodeTools::callback_t expect_item_identifier(NodeTools::callback_t callback) _const { \ + return [this, callback](std::string_view identifier) -> bool { \ + value_type _const* item = get_item_by_identifier(identifier); \ + if (item != nullptr) return callback(*item); \ + Logger::error("Invalid ", name, ": ", identifier); \ + return false; \ + }; \ + } \ + NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) _const { \ + return NodeTools::expect_dictionary([this, 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); \ + } \ + Logger::error("Invalid ", name, " identifier: ", key); \ + return false; \ + }); \ } - 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); - if (it != identifier_index_map.end()) return (*get_cptr)(items[it->second]); - return nullptr; - } +#define _const +GETTERS +#undef _const +#define _const const +GETTERS +#undef _const + +#undef GETTERS bool has_identifier(std::string_view identifier) const { return get_item_by_identifier(identifier) != nullptr; } - value_type* get_item_by_index(size_t index) { - return index < items.size() ? &items[index] : nullptr; - } - - value_type const* get_item_by_index(size_t index) const { - return index < items.size() ? &items[index] : nullptr; - } - bool has_index(size_t index) const { return get_item_by_index(index) != nullptr; } @@ -217,46 +235,6 @@ namespace OpenVic { return identifiers; } - NodeTools::callback_t expect_item_identifier(NodeTools::callback_t callback) { - return [this, callback](std::string_view identifier) -> bool { - value_type* item = get_item_by_identifier(identifier); - if (item != nullptr) return callback(*item); - Logger::error("Invalid ", name, ": ", identifier); - return false; - }; - } - - NodeTools::callback_t expect_item_identifier(NodeTools::callback_t callback) const { - return [this, callback](std::string_view identifier) -> bool { - value_type const* item = get_item_by_identifier(identifier); - if (item != nullptr) return callback(*item); - Logger::error("Invalid ", name, ": ", identifier); - return false; - }; - } - - NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) { - return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool { - value_type* item = get_item_by_identifier(key); - if (item != nullptr) { - return callback(*item, value); - } - Logger::error("Invalid ", name, " identifier: ", key); - return false; - }); - } - - NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) const { - return NodeTools::expect_dictionary([this, 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); - } - Logger::error("Invalid ", name, " identifier: ", key); - return false; - }); - } - NodeTools::node_callback_t expect_item_decimal_map(NodeTools::callback_t&&> callback) const { return [this, callback](ast::NodeCPtr node) -> bool { decimal_map_t map; @@ -272,35 +250,47 @@ namespace OpenVic { } }; + /* Standard value storage */ template - [[nodiscard]] inline constexpr T* _addressof(T& v) noexcept { - return std::addressof(v); - } + struct _addressof { + constexpr T* operator()(T& item) const { + return std::addressof(item); + } + constexpr T const* operator()(T const& item) const { + return std::addressof(item); + } + }; + template + using ValueRegistry = UniqueKeyRegistry<_Type, _Type, _GetIdentifier, _addressof<_Type>>; + + /* std::unique_ptr dynamic storage */ template - const T* _addressof(const T&&) = delete; + struct _uptr_get { + constexpr T* operator()(std::unique_ptr& item) const { + return item.get(); + } + constexpr T const* operator()(std::unique_ptr const& item) const { + return item.get(); + } + }; - template _Type, get_identifier_func_t<_Base> get_identifier> - using ValueRegistry = UniqueKeyRegistry<_Base, _Type, get_identifier, _Type, _addressof<_Type>, _addressof>; + template + using InstanceRegistry = UniqueKeyRegistry<_Type, std::unique_ptr<_Type>, _GetIdentifier, _uptr_get<_Type>>; - template - constexpr _Type* get_ptr(std::unique_ptr<_Type>& storage) { - return storage.get(); - } - template - constexpr _Type const* get_cptr(std::unique_ptr<_Type> const& storage) { - return storage.get(); - } - - template _Type, get_identifier_func_t<_Base> get_identifier> - using InstanceRegistry = UniqueKeyRegistry<_Base, _Type, get_identifier, std::unique_ptr<_Type>, - get_ptr<_Type>, get_cptr<_Type>>; + /* HasIdentifier versions */ + template T> + struct _get_identifier { + constexpr std::string_view operator()(T const* item) const { + return item->get_identifier(); + } + }; template _Type> - using IdentifierRegistry = ValueRegistry; + using IdentifierRegistry = ValueRegistry<_Type, _get_identifier<_Type>>; template _Type> - using IdentifierInstanceRegistry = InstanceRegistry; + using IdentifierInstanceRegistry = InstanceRegistry<_Type, _get_identifier<_Type>>; #define IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(singular, plural) \ void lock_##plural() { plural.lock(); } \ -- cgit v1.2.3-56-ga3b1