diff --git a/common/adc_traits.h b/common/adc_traits.h index 0bec9da..245b063 100644 --- a/common/adc_traits.h +++ b/common/adc_traits.h @@ -67,10 +67,16 @@ struct adc_func_traits_helper_t { }; -// callable traits +// callable concept and its signature traits -template -struct adc_func_traits; +template +concept adc_is_callable = + std::is_function_v || (std::is_object_v && requires(T) { std::is_function_v; }); + +template +struct adc_func_traits { + // use of an empty struct here to match std::invoke_result behaivior (at least of GCC) +}; template struct adc_func_traits : adc_func_traits_helper_t { @@ -89,8 +95,8 @@ struct adc_func_traits : adc_func_traits_helper_t -// struct adc_func_traits : adc_func_traits::operator())> { -struct adc_func_traits>> : adc_func_traits { + requires adc_is_callable +struct adc_func_traits : adc_func_traits { }; template @@ -138,13 +144,32 @@ template struct adc_is_tuple : std::false_type { }; +template +struct adc_is_tuple : adc_is_tuple { +}; + +template +struct adc_is_tuple : adc_is_tuple { +}; + +template +struct adc_is_tuple : adc_is_tuple { +}; + template struct adc_is_tuple> : std::true_type { }; +template +struct adc_is_tuple> : std::true_type { +}; template static inline constexpr bool adc_is_tuple_v = adc_is_tuple::value; +template +concept adc_tuple_like = adc_is_tuple_v == true; + + } // namespace adc::traits diff --git a/common/adc_value.h b/common/adc_value.h index 47da948..3edb80d 100644 --- a/common/adc_value.h +++ b/common/adc_value.h @@ -177,32 +177,21 @@ public: } - template - AdcValueHolder(std::invocable<> auto&& getter, - std::invocable&> auto&& setter, - std::predicate&> auto&& validator, - const std::tuple& /* tuple-of-trivially-converting-types */) - : AdcValueHolder(std::forward(getter), + template , + typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator)> + AdcValueHolder(traits::adc_tuple_like<> auto&& tpl, + GT&& getter, + std::invocable auto&& setter, + VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator) + : AdcValueHolder(std::forward(getter), std::forward(setter), std::forward(validator)) { // setup trivially-defined conversion function - AdcValueHolder::setupTrivialConvertFunc, std::tuple>(); + AdcValueHolder::setupTrivialConvertFunc>(); } - - template - AdcValueHolder(std::invocable<> auto&& getter, - std::invocable&> auto&& setter, - const std::tuple& t /* tuple-of-trivially-converting-types */) - : AdcValueHolder(std::forward(getter), - std::forward(setter), - AdcValueHolder::AdcValueHolderDummyValidator>, - t) - { - } - - AdcValueHolder(const AdcValueHolder&) = default; AdcValueHolder(AdcValueHolder&&) = default; @@ -227,29 +216,17 @@ public: } - template - AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter, - std::invocable&> auto&& setter, - std::predicate&> auto&& validator, - const std::tuple& /* tuple-of-trivially-converting-types */) + template >)> + AdcValueHolder& resetValueHolder(traits::adc_tuple_like<> auto&& tpl, + GT&& getter, + std::invocable&> auto&& setter, + VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator>) { - resetValueHolder(std::forward(getter), std::forward(setter), - std::forward(validator)); - // setup trivially-defined conversion function - setupTrivialConvertFunc, std::tuple>(); + AdcValueHolder::setupTrivialConvertFunc, std::decay_t>(); - return *this; - } - - - template - AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter, - std::invocable&> auto&& setter, - const std::tuple& t /* tuple-of-trivially-converting-types */) - { return resetValueHolder(std::forward(getter), std::forward(setter), - AdcValueHolder::AdcValueHolderDummyValidator>, t); + std::forward(validator)); } @@ -425,43 +402,24 @@ public: template , - typename VT, + typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator), typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize), - typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize), - typename... Ts> - AdcSerializingValueHolder(GT&& getter, + typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize)> + AdcSerializingValueHolder(traits::adc_tuple_like<> auto&& tpl, + GT&& getter, ST&& setter, - VT&& validator, - const std::tuple&, + VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator, SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize, DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) - : AdcValueHolder(std::forward(getter), - std::forward(setter), - std::forward(validator), - std::tuple{}) + requires std::invocable && std::invocable && std::predicate && + std::invocable && std::invocable + : AdcSerializingValueHolder(std::forward(getter), + std::forward(setter), + std::forward(validator), + std::forward(serializer), + std::forward(deserializer)) { - initWrappers(std::forward(serializer), std::forward(deserializer)); - } - - - - template , - typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize), - typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize), - typename... Ts> - AdcSerializingValueHolder(GT&& getter, - ST&& setter, - const std::tuple&, - SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize, - DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) - : AdcValueHolder(std::forward(getter), - std::forward(setter), - AdcValueHolder::AdcValueHolderDummyValidator, - std::tuple{}) - { - initWrappers(std::forward(serializer), std::forward(deserializer)); + AdcValueHolder::setupTrivialConvertFunc>(); } @@ -494,44 +452,24 @@ public: typename ST, typename VT, typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize>), - typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize, SerializedT>), - typename... Ts> + typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize, SerializedT>)> AdcSerializingValueHolder& resetValueHolder( + traits::adc_tuple_like<> auto&& tpl, GT&& getter, ST&& setter, VT&& validator, - const std::tuple&, SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize>, DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize, SerializedT>) { - AdcValueHolder::resetValueHolder(std::forward(getter), std::forward(setter), - std::forward(validator), std::tuple{}); + AdcSerializingValueHolder::resetValueHolder(std::forward(getter), std::forward(setter), + std::forward(validator), std::forward(serializer), + std::forward(deserializer)); - initWrappers>(std::forward(serializer), std::forward(deserializer)); + AdcValueHolder::setupTrivialConvertFunc, std::decay_t>(); return *this; } - template ::serialize>), - typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize, SerializedT>), - typename... Ts> - AdcSerializingValueHolder& resetValueHolder( - GT&& getter, - ST&& setter, - const std::tuple&, - SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize>, - DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize, SerializedT>) - { - AdcValueHolder::resetValueHolder(std::forward(getter), std::forward(setter), std::tuple{}); - - initWrappers>(std::forward(serializer), std::forward(deserializer)); - - return *this; - } - - SerializedT serialize() { return _serializerWrapper(); } void deserialize(const SerializedT& sval) { _deserializerWrapper(sval); } @@ -560,8 +498,8 @@ HolderT makeArithmValue(GT&& getter, static_assert(std::is_arithmetic_v, "GETTER MUST RETURN AN ARITHMETIC TYPE VALUE!!!"); - return HolderT(std::forward(getter), std::forward(setter), - std::forward(validator), AdcValueHolder::_defaultTrivialConvTypes, + return HolderT(AdcValueHolder::_defaultTrivialConvTypes, std::forward(getter), + std::forward(setter), std::forward(validator), std::forward(other_ctor_args)...); } diff --git a/device/adc_device_attribute.h b/device/adc_device_attribute.h index 1045610..4fdd8c2 100644 --- a/device/adc_device_attribute.h +++ b/device/adc_device_attribute.h @@ -81,6 +81,26 @@ public: } + template , + typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize)> + AdcDeviceAttribute(const IdentT& ident, + traits::adc_tuple_like<> auto&& tpl, + GT&& getter, + SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize) + requires std::invocable && std::invocable + : AdcDeviceAttribute(ident, + std::forward(tpl), + std::forward(getter), + AdcDeviceAttribute::DummySetter, + AdcValueHolder::AdcValueHolderDummyValidator, + std::forward(serializer), + AdcDeviceAttribute::DummyDeserializer) + { + _accessType = ReadOnly; + } + + // write-only attribute constructor template >, @@ -101,6 +121,27 @@ public: } + template >, + typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize)> + AdcDeviceAttribute(const IdentT& ident, + traits::adc_tuple_like<> auto&& tpl, + ST&& setter, + std::predicate auto&& validator, + DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) + requires std::invocable + : AdcDeviceAttribute(ident, + std::forward(tpl), + AdcDeviceAttribute::DummyGetter, + std::forward(setter), + std::forward(validator), + AdcDeviceAttribute::DummySerializer, + std::forward(deserializer)) + { + _accessType = WriteOnly; + } + + virtual ~AdcDeviceAttribute() = default; diff --git a/tests/adc_devattr_test.cpp b/tests/adc_devattr_test.cpp index 4497f2e..dfc38f0 100644 --- a/tests/adc_devattr_test.cpp +++ b/tests/adc_devattr_test.cpp @@ -32,13 +32,15 @@ TEST_CASE("[ADC DEVICE ATTRIBUTE]") using attr_t = AdcDeviceAttribute; - // attr_t attr(AdcValueHolder::_defaultTrivialConvTypes, "ATTR_A", attr_t::ReadWrite, vv::getter, vv::setter, - // vv::validator); - attr_t attr("ATTR_A", vv::getter, vv::setter, vv::validator, AdcValueHolder::_defaultTrivialConvTypes); + attr_t attr("ATTR_A", AdcValueHolder::_defaultTrivialConvTypes, vv::getter, vv::setter, vv::validator); attr = 10.7; av = attr; std::cout << "ATTR = " << av << "\n"; // std::cout << "ATTR = " << (unsigned)attr << "\n"; + + attr_t aw("ATTR_WO", AdcValueHolder::_defaultTrivialConvTypes, vv::setter, vv::validator); + + std::cout << "ACC_TYPE: " << aw.accessType() << "\n"; } diff --git a/tests/adc_valueholder_test.cpp b/tests/adc_valueholder_test.cpp index 0a68ec7..958b971 100644 --- a/tests/adc_valueholder_test.cpp +++ b/tests/adc_valueholder_test.cpp @@ -46,7 +46,8 @@ TEST_CASE("[ADC VALUEHOLDER]") return true; }; - adc::AdcValueHolder vht(getter, setter, adc::AdcValueHolder::_defaultTrivialConvTypes); + // adc::AdcValueHolder vht(getter, setter, adc::AdcValueHolder::_defaultTrivialConvTypes); + adc::AdcValueHolder vht(adc::AdcValueHolder::_defaultTrivialConvTypes, getter, setter); adc::AdcValueHolder vh(getter, setter, validator); // auto vah = adc::make_arith_valueholder(getter, setter); auto vah = adc::makeArithmValue(getter, setter); @@ -178,7 +179,8 @@ TEST_CASE("[ADC VALUEHOLDER]") - adc::AdcSerializingValueHolder svh(getter, setter, validator, adc::AdcValueHolder::_defaultTrivialConvTypes); + // adc::AdcSerializingValueHolder svh(getter, setter, validator, adc::AdcValueHolder::_defaultTrivialConvTypes); + adc::AdcSerializingValueHolder svh(adc::AdcValueHolder::_defaultTrivialConvTypes, getter, setter, validator); svh = 77.65412; @@ -193,7 +195,8 @@ TEST_CASE("[ADC VALUEHOLDER]") // fl = vsh; // std::cout << "VSH: " << fl << "\n"; - svh.resetValueHolder(gdbl, sdbl, vdbl, adc::AdcValueHolder::_defaultTrivialConvTypes); + // svh.resetValueHolder(gdbl, sdbl, vdbl, adc::AdcValueHolder::_defaultTrivialConvTypes); + svh.resetValueHolder(adc::AdcValueHolder::_defaultTrivialConvTypes, gdbl, sdbl, vdbl); // svh.resetValueHolder([]() { return dbl_val; }, [](const double& v) { dbl_val = v; }, // [](const double&) { return true; }, adc::AdcValueHolder::_defaultTrivialConvTypes); std::cout << "SERIALIZED: " << svh.serialize() << "\n";