This commit is contained in:
2026-07-17 13:15:20 +03:00
parent 49734de1c4
commit fd21fbfe1d
2 changed files with 98 additions and 49 deletions

View File

@@ -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<std::string> 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;
}

View File

@@ -366,63 +366,92 @@ public:
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!");
auto from_cnv_func = [](adclib_attr_conv_from_func_c<v_t> auto&& conv_from,
adclib_attr_conv_to_func_c<v_t> auto&& conv_to) {
using u_t = adclib_attr_user_deduced_t<v_t, decltype(conv_from), decltype(conv_to)>;
return [conv_from_cap = std::forward<decltype(conv_from)>(conv_from),
conv_to_cap =
std::forward<decltype(conv_to)>(conv_to)](attr_t<v_t> const& attr) mutable -> attr_t<u_t> {
return attr_t<u_t>{.getter = [&attr, conv_from_cap_cap = std::forward<decltype(conv_from_cap)>(
conv_from_cap)]() mutable -> adc_result_t<u_t> {
return conv_from_cap_cap(attr.getter());
},
.setter = [&attr, conv_to_cap_cap = std::forward<decltype(conv_to_cap)>(
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<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 {
auto&& tp = std::forward_as_tuple(std::forward<FuncTs>(cnv_pairs_cap)...);
// static_assert(
// std::disjunction_v<adclib_is_deduced_void_t<std::tuple_element_t<Is * 2,
// decltype(tp)>,
// std::tuple_element_t<Is * 2 +
// 1, decltype(tp)>>...>,
// "Getter and setter cannot be nullptr_t at the same time!");
auto from_cnv_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT const& func_tp) {
using from_fn_t = std::decay_t<std::tuple_element_t<I, TpT>>;
using to_fn_t = std::decay_t<std::tuple_element_t<I + 1, TpT>>;
using u_t = typename adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>::value_type;
return [&func_tp](attr_t<v_t> const& attr) mutable -> attr_t<u_t> {
return attr_t<u_t>{
.getter = [&attr, &func_tp]() mutable -> adc_result_t<u_t> {
return std::forward<std::tuple_element_t<I, TpT>>(std::get<I>(func_tp))(attr.getter());
},
.setter = [&attr, &func_tp](u_t const& uv) mutable -> adc_error_t {
auto val = std::forward<std::tuple_element_t<I + 1, TpT>>(std::get<I + 1>(func_tp))(uv);
if (val) {
return attr.setter(val.value());
} else {
return val.error();
}
}};
};
};
};
// auto from_cnv_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT&& func_tp) {
// using tp_t = std::remove_cvref_t<TpT>;
auto to_cnv_func = [id, this](adclib_attr_conv_from_func_c<v_t> auto&& conv_from,
adclib_attr_conv_to_func_c<v_t> auto&& conv_to) {
using u_t = adclib_attr_user_deduced_t<v_t, decltype(conv_from), decltype(conv_to)>;
// 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>>;
return [id, this](attr_t<u_t> const&) -> attr_t<v_t> { return _attrs.template get<attr_t<v_t>>(id); };
};
// using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
std::apply([this](auto&&... args) { _attrs.pushWithCnv(std::forward<decltype(args)>(args)...); },
std::tuple_cat(std::forward_as_tuple(id, getter, setter),
[... cnv_pairs_cap = std::forward<FuncTs>(cnv_pairs), from_cnv_func, to_cnv_func, id,
this]<size_t... Is>(std::index_sequence<Is...>) mutable {
auto&& tp = std::forward_as_tuple(std::forward<FuncTs>(cnv_pairs_cap)...);
// return [func_tp_cap = std::forward<TpT>(func_tp)](attr_t<v_t> const& attr) mutable -> attr_t<u_t> {
// using tp_cap_t = decltype(func_tp_cap);
// return attr_t<u_t>{.getter = [&attr, func_tp_cap_cap = std::forward<tp_cap_t>(
// func_tp_cap)]() mutable -> adc_result_t<u_t> {
// using tp_cap_cap_t = decltype(func_tp_cap_cap);
// return std::forward<std::tuple_element_t<I, tp_cap_cap_t>>(
// std::get<I>(std::forward<tp_cap_cap_t>(func_tp_cap_cap)))(attr.getter());
// },
// .setter = [&attr, func_tp_cap_cap = std::forward<tp_cap_t>(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<adclib_is_deduced_void_t<std::tuple_element_t<Is * 2,
// decltype(tp)>,
// std::tuple_element_t<Is * 2 +
// 1, decltype(tp)>>...>,
// "Getter and setter cannot be nullptr_t at the same time!");
// auto val = std::forward<std::tuple_element_t<I + 1, tp_cap_cap_t>>(
// std::get<I + 1>(std::forward<tp_cap_cap_t>(func_tp_cap_cap)))(uv);
// return std::forward_as_tuple(
// [](attr_t<v_t> const& av)
// -> adclib_attr_value_deduced_t<std::tuple_element_t<Is * 2,
// decltype(tp)>,
// std::tuple_element_t<Is * 2 + 1,
// decltype(tp)>>
// {}...);
// if (val) {
// return attr.setter(val.value());
// } else {
// return val.error();
// }
// }};
// };
// };
return std::forward_as_tuple(
from_cnv_func(std::get<Is * 2>(tp), std::get<Is * 2 + 1>(tp))...,
to_cnv_func(std::get<Is * 2>(tp), std::get<Is * 2 + 1>(tp))...);
// (from_cnv_func(std::get<Is * 2>(tp), std::get<Is * 2 + 1>(tp)),
// to_cnv_func(std::get<Is * 2>(tp), std::get<Is * 2 + 1>(tp)))...);
}(std::make_index_sequence<NFUNCS / 2>{})));
auto to_cnv_func = [id, this]<size_t I, snplib::snplib_tuple_c TpT>(TpT const& func_tp) {
using from_fn_t = std::decay_t<std::tuple_element_t<I, TpT>>;
using to_fn_t = std::decay_t<std::tuple_element_t<I + 1, TpT>>;
using u_t = typename adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>::value_type;
return [id, this](attr_t<u_t> const&) -> attr_t<v_t> {
return _attrs.template get<attr_t<v_t>>(id).value();
};
};
std::apply(
[this](auto&&... args) { _attrs.pushWithCnv(std::forward<decltype(args)>(args)...); },
std::tuple_cat(
std::forward_as_tuple(id, attr_t<v_t>{.getter = std::forward<decltype(getter_cap)>(getter_cap),
.setter = std::forward<decltype(setter_cap)>(setter_cap)}),
std::tuple_cat(std::forward_as_tuple(from_cnv_func.template operator()<Is>(tp),
to_cnv_func.template operator()<Is>(tp))...)));
}(std::make_index_sequence<NFUNCS / 2>{});
}
// add attribute of one of arithmetic type