This commit is contained in:
Timur A. Fatkhullin 2024-11-02 00:58:25 +03:00
parent 8e13ad0c3c
commit 2f46b08c8e
4 changed files with 81 additions and 88 deletions

View File

@ -206,20 +206,12 @@ protected:
std::function<void(const SerializedT&)> _deserializerFunc;
std::function<void()> _clearFunc;
static inline std::vector<std::function<void(AdcDeviceAttribute*)>> _clearFunc{};
std::function<void(AdcDeviceAttribute*)> _copyFunc;
std::function<void(AdcDeviceAttribute*)> _moveFunc;
static inline std::vector<std::function<void(const AdcDeviceAttribute*, AdcDeviceAttribute*)>> _copyFunc{};
static inline std::vector<std::function<void(AdcDeviceAttribute*, AdcDeviceAttribute*)>> _moveFunc{};
template <typename VT>
struct ValueHolder {
std::function<VT()> _getterFunc;
std::function<void(const VT&)> _setterFunc;
// std::unordered_map<const AdcDeviceAttribute*>
};
public:
typedef IdentT ident_t;
@ -277,40 +269,27 @@ public:
ValueT val = deserializer(sval);
_setterFunc<ValueT>[this](val);
AdcDeviceAttribute::_setterFunc<ValueT>[this](val);
};
}
_clearFunc = [this]() {
_getterFunc<ValueT>.erase(this);
_setterFunc<ValueT>.erase(this);
};
_clearFunc.emplace_back([](AdcDeviceAttribute* inst) {
_getterFunc<ValueT>.erase(inst);
_setterFunc<ValueT>.erase(inst);
});
// copy TO other
_copyFunc = [this](AdcDeviceAttribute* other) {
_getterFunc<ValueT>.emplace(other, _getterFunc<ValueT>[this]);
_setterFunc<ValueT>.emplace(other, _setterFunc<ValueT>[this]);
// copy instance function
_copyFunc.emplace_back([](const AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
_getterFunc<ValueT>.emplace(to, _getterFunc<ValueT>[from]);
_setterFunc<ValueT>.emplace(to, _setterFunc<ValueT>[from]);
});
// define copy-function for newly constructed object
other->_copyFunc = [other](AdcDeviceAttribute* o_next) {
_getterFunc<ValueT>.emplace(o_next, _getterFunc<ValueT>[other]);
_setterFunc<ValueT>.emplace(o_next, _setterFunc<ValueT>[other]);
};
};
// move TO other
_moveFunc = [this](AdcDeviceAttribute* other) {
_getterFunc<ValueT>.emplace(other, std::move(_getterFunc<ValueT>[this]));
_setterFunc<ValueT>.emplace(other, std::move(_setterFunc<ValueT>[this]));
// define move-function for newly constructed object
other->_moveFunc = [other](AdcDeviceAttribute* o_next) {
_getterFunc<ValueT>.emplace(o_next, std::move(_getterFunc<ValueT>[other]));
_setterFunc<ValueT>.emplace(o_next, std::move(_setterFunc<ValueT>[other]));
};
};
// move instance function
_moveFunc.emplace_back([](AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
_getterFunc<ValueT>.emplace(to, std::move(_getterFunc<ValueT>[from]));
_setterFunc<ValueT>.emplace(to, std::move(_setterFunc<ValueT>[from]));
});
}
@ -400,8 +379,13 @@ public:
AdcDeviceAttribute(const AdcDeviceAttribute& other)
{
if (&other != this) {
other._copyFunc(this);
for (auto& fn : _copyFunc) {
fn(&other, this);
}
_ident = other._ident;
_accessType = other._accessType;
_serializerFunc = other._serializerFunc;
_deserializerFunc = other._deserializerFunc;
}
@ -410,8 +394,12 @@ public:
AdcDeviceAttribute(AdcDeviceAttribute&& other)
{
if (&other != this) {
other._moveFunc(this);
for (auto& fn : _moveFunc) {
fn(&other, this);
}
_ident = std::move(other._ident);
_accessType = std::move(other._accessType);
_serializerFunc = std::move(other._serializerFunc);
_deserializerFunc = std::move(other._deserializerFunc);
}
@ -420,7 +408,9 @@ public:
virtual ~AdcDeviceAttribute()
{
// _clearFunc();
// for (auto& fn : _clearFunc) {
// fn(this);
// };
}
@ -479,47 +469,24 @@ public:
throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INTERNAL_TYPE_MISMATCH);
}
_clearFunc = [prev_clear = _clearFunc, this]() {
prev_clear();
_getterFunc<user_t>.erase(this);
_setterFunc<user_t>.erase(this);
};
_clearFunc.emplace_back([](AdcDeviceAttribute* inst) {
_getterFunc<user_t>.erase(inst);
_setterFunc<user_t>.erase(inst);
});
// copy TO other
_copyFunc = [prev_copy = _copyFunc, this](AdcDeviceAttribute* other) {
prev_copy(other);
// copy instance functions
_copyFunc.emplace_back([](const AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
_getterFunc<user_t>.emplace(to, _getterFunc<user_t>[from]);
_setterFunc<user_t>.emplace(to, _setterFunc<user_t>[from]);
});
_getterFunc<user_t>.emplace(other, _getterFunc<user_t>[this]);
_setterFunc<user_t>.emplace(other, _setterFunc<user_t>[this]);
// redefine copy-function for newly constructed instance
// other._copyFunc was defined in the 'prev_copy(other)' call above
other->_moveFunc = [other, copy_f = other->_copyFunc](AdcDeviceAttribute* o_next) {
copy_f(o_next);
_getterFunc<user_t>.emplace(o_next, _getterFunc<user_t>[other]);
_setterFunc<user_t>.emplace(o_next, _setterFunc<user_t>[other]);
};
};
// move TO other
_moveFunc = [prev_move = _moveFunc, this](AdcDeviceAttribute* other) {
prev_move(other);
_getterFunc<user_t>.emplace(other, std::move(_getterFunc<user_t>[this]));
_setterFunc<user_t>.emplace(other, std::move(_setterFunc<user_t>[this]));
// redefine move-function for newly constructed instance
// other._moveFunc was defined in the 'prev_move(other)' call above
other->_moveFunc = [other, move_f = other->_moveFunc](AdcDeviceAttribute* o_next) {
move_f(o_next);
_getterFunc<user_t>.emplace(o_next, std::move(_getterFunc<user_t>[other]));
_setterFunc<user_t>.emplace(o_next, std::move(_setterFunc<user_t>[other]));
};
};
// move instance functions
_moveFunc.emplace_back([](AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
_getterFunc<user_t>.emplace(to, std::move(_getterFunc<user_t>[from]));
_setterFunc<user_t>.emplace(to, std::move(_setterFunc<user_t>[from]));
});
return *this;
}
@ -541,6 +508,7 @@ public:
}
template <typename UT>
requires(!std::same_as<AdcDeviceAttribute, std::decay_t<UT>>)
AdcDeviceAttribute& operator=(UT&& val)
{
if (_accessType == ReadOnly) {
@ -562,8 +530,12 @@ public:
AdcDeviceAttribute& operator=(const AdcDeviceAttribute& other)
{
if (&other != this) {
other._copyFunc(this);
for (auto& fn : other._copyFunc) {
fn(&other, this);
}
_ident = other._ident;
_accessType = other._accessType;
_serializerFunc = other._serializerFunc;
_deserializerFunc = other._deserializerFunc;
}
@ -575,8 +547,13 @@ public:
AdcDeviceAttribute& operator=(AdcDeviceAttribute&& other)
{
if (&other != this) {
other._moveFunc(this);
for (auto& fn : other._moveFunc) {
fn(&other, this);
}
_ident = std::move(other._ident);
_accessType = std::move(other._accessType);
_serializerFunc = std::move(other._serializerFunc);
_deserializerFunc = std::move(other._deserializerFunc);
}

View File

@ -453,7 +453,8 @@ public:
template <std::ranges::range ParT>
requires(!traits::adc_input_char_range<std::ranges::range_value_t<ParT>>)
// requires(!traits::adc_input_char_range<std::ranges::range_value_t<ParT>>)
requires(!traits::adc_input_char_range<ParT>)
void ack(const ParT& param)
{
base_t::setKeyValue(ACK_KEY, param);

View File

@ -159,9 +159,10 @@ protected:
_get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<AttrIdDeserialT>(attr_id_deser_func))](
const auto& attr_name) mutable {
auto attr_id = std::get<0>(wrapper)(attr_name);
// auto attr = (*dev_ptr)[attr_id];
// auto val = attr.serialize();
auto val = (*dev_ptr)[attr_id].serialize();
auto& attr = (*dev_ptr)[attr_id];
auto val = attr.serialize();
return val;
// auto val = (*dev_ptr)[attr_id].serialize();
using val_t = std::remove_cvref_t<decltype(val)>;
if constexpr (std::same_as<serialized_t, val_t> || std::convertible_to<val_t, serialized_t>) {

View File

@ -9,8 +9,14 @@ using namespace adc;
template <typename T>
struct V {
static T getter() { return _v; }
static void setter(const T& v) { _v = v; }
static T getter()
{
return _v;
}
static void setter(const T& v)
{
_v = v;
}
static bool validator(const T& v)
{
@ -30,7 +36,7 @@ TEST_CASE("[ADC DEVICE ATTRIBUTE]")
double av = -10;
using vv = V<unsigned>;
using attr_t = AdcDeviceAttribute<std::string_view>;
using attr_t = AdcDeviceAttribute<std::string_view, std::string>;
std::string_view id{"ATTR_A"};
@ -56,4 +62,12 @@ TEST_CASE("[ADC DEVICE ATTRIBUTE]")
std::cout << "ACC_TYPE: " << ar.accessType() << "\n";
std::cout << "ATTR_RO = " << (double)ar << "\n";
auto ar1 = ar;
std::cout << "ATTR1_RO = " << (double)ar1 << "\n";
auto ar2(ar1);
std::cout << "ATTR2_RO = " << (double)ar2 << "\n";
std::cout << "ATTR2_RO_SER = " << ar2.serialize() << "\n";
}