add iteration interface to config

This commit is contained in:
Green Sky 2023-12-12 16:33:50 +01:00
parent 57d7178e76
commit 0b4179c039
No known key found for this signature in database
4 changed files with 146 additions and 0 deletions

View File

@ -2,6 +2,8 @@
#include "./config_model.inl"
#include <memory> // Q.Q
// TODO: events?
struct ConfigModelI {
~ConfigModelI(void) {}
@ -35,6 +37,53 @@ struct ConfigModelI {
virtual CM_InternalOptional<int64_t> get_int(CM_ISV module, CM_ISV category) = 0;
virtual CM_InternalOptional<double> get_double(CM_ISV module, CM_ISV category) = 0;
virtual CM_InternalOptional<CM_ISV> get_string(CM_ISV module, CM_ISV category) = 0;
// iteration
// actual range cant be virtual
template<typename Type>
struct ConstEntryProxy {
struct ConstEntryIteratorI {
virtual ~ConstEntryIteratorI(void) {}
virtual std::unique_ptr<ConstEntryIteratorI> 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<ConstEntryIteratorI> _value;
// conversion
//ConstEntryIterator(const std::unique_ptr<ConstEntryIteratorI>& other) { _value = other._value->clone(); }
ConstEntryIterator(std::unique_ptr<ConstEntryIteratorI>&& 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<bool> entries_bool(CM_ISV module, CM_ISV category) const = 0;
virtual ConstEntryProxy<int64_t> entries_int(CM_ISV module, CM_ISV category) const = 0;
virtual ConstEntryProxy<double> entries_double(CM_ISV module, CM_ISV category) const = 0;
virtual ConstEntryProxy<CM_ISV> entries_string(CM_ISV module, CM_ISV category) const = 0;
};

View File

@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include <string>
#include <string_view>
#include <optional>

View File

@ -118,6 +118,69 @@ CM_InternalOptional<CM_ISV> SimpleConfigModel::get_string(CM_ISV module, CM_ISV
}
}
// iteration
// level 3
ConfigModelI::ConstEntryProxy<bool> SimpleConfigModel::entries_bool(CM_ISV module, CM_ISV category) const {
using Type = bool;
using RealType = Type;
static std::map<std::string, RealType> 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<Type, RealType>::createRange(
tmp_map.cbegin(),
tmp_map.cend()
);
}
return SimpleConstEntryIteratorImpl<Type, RealType>::createRange(g_empty_map.cbegin(), g_empty_map.cend());
}
ConfigModelI::ConstEntryProxy<int64_t> SimpleConfigModel::entries_int(CM_ISV module, CM_ISV category) const {
using Type = int64_t;
using RealType = Type;
static std::map<std::string, RealType> 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<Type, RealType>::createRange(
tmp_map.cbegin(),
tmp_map.cend()
);
}
return SimpleConstEntryIteratorImpl<Type, RealType>::createRange(g_empty_map.cbegin(), g_empty_map.cend());
}
ConfigModelI::ConstEntryProxy<double> SimpleConfigModel::entries_double(CM_ISV module, CM_ISV category) const {
using Type = double;
using RealType = Type;
static std::map<std::string, RealType> 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<Type, RealType>::createRange(
tmp_map.cbegin(),
tmp_map.cend()
);
}
return SimpleConstEntryIteratorImpl<Type, RealType>::createRange(g_empty_map.cbegin(), g_empty_map.cend());
}
ConfigModelI::ConstEntryProxy<CM_ISV> SimpleConfigModel::entries_string(CM_ISV module, CM_ISV category) const {
using Type = CM_ISV;
using RealType = std::string;
static std::map<std::string, RealType> 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<Type, RealType>::createRange(
tmp_map.cbegin(),
tmp_map.cend()
);
}
return SimpleConstEntryIteratorImpl<Type, RealType>::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) {

View File

@ -39,6 +39,39 @@ struct SimpleConfigModel : public ConfigModelI {
CM_InternalOptional<double> get_double(CM_ISV module, CM_ISV category) override;
CM_InternalOptional<CM_ISV> get_string(CM_ISV module, CM_ISV category) override;
// iteration
template<typename Type, typename RealType = Type>
struct SimpleConstEntryIteratorImpl : public ConfigModelI::ConstEntryProxy<Type>::ConstEntryIteratorI {
using BaseIteratorIType = typename ConfigModelI::ConstEntryProxy<Type>::ConstEntryIteratorI;
using MapType = std::map<std::string, RealType>;
using MapTypeIterator = typename MapType::const_iterator;
MapTypeIterator _self;
SimpleConstEntryIteratorImpl(const MapTypeIterator& self) : _self(self) {}
SimpleConstEntryIteratorImpl(void) {}
virtual ~SimpleConstEntryIteratorImpl(void) {}
std::unique_ptr<BaseIteratorIType> clone(void) override { return std::make_unique<SimpleConstEntryIteratorImpl>(_self); }
bool equal(const BaseIteratorIType& other) const override { return _self == static_cast<const SimpleConstEntryIteratorImpl&>(other)._self; }
void incrementOne(void) override { ++_self; }
Type getValue(void) const override { return _self->second; }
// helper
static ConfigModelI::ConstEntryProxy<Type> createRange(const MapTypeIterator& begin, const MapTypeIterator& end) {
return {
SimpleConstEntryIteratorImpl{begin}.clone(),
SimpleConstEntryIteratorImpl{end}.clone()
};
}
};
// level 3
ConfigModelI::ConstEntryProxy<bool> entries_bool(CM_ISV module, CM_ISV category) const override;
ConfigModelI::ConstEntryProxy<int64_t> entries_int(CM_ISV module, CM_ISV category) const override;
ConfigModelI::ConstEntryProxy<double> entries_double(CM_ISV module, CM_ISV category) const override;
ConfigModelI::ConstEntryProxy<CM_ISV> entries_string(CM_ISV module, CM_ISV category) const override;
// debug
void dump(void);
};