add iteration interface to config
This commit is contained in:
parent
57d7178e76
commit
0b4179c039
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user