diff --git a/include/adclib/adclib_device1.h b/include/adclib/adclib_device1.h index 55dbb85..ba1961e 100644 --- a/include/adclib/adclib_device1.h +++ b/include/adclib/adclib_device1.h @@ -306,8 +306,8 @@ public: _commands.emplace(std::move(id), std::forward(exec_func)); } - template - void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple = std::tuple<>{}) + template + void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter) { using v_t = adclib_attr_value_deduced_t; static_assert(!std::is_void_v, "Getter and setter cannot be nullptr_t at the same time!"); @@ -316,24 +316,34 @@ public: static_assert(std::invocable, "Invalid setter argument type!"); } - if constexpr (sizeof...(UTs)) { - using tp_t = std::tuple; + _attrGetter.push(id, attr_getter_t(std::forward(getter))); + _attrSetter.push(id, attr_setter_t(std::forward(setter))); + } - [&id, getter_cap = std::forward(getter), setter_cap = std::forward(setter), - this](std::index_sequence) mutable { - return std::apply( - [this](auto&&... args) { addAttr(std::forward(args)...); }, - std::tuple_cat( - std::forward_as_tuple(id, std::forward(getter_cap), - std::forward(setter_cap)), - std::tuple_cat(std::forward_as_tuple( - decltype(_attrGetter)::template trivial_conv_from>, - decltype(_attrGetter)::template trivial_conv_to>)...))); - }(std::make_index_sequence{}); - } else { - _attrGetter.push(id, std::forward(getter)); - _attrSetter.push(id, std::forward(setter)); + template + requires(sizeof...(UTs) > 0) + void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple) + { + using v_t = adclib_attr_value_deduced_t; + static_assert(!std::is_void_v, "Getter and setter cannot be nullptr_t at the same time!"); + + if constexpr (!std::is_null_pointer_v && !std::is_null_pointer_v) { + static_assert(std::invocable, "Invalid setter argument type!"); } + + using tp_t = std::tuple; + + [&id, getter_cap = std::forward(getter), setter_cap = std::forward(setter), + this](std::index_sequence) mutable { + return std::apply( + [this](auto&&... args) { addAttr(std::forward(args)...); }, + std::tuple_cat( + std::forward_as_tuple(id, std::forward(getter_cap), + std::forward(setter_cap)), + std::tuple_cat(std::forward_as_tuple( + decltype(_attrGetter)::template trivial_conv_from>, + decltype(_attrGetter)::template trivial_conv_to>)...))); + }(std::make_index_sequence{}); } // @@ -358,8 +368,8 @@ public: using from_fn_t = std::decay_t>; using to_fn_t = std::decay_t>; - // using u_t = adclib_attr_user_deduced_t; - using u_t = std::invoke_result_t::value_type; + using u_t = adclib_attr_user_deduced_t; + // using u_t = std::invoke_result_t::value_type; // static_assert(requires(v_t v, u_t u) { u = v; }, "Invalid deduced user type!"); @@ -381,8 +391,8 @@ public: using from_fn_t = std::decay_t>; using to_fn_t = std::decay_t>; - // using u_t = adclib_attr_user_deduced_t; - using u_t = std::invoke_result_t::value_type; + using u_t = adclib_attr_user_deduced_t; + // using u_t = std::invoke_result_t::value_type; // static_assert(requires(v_t v, u_t u) { u = v; }, "Invalid deduced user type!"); @@ -403,8 +413,8 @@ public: using from_fn_t = std::decay_t>; using to_fn_t = std::decay_t>; - // using u_t = adclib_attr_user_deduced_t; - using u_t = std::invoke_result_t::value_type; + using u_t = adclib_attr_user_deduced_t; + // using u_t = std::invoke_result_t::value_type; // static_assert(requires(v_t v, u_t u) { v = u; }, "Invalid deduced user type!"); @@ -427,8 +437,8 @@ public: using from_fn_t = std::decay_t>; using to_fn_t = std::decay_t>; - // using u_t = adclib_attr_user_deduced_t; - using u_t = std::invoke_result_t::value_type; + using u_t = adclib_attr_user_deduced_t; + // using u_t = std::invoke_result_t::value_type; // static_assert(requires(v_t v, u_t u) { v = u; }, "Invalid deduced user type!"); @@ -446,17 +456,19 @@ public: }; }; - std::apply([this](auto&&... args) { _attrGetter.push(std::forward(args)...); }, - std::tuple_cat( - std::forward_as_tuple(id, std::forward(getter_cap)), - std::tuple_cat(std::forward_as_tuple(gt_cnv_from_func.template operator()<2 * Is>(tp), - gt_cnv_to_func.template operator()<2 * Is>(tp))...))); + std::apply( + [this](auto&&... args) { _attrGetter.push(std::forward(args)...); }, + std::tuple_cat( + std::forward_as_tuple(id, attr_getter_t(std::forward(getter_cap))), + std::tuple_cat(std::forward_as_tuple(gt_cnv_from_func.template operator()<2 * Is>(tp), + gt_cnv_to_func.template operator()<2 * Is>(tp))...))); - std::apply([this](auto&&... args) { _attrSetter.push(std::forward(args)...); }, - std::tuple_cat( - std::forward_as_tuple(id, std::forward(setter_cap)), - std::tuple_cat(std::forward_as_tuple(st_cnv_from_func.template operator()<2 * Is>(tp), - st_cnv_to_func.template operator()<2 * Is>(tp))...))); + std::apply( + [this](auto&&... args) { _attrSetter.push(std::forward(args)...); }, + std::tuple_cat( + std::forward_as_tuple(id, attr_setter_t(std::forward(setter_cap))), + std::tuple_cat(std::forward_as_tuple(st_cnv_from_func.template operator()<2 * Is>(tp), + st_cnv_to_func.template operator()<2 * Is>(tp))...))); }(std::make_index_sequence{}); }