diff options
author | hop311 <hop3114@gmail.com> | 2023-10-13 23:04:12 +0200 |
---|---|---|
committer | hop311 <hop3114@gmail.com> | 2023-10-14 12:05:06 +0200 |
commit | d26f9c2fb5a9666822a0f702d76b764600a390d7 (patch) | |
tree | c2a13a44d4c8553f6e87193f5f437052cf1d7067 /src/openvic-simulation/types/IdentifierRegistry.hpp | |
parent | ce6e70d079f4ab18cdfa082032dc3580ab233b0e (diff) |
Further CLI and modifier reading work
Diffstat (limited to 'src/openvic-simulation/types/IdentifierRegistry.hpp')
-rw-r--r-- | src/openvic-simulation/types/IdentifierRegistry.hpp | 162 |
1 files changed, 76 insertions, 86 deletions
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<typename T> - using get_identifier_func_t = std::string_view(T::*)(void) const; - - template<typename _Base, std::derived_from<_Base> _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<typename _Type, typename _Storage, typename _GetIdentifier, typename _GetPointer> class UniqueKeyRegistry { const std::string name; @@ -116,12 +115,15 @@ namespace OpenVic { bool locked = false; string_map_t<size_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<std::string_view> expect_item_identifier(NodeTools::callback_t<value_type _const&> 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<value_type _const&, ast::NodeCPtr> 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<std::string_view> expect_item_identifier(NodeTools::callback_t<value_type&> 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<std::string_view> expect_item_identifier(NodeTools::callback_t<value_type const&> 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<value_type&, ast::NodeCPtr> 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<value_type const&, ast::NodeCPtr> 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<decimal_map_t<value_type const*>&&> callback) const { return [this, callback](ast::NodeCPtr node) -> bool { decimal_map_t<value_type const*> map; @@ -272,35 +250,47 @@ namespace OpenVic { } }; + /* Standard value storage */ template<typename T> - [[nodiscard]] inline constexpr T* _addressof(T& v) noexcept { - return std::addressof<T>(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<typename _Type, typename _GetIdentifier> + using ValueRegistry = UniqueKeyRegistry<_Type, _Type, _GetIdentifier, _addressof<_Type>>; + + /* std::unique_ptr dynamic storage */ template<typename T> - const T* _addressof(const T&&) = delete; + struct _uptr_get { + constexpr T* operator()(std::unique_ptr<T>& item) const { + return item.get(); + } + constexpr T const* operator()(std::unique_ptr<T> const& item) const { + return item.get(); + } + }; - template<typename _Base, std::derived_from<_Base> _Type, get_identifier_func_t<_Base> get_identifier> - using ValueRegistry = UniqueKeyRegistry<_Base, _Type, get_identifier, _Type, _addressof<_Type>, _addressof<const _Type>>; + template<typename _Type, typename _GetIdentifier> + using InstanceRegistry = UniqueKeyRegistry<_Type, std::unique_ptr<_Type>, _GetIdentifier, _uptr_get<_Type>>; - template<typename _Type> - constexpr _Type* get_ptr(std::unique_ptr<_Type>& storage) { - return storage.get(); - } - template<typename _Type> - constexpr _Type const* get_cptr(std::unique_ptr<_Type> const& storage) { - return storage.get(); - } - - template<typename _Base, std::derived_from<_Base> _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<std::derived_from<HasIdentifier> T> + struct _get_identifier { + constexpr std::string_view operator()(T const* item) const { + return item->get_identifier(); + } + }; template<std::derived_from<HasIdentifier> _Type> - using IdentifierRegistry = ValueRegistry<HasIdentifier, _Type, &HasIdentifier::get_identifier>; + using IdentifierRegistry = ValueRegistry<_Type, _get_identifier<_Type>>; template<std::derived_from<HasIdentifier> _Type> - using IdentifierInstanceRegistry = InstanceRegistry<HasIdentifier, _Type, &HasIdentifier::get_identifier>; + using IdentifierInstanceRegistry = InstanceRegistry<_Type, _get_identifier<_Type>>; #define IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(singular, plural) \ void lock_##plural() { plural.lock(); } \ |