...
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user