From fd21fbfe1dadea56a52e85728f0c1763490c44b6 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Fri, 17 Jul 2026 13:15:20 +0300 Subject: [PATCH] ... --- examples/device_exam.cpp | 20 ++++++ include/adclib/adclib_device.h | 127 ++++++++++++++++++++------------- 2 files changed, 98 insertions(+), 49 deletions(-) diff --git a/examples/device_exam.cpp b/examples/device_exam.cpp index 36c4ed9..0aa3d10 100644 --- a/examples/device_exam.cpp +++ b/examples/device_exam.cpp @@ -92,5 +92,25 @@ int main() std::println("cannot set dev[{}] as double: {}", id2, err.message()); } + std::println("\n"); + + std::print("get '{}'-attr value as native string:\t", id3); + adc_result_t rs = dev[id3]; + if (rs) { + std::println("dev[{}] = {}", id3, rs.value()); + } else { + std::println("cannot get dev[{}] as string: {}", id3, rs.error().message()); + } + + const char* sp = "QWERTY"; + std::print("set '{}'-attr value to '{}' as const char*:\t", id3, sp); + err = dev[id3] = sp; + if (err) { + std::println("cannot set dev[{}] as const char*: {}", id3, err.message()); + } else { + std::println("OK"); + } + + return 0; } \ No newline at end of file diff --git a/include/adclib/adclib_device.h b/include/adclib/adclib_device.h index d208eab..86c116d 100644 --- a/include/adclib/adclib_device.h +++ b/include/adclib/adclib_device.h @@ -366,63 +366,92 @@ public: 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!"); - auto from_cnv_func = [](adclib_attr_conv_from_func_c auto&& conv_from, - adclib_attr_conv_to_func_c auto&& conv_to) { - using u_t = adclib_attr_user_deduced_t; - return [conv_from_cap = std::forward(conv_from), - conv_to_cap = - std::forward(conv_to)](attr_t const& attr) mutable -> attr_t { - return attr_t{.getter = [&attr, conv_from_cap_cap = std::forward( - conv_from_cap)]() mutable -> adc_result_t { - return conv_from_cap_cap(attr.getter()); - }, - .setter = [&attr, conv_to_cap_cap = std::forward( - conv_to_cap)](u_t const& uv) mutable -> adc_error_t { - auto val = conv_to_cap_cap(uv); - if (val) { - return attr.setter(val.value()); - } else { - return std::unexpected(val.error()); - } - }}; + + [... cnv_pairs_cap = std::forward(cnv_pairs), id, getter_cap = std::forward(getter), + setter_cap = std::forward(setter), this](std::index_sequence) mutable { + auto&& tp = std::forward_as_tuple(std::forward(cnv_pairs_cap)...); + + // static_assert( + // std::disjunction_v, + // std::tuple_element_t>...>, + // "Getter and setter cannot be nullptr_t at the same time!"); + + auto from_cnv_func = [](TpT const& func_tp) { + using from_fn_t = std::decay_t>; + using to_fn_t = std::decay_t>; + + using u_t = typename adclib_attr_user_deduced_t::value_type; + + return [&func_tp](attr_t const& attr) mutable -> attr_t { + return attr_t{ + .getter = [&attr, &func_tp]() mutable -> adc_result_t { + return std::forward>(std::get(func_tp))(attr.getter()); + }, + .setter = [&attr, &func_tp](u_t const& uv) mutable -> adc_error_t { + auto val = std::forward>(std::get(func_tp))(uv); + + if (val) { + return attr.setter(val.value()); + } else { + return val.error(); + } + }}; + }; }; - }; + // auto from_cnv_func = [](TpT&& func_tp) { + // using tp_t = std::remove_cvref_t; - auto to_cnv_func = [id, this](adclib_attr_conv_from_func_c auto&& conv_from, - adclib_attr_conv_to_func_c auto&& conv_to) { - using u_t = adclib_attr_user_deduced_t; + // using from_fn_t = std::decay_t>; + // using to_fn_t = std::decay_t>; - return [id, this](attr_t const&) -> attr_t { return _attrs.template get>(id); }; - }; + // using u_t = adclib_attr_user_deduced_t; - std::apply([this](auto&&... args) { _attrs.pushWithCnv(std::forward(args)...); }, - std::tuple_cat(std::forward_as_tuple(id, getter, setter), - [... cnv_pairs_cap = std::forward(cnv_pairs), from_cnv_func, to_cnv_func, id, - this](std::index_sequence) mutable { - auto&& tp = std::forward_as_tuple(std::forward(cnv_pairs_cap)...); + // return [func_tp_cap = std::forward(func_tp)](attr_t const& attr) mutable -> attr_t { + // using tp_cap_t = decltype(func_tp_cap); + // return attr_t{.getter = [&attr, func_tp_cap_cap = std::forward( + // func_tp_cap)]() mutable -> adc_result_t { + // using tp_cap_cap_t = decltype(func_tp_cap_cap); + // return std::forward>( + // std::get(std::forward(func_tp_cap_cap)))(attr.getter()); + // }, + // .setter = [&attr, func_tp_cap_cap = std::forward(func_tp_cap)]( + // u_t const& uv) mutable -> adc_error_t { + // using tp_cap_cap_t = decltype(func_tp_cap_cap); - // static_assert( - // std::disjunction_v, - // std::tuple_element_t>...>, - // "Getter and setter cannot be nullptr_t at the same time!"); + // auto val = std::forward>( + // std::get(std::forward(func_tp_cap_cap)))(uv); - // return std::forward_as_tuple( - // [](attr_t const& av) - // -> adclib_attr_value_deduced_t, - // std::tuple_element_t> - // {}...); + // if (val) { + // return attr.setter(val.value()); + // } else { + // return val.error(); + // } + // }}; + // }; + // }; - return std::forward_as_tuple( - from_cnv_func(std::get(tp), std::get(tp))..., - to_cnv_func(std::get(tp), std::get(tp))...); - // (from_cnv_func(std::get(tp), std::get(tp)), - // to_cnv_func(std::get(tp), std::get(tp)))...); - }(std::make_index_sequence{}))); + auto to_cnv_func = [id, this](TpT const& func_tp) { + using from_fn_t = std::decay_t>; + using to_fn_t = std::decay_t>; + + using u_t = typename adclib_attr_user_deduced_t::value_type; + + return [id, this](attr_t const&) -> attr_t { + return _attrs.template get>(id).value(); + }; + }; + + std::apply( + [this](auto&&... args) { _attrs.pushWithCnv(std::forward(args)...); }, + std::tuple_cat( + std::forward_as_tuple(id, attr_t{.getter = std::forward(getter_cap), + .setter = std::forward(setter_cap)}), + std::tuple_cat(std::forward_as_tuple(from_cnv_func.template operator()(tp), + to_cnv_func.template operator()(tp))...))); + }(std::make_index_sequence{}); } // add attribute of one of arithmetic type