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