This commit is contained in:
2026-09-14 16:07:12 +03:00
parent 39fa33b472
commit 787005880c

View File

@@ -347,7 +347,7 @@ public:
using tp_t = std::tuple<UTs...>; using tp_t = std::tuple<UTs...>;
[&id, getter_cap = std::forward<GT>(getter), setter_cap = std::forward<ST>(setter), [id = std::move(id), getter_cap = std::forward<GT>(getter), setter_cap = std::forward<ST>(setter),
this]<size_t... Is>(std::index_sequence<Is...>) mutable { this]<size_t... Is>(std::index_sequence<Is...>) mutable {
return std::apply( return std::apply(
[this](auto&&... args) { addAttr(std::forward<decltype(args)>(args)...); }, [this](auto&&... args) { addAttr(std::forward<decltype(args)>(args)...); },
@@ -374,6 +374,115 @@ public:
using v_t = adclib_attr_value_deduced_t<GT, ST>; using v_t = adclib_attr_value_deduced_t<GT, ST>;
static_assert(!std::is_void_v<v_t>, "Getter and setter cannot be nullptr_t at the same time!"); static_assert(!std::is_void_v<v_t>, "Getter and setter cannot be nullptr_t at the same time!");
[id = std::move(id), getter_cap = std::forward<GT>(getter), setter_cap = std::forward<ST>(setter),
tp = std::forward_as_tuple(std::forward<FuncTs>(cnv_pairs)...),
this]<size_t... Is>(std::index_sequence<Is...>) mutable {
//
auto gt_cnv_from_func = [tp]<size_t I>() {
using tp_t = decltype(tp);
using from_fn_t = std::decay_t<std::tuple_element_t<I, tp_t>>;
using to_fn_t = std::decay_t<std::tuple_element_t<I + 1, tp_t>>;
using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
return [tp = std::move(tp)](attr_getter_t<v_t> const& gt) -> adc_result_t<attr_getter_t<u_t>> {
return [tp = std::move(tp), &gt]() -> adc_result_t<u_t> {
auto v = gt();
if (v) {
// convert from inner type to user's ("convert-from" function)
// it returns adc_result_t<u_t>
return std::forward<std::tuple_element_t<I, tp_t>>(std::get<I>(tp))(v.value());
}
return std::unexpected(v.error());
};
};
};
auto st_cnv_from_func = [tp]<size_t I>() {
using tp_t = decltype(tp);
using from_fn_t = std::decay_t<std::tuple_element_t<I, tp_t>>;
using to_fn_t = std::decay_t<std::tuple_element_t<I + 1, tp_t>>;
using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
return [tp = std::move(tp)](attr_setter_t<v_t> const& st) -> adc_result_t<attr_setter_t<u_t>> {
return [tp = std::move(tp), &st](u_t const& uval) -> adc_error_t {
// convert from user type to inner ("convert-to" function)!
auto val = std::forward<std::tuple_element_t<I + 1, tp_t>>(std::get<I + 1>(tp))(uval);
if (val) {
return st(val.value());
}
return val.error();
};
};
};
auto gt_cnv_to_func = [tp]<size_t I>() {
using tp_t = decltype(tp);
using from_fn_t = std::decay_t<std::tuple_element_t<I, tp_t>>;
using to_fn_t = std::decay_t<std::tuple_element_t<I + 1, tp_t>>;
using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
return [tp = std::move(tp)](attr_getter_t<u_t> const& gt) -> adc_result_t<attr_getter_t<v_t>> {
return [tp = std::move(tp), &gt]() -> adc_result_t<v_t> {
auto uv = gt();
if (uv) {
// convert to inner type from user's ("convert-to" function)
// it returns adc_result_t<v_t>
return std::forward<std::tuple_element_t<I + 1, tp_t>>(std::get<I + 1>(tp))(uv.value());
}
return std::unexpected(uv.error());
};
};
};
auto st_cnv_to_func = [tp]<size_t I>() {
using tp_t = decltype(tp);
using from_fn_t = std::decay_t<std::tuple_element_t<I, tp_t>>;
using to_fn_t = std::decay_t<std::tuple_element_t<I + 1, tp_t>>;
using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
return [tp = std::move(tp)](attr_setter_t<u_t> const& st) -> adc_result_t<attr_setter_t<v_t>> {
return [tp = std::move(tp), &st](v_t const& val) -> adc_error_t {
// convert to user type from inner ("convert-from" function)!
auto uval = std::forward<std::tuple_element_t<I, tp_t>>(std::get<I>(tp))(val);
if (uval) {
return st(uval.value());
}
return uval.error();
};
};
};
std::apply(
[this](auto&&... args) { _attrGetter.push(std::forward<decltype(args)>(args)...); },
std::tuple_cat(
std::forward_as_tuple(id, attr_getter_t<v_t>(std::forward<decltype(getter_cap)>(getter_cap))),
std::tuple_cat(std::forward_as_tuple(gt_cnv_from_func.template operator()<2 * Is>(),
gt_cnv_to_func.template operator()<2 * Is>())...)));
std::apply(
[this](auto&&... args) { _attrSetter.push(std::forward<decltype(args)>(args)...); },
std::tuple_cat(
std::forward_as_tuple(id, attr_setter_t<v_t>(std::forward<decltype(setter_cap)>(setter_cap))),
std::tuple_cat(std::forward_as_tuple(st_cnv_from_func.template operator()<2 * Is>(),
st_cnv_to_func.template operator()<2 * Is>())...)));
}(std::make_index_sequence<std::tuple_size_v<AdcGenericDevice::char_ranges_t>>{});
return;
[... cnv_pairs_cap = std::forward<FuncTs>(cnv_pairs), id, getter_cap = std::forward<GT>(getter), [... cnv_pairs_cap = std::forward<FuncTs>(cnv_pairs), id, getter_cap = std::forward<GT>(getter),
setter_cap = std::forward<ST>(setter), this]<size_t... Is>(std::index_sequence<Is...>) mutable { setter_cap = std::forward<ST>(setter), this]<size_t... Is>(std::index_sequence<Is...>) mutable {
auto tp = std::forward_as_tuple(std::forward<FuncTs>(cnv_pairs_cap)...); auto tp = std::forward_as_tuple(std::forward<FuncTs>(cnv_pairs_cap)...);