From 0b4179c0392c30bc1da9791d063a499b6d36ff1c Mon Sep 17 00:00:00 2001 From: Green Sky Date: Tue, 12 Dec 2023 16:33:50 +0100 Subject: [PATCH] add iteration interface to config --- solanaceae/util/config_model.hpp | 49 +++++++++++++++++++ solanaceae/util/config_model.inl | 1 + solanaceae/util/simple_config_model.cpp | 63 +++++++++++++++++++++++++ solanaceae/util/simple_config_model.hpp | 33 +++++++++++++ 4 files changed, 146 insertions(+) diff --git a/solanaceae/util/config_model.hpp b/solanaceae/util/config_model.hpp index 744df17..5108885 100644 --- a/solanaceae/util/config_model.hpp +++ b/solanaceae/util/config_model.hpp @@ -2,6 +2,8 @@ #include "./config_model.inl" +#include // Q.Q + // TODO: events? struct ConfigModelI { ~ConfigModelI(void) {} @@ -35,6 +37,53 @@ struct ConfigModelI { virtual CM_InternalOptional get_int(CM_ISV module, CM_ISV category) = 0; virtual CM_InternalOptional get_double(CM_ISV module, CM_ISV category) = 0; virtual CM_InternalOptional get_string(CM_ISV module, CM_ISV category) = 0; + + // iteration + // actual range cant be virtual + template + struct ConstEntryProxy { + struct ConstEntryIteratorI { + virtual ~ConstEntryIteratorI(void) {} + virtual std::unique_ptr clone(void) = 0; + virtual bool equal(const ConstEntryIteratorI& other) const = 0; + virtual void incrementOne(void) = 0; + //virtual const Type& getValue(void) const = 0; + virtual Type getValue(void) const = 0; + }; + + // actual iterator cant be virtual + struct ConstEntryIterator { + std::unique_ptr _value; + + // conversion + //ConstEntryIterator(const std::unique_ptr& other) { _value = other._value->clone(); } + ConstEntryIterator(std::unique_ptr&& value) { _value = std::move(value); } + + // copy + ConstEntryIterator(const ConstEntryIterator& other) { _value = other._value->clone(); } + ConstEntryIterator& operator=(const ConstEntryIterator& other) { _value = other._value->clone(); return *this; } + + // move + ConstEntryIterator(ConstEntryIterator&& other) { _value = std::move(other._value); } + + bool operator==(const ConstEntryIterator& other) const { return _value->equal(*other._value); } + bool operator!=(const ConstEntryIterator& other) const { return !operator==(other); } + ConstEntryIterator& operator++(void) { _value->incrementOne(); return *this; } + Type operator*(void) const { return _value->getValue(); } + }; + + ConstEntryIterator _begin; + ConstEntryIterator _end; + + const ConstEntryIterator& begin(void) const { return _begin; } + const ConstEntryIterator& end(void) const { return _end; } + }; + + // level 3 + virtual ConstEntryProxy entries_bool(CM_ISV module, CM_ISV category) const = 0; + virtual ConstEntryProxy entries_int(CM_ISV module, CM_ISV category) const = 0; + virtual ConstEntryProxy entries_double(CM_ISV module, CM_ISV category) const = 0; + virtual ConstEntryProxy entries_string(CM_ISV module, CM_ISV category) const = 0; }; diff --git a/solanaceae/util/config_model.inl b/solanaceae/util/config_model.inl index ed41c80..c86ccfd 100644 --- a/solanaceae/util/config_model.inl +++ b/solanaceae/util/config_model.inl @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/solanaceae/util/simple_config_model.cpp b/solanaceae/util/simple_config_model.cpp index 5bae34e..8d1edb7 100644 --- a/solanaceae/util/simple_config_model.cpp +++ b/solanaceae/util/simple_config_model.cpp @@ -118,6 +118,69 @@ CM_InternalOptional SimpleConfigModel::get_string(CM_ISV module, CM_ISV } } +// iteration + +// level 3 +ConfigModelI::ConstEntryProxy SimpleConfigModel::entries_bool(CM_ISV module, CM_ISV category) const { + using Type = bool; + using RealType = Type; + static std::map g_empty_map; + auto& map = _map_bool; + if (map.count(module) && map.at(module).count(category)) { + const auto& tmp_map = map.at(module).at(category).second; + return SimpleConstEntryIteratorImpl::createRange( + tmp_map.cbegin(), + tmp_map.cend() + ); + } + return SimpleConstEntryIteratorImpl::createRange(g_empty_map.cbegin(), g_empty_map.cend()); +} + +ConfigModelI::ConstEntryProxy SimpleConfigModel::entries_int(CM_ISV module, CM_ISV category) const { + using Type = int64_t; + using RealType = Type; + static std::map g_empty_map; + auto& map = _map_int; + if (map.count(module) && map.at(module).count(category)) { + const auto& tmp_map = map.at(module).at(category).second; + return SimpleConstEntryIteratorImpl::createRange( + tmp_map.cbegin(), + tmp_map.cend() + ); + } + return SimpleConstEntryIteratorImpl::createRange(g_empty_map.cbegin(), g_empty_map.cend()); +} + +ConfigModelI::ConstEntryProxy SimpleConfigModel::entries_double(CM_ISV module, CM_ISV category) const { + using Type = double; + using RealType = Type; + static std::map g_empty_map; + auto& map = _map_double; + if (map.count(module) && map.at(module).count(category)) { + const auto& tmp_map = map.at(module).at(category).second; + return SimpleConstEntryIteratorImpl::createRange( + tmp_map.cbegin(), + tmp_map.cend() + ); + } + return SimpleConstEntryIteratorImpl::createRange(g_empty_map.cbegin(), g_empty_map.cend()); +} + +ConfigModelI::ConstEntryProxy SimpleConfigModel::entries_string(CM_ISV module, CM_ISV category) const { + using Type = CM_ISV; + using RealType = std::string; + static std::map g_empty_map; + auto& map = _map_string; + if (map.count(module) && map.at(module).count(category)) { + const auto& tmp_map = map.at(module).at(category).second; + return SimpleConstEntryIteratorImpl::createRange( + tmp_map.cbegin(), + tmp_map.cend() + ); + } + return SimpleConstEntryIteratorImpl::createRange(g_empty_map.cbegin(), g_empty_map.cend()); +} + void SimpleConfigModel::dump(void) { std::cout << "SCM dump:\n"; for (const auto& [k_m, v_c] : _map_bool) { diff --git a/solanaceae/util/simple_config_model.hpp b/solanaceae/util/simple_config_model.hpp index 797587e..5a6da00 100644 --- a/solanaceae/util/simple_config_model.hpp +++ b/solanaceae/util/simple_config_model.hpp @@ -39,6 +39,39 @@ struct SimpleConfigModel : public ConfigModelI { CM_InternalOptional get_double(CM_ISV module, CM_ISV category) override; CM_InternalOptional get_string(CM_ISV module, CM_ISV category) override; + // iteration + template + struct SimpleConstEntryIteratorImpl : public ConfigModelI::ConstEntryProxy::ConstEntryIteratorI { + using BaseIteratorIType = typename ConfigModelI::ConstEntryProxy::ConstEntryIteratorI; + using MapType = std::map; + using MapTypeIterator = typename MapType::const_iterator; + + MapTypeIterator _self; + + SimpleConstEntryIteratorImpl(const MapTypeIterator& self) : _self(self) {} + SimpleConstEntryIteratorImpl(void) {} + + virtual ~SimpleConstEntryIteratorImpl(void) {} + std::unique_ptr clone(void) override { return std::make_unique(_self); } + bool equal(const BaseIteratorIType& other) const override { return _self == static_cast(other)._self; } + void incrementOne(void) override { ++_self; } + Type getValue(void) const override { return _self->second; } + + // helper + static ConfigModelI::ConstEntryProxy createRange(const MapTypeIterator& begin, const MapTypeIterator& end) { + return { + SimpleConstEntryIteratorImpl{begin}.clone(), + SimpleConstEntryIteratorImpl{end}.clone() + }; + } + }; + + // level 3 + ConfigModelI::ConstEntryProxy entries_bool(CM_ISV module, CM_ISV category) const override; + ConfigModelI::ConstEntryProxy entries_int(CM_ISV module, CM_ISV category) const override; + ConfigModelI::ConstEntryProxy entries_double(CM_ISV module, CM_ISV category) const override; + ConfigModelI::ConstEntryProxy entries_string(CM_ISV module, CM_ISV category) const override; + // debug void dump(void); };