This commit is contained in:
Timur A. Fatkhullin
2026-09-03 00:35:23 +03:00
parent c6ee8f6c5b
commit a72bd3b45a

View File

@@ -226,6 +226,40 @@ protected:
snplib::HeterogenMap<ATTR_ID_T> _attrGetter{};
snplib::HeterogenMap<ATTR_ID_T> _attrSetter{};
template <typename GT, typename UGT>
requires requires(std::invoke_result_t<GT> v, std::invoke_result_t<UGT> u) { u = v; }
inline static auto default_cnv_from_func = [](GT const& g) -> adc_result_t<UGT> {
using u_t = std::invoke_result_t<UGT>;
return [g]() -> adc_result_t<u_t> {
auto v = g();
if (v) {
return static_cast<u_t>(v.value());
}
return v.error();
};
};
template <typename GT, typename UGT>
requires requires(std::invoke_result_t<GT> v, std::invoke_result_t<UGT> u) { v = u; }
inline static auto default_cnv_to_func = [](UGT const& g) -> adc_result_t<GT> {
using v_t = std::invoke_result_t<GT>;
return [g]() -> adc_result_t<v_t> {
auto v = g();
if (v) {
return static_cast<v_t>(v.value());
}
return v.error();
};
};
public:
static constexpr std::tuple<bool,
char,
@@ -270,8 +304,8 @@ public:
_commands.emplace(std::move(id), std::forward<ET>(exec_func));
}
template <typename GT, typename ST, typename... VTs>
void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple<VTs...> = std::tuple<>{})
template <typename GT, typename ST, typename... UTs>
void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple<UTs...> = std::tuple<>{})
{
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!");
@@ -281,12 +315,15 @@ public:
}
_attrGetter.push(id, attr_getter_t<std::remove_cvref_t<GT>>(std::forward<GT>(getter)),
std::tuple<attr_getter_t<VTs>...>{});
std::tuple<attr_getter_t<UTs>...>{});
_attrSetter.push(id, attr_setter_t<std::remove_cvref_t<ST>>(std::forward<ST>(setter)),
std::tuple<attr_setter_t<VTs>...>{});
std::tuple<attr_setter_t<UTs>...>{});
}
//
// conversional functions are the same as defined in the snplib::hmap class
// (it must convert attribute values instead of getters or setters itself!)
template <adclib_attr_getter_c GT, adclib_attr_setter_c ST, typename... FuncTs>
requires(sizeof...(FuncTs) > 1)
void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, FuncTs&&... cnv_pairs)
@@ -297,6 +334,48 @@ 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!");
[... 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)...);
auto gt_cnv_from_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT const& tpl) {
using u_t = std::tuple_element_t<I, TpT>::value_type;
static_assert(requires(v_t v, u_t u) { u = v; }, "Invalid deduced user type!");
return [&tpl](attr_getter_t<v_t> const& gt) -> adc_result_t<attr_getter_t<u_t>> {
return [&tpl, &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, TpT>>(std::get<I>(tpl))(v.value());
}
return std::unexpected(v.error());
};
};
};
auto st_cnv_from_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT const& tpl) {
using u_t = std::tuple_element_t<I, TpT>::value_type;
static_assert(requires(v_t v, u_t u) { u = v; }, "Invalid deduced user type!");
return [&tpl](attr_setter_t<v_t> const& st) -> adc_result_t<attr_setter_t<u_t>> {
return [&tpl, &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, TpT>>(std::get<I + 1>(tpl))(uval);
if (val) {
return st(val.value());
}
return std::unexpected(val.error());
};
};
};
}(std::make_index_sequence<NFUNCS / 2>{});
}
};