diff --git a/device/adc_device_attribute.h b/device/adc_device_attribute.h index c16422b..d21007e 100644 --- a/device/adc_device_attribute.h +++ b/device/adc_device_attribute.h @@ -206,20 +206,12 @@ protected: std::function _deserializerFunc; - std::function _clearFunc; + static inline std::vector> _clearFunc{}; - std::function _copyFunc; - std::function _moveFunc; + static inline std::vector> _copyFunc{}; + static inline std::vector> _moveFunc{}; - template - struct ValueHolder { - std::function _getterFunc; - std::function _setterFunc; - - // std::unordered_map - }; - public: typedef IdentT ident_t; @@ -277,40 +269,27 @@ public: ValueT val = deserializer(sval); - _setterFunc[this](val); + AdcDeviceAttribute::_setterFunc[this](val); }; } - _clearFunc = [this]() { - _getterFunc.erase(this); - _setterFunc.erase(this); - }; + _clearFunc.emplace_back([](AdcDeviceAttribute* inst) { + _getterFunc.erase(inst); + _setterFunc.erase(inst); + }); - // copy TO other - _copyFunc = [this](AdcDeviceAttribute* other) { - _getterFunc.emplace(other, _getterFunc[this]); - _setterFunc.emplace(other, _setterFunc[this]); + // copy instance function + _copyFunc.emplace_back([](const AdcDeviceAttribute* from, AdcDeviceAttribute* to) { + _getterFunc.emplace(to, _getterFunc[from]); + _setterFunc.emplace(to, _setterFunc[from]); + }); - // define copy-function for newly constructed object - other->_copyFunc = [other](AdcDeviceAttribute* o_next) { - _getterFunc.emplace(o_next, _getterFunc[other]); - _setterFunc.emplace(o_next, _setterFunc[other]); - }; - }; - - - // move TO other - _moveFunc = [this](AdcDeviceAttribute* other) { - _getterFunc.emplace(other, std::move(_getterFunc[this])); - _setterFunc.emplace(other, std::move(_setterFunc[this])); - - // define move-function for newly constructed object - other->_moveFunc = [other](AdcDeviceAttribute* o_next) { - _getterFunc.emplace(o_next, std::move(_getterFunc[other])); - _setterFunc.emplace(o_next, std::move(_setterFunc[other])); - }; - }; + // move instance function + _moveFunc.emplace_back([](AdcDeviceAttribute* from, AdcDeviceAttribute* to) { + _getterFunc.emplace(to, std::move(_getterFunc[from])); + _setterFunc.emplace(to, std::move(_setterFunc[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.erase(this); - _setterFunc.erase(this); - }; + _clearFunc.emplace_back([](AdcDeviceAttribute* inst) { + _getterFunc.erase(inst); + _setterFunc.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.emplace(to, _getterFunc[from]); + _setterFunc.emplace(to, _setterFunc[from]); + }); - _getterFunc.emplace(other, _getterFunc[this]); - _setterFunc.emplace(other, _setterFunc[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.emplace(o_next, _getterFunc[other]); - _setterFunc.emplace(o_next, _setterFunc[other]); - }; - }; - - // move TO other - _moveFunc = [prev_move = _moveFunc, this](AdcDeviceAttribute* other) { - prev_move(other); - - _getterFunc.emplace(other, std::move(_getterFunc[this])); - _setterFunc.emplace(other, std::move(_setterFunc[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.emplace(o_next, std::move(_getterFunc[other])); - _setterFunc.emplace(o_next, std::move(_setterFunc[other])); - }; - }; + // move instance functions + _moveFunc.emplace_back([](AdcDeviceAttribute* from, AdcDeviceAttribute* to) { + _getterFunc.emplace(to, std::move(_getterFunc[from])); + _setterFunc.emplace(to, std::move(_setterFunc[from])); + }); return *this; } @@ -541,6 +508,7 @@ public: } template + requires(!std::same_as>) 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); } diff --git a/net/adc_device_netmsg.h b/net/adc_device_netmsg.h index 3588d69..4c96808 100644 --- a/net/adc_device_netmsg.h +++ b/net/adc_device_netmsg.h @@ -453,7 +453,8 @@ public: template - requires(!traits::adc_input_char_range>) + // requires(!traits::adc_input_char_range>) + requires(!traits::adc_input_char_range) void ack(const ParT& param) { base_t::setKeyValue(ACK_KEY, param); diff --git a/net/adc_device_netserver.h b/net/adc_device_netserver.h index d9f8613..59faba7 100644 --- a/net/adc_device_netserver.h +++ b/net/adc_device_netserver.h @@ -159,9 +159,10 @@ protected: _get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(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; if constexpr (std::same_as || std::convertible_to) { diff --git a/tests/adc_devattr_test.cpp b/tests/adc_devattr_test.cpp index 0b2d8c5..14d0e1b 100644 --- a/tests/adc_devattr_test.cpp +++ b/tests/adc_devattr_test.cpp @@ -9,8 +9,14 @@ using namespace adc; template 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; - using attr_t = AdcDeviceAttribute; + using attr_t = AdcDeviceAttribute; 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"; }