...
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#include <print>
|
#include <print>
|
||||||
|
|
||||||
#include <adclib/adclib_device.h>
|
#include <adclib/adclib_device1.h>
|
||||||
|
|
||||||
using namespace adc;
|
using namespace adc;
|
||||||
|
|
||||||
@@ -39,12 +39,15 @@ int main()
|
|||||||
s = sv;
|
s = sv;
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
[&s](adc_result_t<std::string> const&) -> adc_result_t<const char*> { return s.c_str(); },
|
[](std::string const& v) -> adc_result_t<const char*> { return v.c_str(); },
|
||||||
[&s](adc_result_t<const char*> const& p) mutable -> adc_result_t<std::string> {
|
[](const char* p) -> adc_result_t<std::string> { return std::string(p); }
|
||||||
// s = p.value();
|
// [&s](adc_result_t<std::string> const&) -> adc_result_t<const char*> { return s.c_str(); },
|
||||||
// return s;
|
// [&s](adc_result_t<const char*> const& p) mutable -> adc_result_t<std::string> {
|
||||||
return std::string(p.value());
|
// // s = p.value();
|
||||||
});
|
// // return s;
|
||||||
|
// return std::string(p.value());
|
||||||
|
// }
|
||||||
|
);
|
||||||
|
|
||||||
std::print("get '{}'-attr value as native int:\t", id1);
|
std::print("get '{}'-attr value as native int:\t", id1);
|
||||||
adc_result_t<int> ri = dev[id1];
|
adc_result_t<int> ri = dev[id1];
|
||||||
|
|||||||
@@ -132,12 +132,12 @@ struct adclib_is_deduced_void_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// conversional function signature:
|
// conversional function signature:
|
||||||
// "from": adc_result_t<UT> func(const adc_result_t<VT>&)
|
// "from": adc_result_t<UT> func(const VT&)
|
||||||
// "to": adc_result_t<VT> func(const adc_result_t<UT>&)
|
// "to": adc_result_t<VT> func(const UT&)
|
||||||
template <typename T, typename VT>
|
template <typename T, typename VT>
|
||||||
concept adclib_attr_conv_from_func_c =
|
concept adclib_attr_conv_from_func_c =
|
||||||
std::same_as<T, std::nullptr_t> ||
|
std::same_as<T, std::nullptr_t> ||
|
||||||
(std::invocable<T, const adc_result_t<VT>&> && !std::is_void_v<std::invoke_result_t<T, const adc_result_t<VT>&>>);
|
(std::invocable<T, const VT&> && !std::is_void_v<std::invoke_result_t<T, const VT&>>);
|
||||||
|
|
||||||
template <typename T, typename VT>
|
template <typename T, typename VT>
|
||||||
concept adclib_attr_conv_to_func_c = std::same_as<T, std::nullptr_t> ||
|
concept adclib_attr_conv_to_func_c = std::same_as<T, std::nullptr_t> ||
|
||||||
@@ -150,7 +150,7 @@ using adclib_attr_user_deduced_t =
|
|||||||
std::conditional_t<std::is_null_pointer_v<CONV_TO_T>,
|
std::conditional_t<std::is_null_pointer_v<CONV_TO_T>,
|
||||||
void,
|
void,
|
||||||
std::remove_cvref_t<snplib::snplib_func_arg1_t<CONV_TO_T>>>,
|
std::remove_cvref_t<snplib::snplib_func_arg1_t<CONV_TO_T>>>,
|
||||||
typename snplib::snplib_func_traits_t<CONV_FROM_T>::ret_t>;
|
typename snplib::snplib_func_traits_t<CONV_FROM_T>::ret_t::value_type>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getter.error() == snplib::HeterogenMap<ATTR_ID_T>::ERROR_NO_ELEM) {
|
if (getter.error() == snplib::hmap_error_e::ERROR_INVALID_KEY) {
|
||||||
return std::unexpected(AdcDeviceErrorCode::ERROR_NO_ATTR_ID);
|
return std::unexpected(AdcDeviceErrorCode::ERROR_NO_ATTR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setter.error() == snplib::HeterogenMap<ATTR_ID_T>::ERROR_NO_ELEM) {
|
if (setter.error() == snplib::hmap_error_e::ERROR_INVALID_KEY) {
|
||||||
return AdcDeviceErrorCode::ERROR_NO_ATTR_ID;
|
return AdcDeviceErrorCode::ERROR_NO_ATTR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,8 +223,10 @@ protected:
|
|||||||
std::unordered_map<CMD_ID_T, std::function<adc_error_t()>> _commands{};
|
std::unordered_map<CMD_ID_T, std::function<adc_error_t()>> _commands{};
|
||||||
std::unordered_map<ATTR_ID_T, attr_t> _attrs{};
|
std::unordered_map<ATTR_ID_T, attr_t> _attrs{};
|
||||||
|
|
||||||
snplib::HeterogenMap<ATTR_ID_T> _attrGetter{};
|
// snplib::HeterogenMap<ATTR_ID_T> _attrGetter{};
|
||||||
snplib::HeterogenMap<ATTR_ID_T> _attrSetter{};
|
// snplib::HeterogenMap<ATTR_ID_T> _attrSetter{};
|
||||||
|
snplib::hmap<ATTR_ID_T> _attrGetter{};
|
||||||
|
snplib::hmap<ATTR_ID_T> _attrSetter{};
|
||||||
|
|
||||||
|
|
||||||
template <typename GT, typename UGT>
|
template <typename GT, typename UGT>
|
||||||
@@ -314,11 +316,29 @@ public:
|
|||||||
static_assert(std::invocable<ST, v_t const&>, "Invalid setter argument type!");
|
static_assert(std::invocable<ST, v_t const&>, "Invalid setter argument type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
_attrGetter.push(id, attr_getter_t<std::remove_cvref_t<GT>>(std::forward<GT>(getter)),
|
using tp_t = std::tuple<UTs...>;
|
||||||
std::tuple<attr_getter_t<UTs>...>{});
|
|
||||||
|
|
||||||
_attrSetter.push(id, attr_setter_t<std::remove_cvref_t<ST>>(std::forward<ST>(setter)),
|
[&id, getter_cap = std::forward<GT>(getter), setter_cap = std::forward<ST>(setter),
|
||||||
std::tuple<attr_setter_t<UTs>...>{});
|
this]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||||
|
return std::apply(
|
||||||
|
[this](auto&&... args) { addAttr(std::forward<decltype(args)>(args)...); },
|
||||||
|
std::tuple_cat(
|
||||||
|
std::forward_as_tuple(id, std::forward<decltype(getter_cap)>(getter_cap),
|
||||||
|
std::forward<decltype(setter_cap)>(setter_cap)),
|
||||||
|
std::tuple_cat(std::forward_as_tuple(
|
||||||
|
decltype(_attrGetter)::template trivial_conv_from<v_t, std::tuple_element_t<Is, tp_t>>,
|
||||||
|
decltype(_attrGetter)::template trivial_conv_to<v_t, std::tuple_element_t<Is, tp_t>>)...)));
|
||||||
|
}(std::make_index_sequence<sizeof...(UTs)>{});
|
||||||
|
|
||||||
|
// [&id, setter_cap = std::forward<ST>(setter), this]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||||
|
// return std::apply(
|
||||||
|
// [this](auto&&... args) { addAttr(std::forward<decltype(args)>(args)...); },
|
||||||
|
// std::tuple_cat(
|
||||||
|
// std::forward_as_tuple(id, std::forward<decltype(setter_cap)>(setter_cap)),
|
||||||
|
// std::tuple_cat(std::forward_as_tuple(
|
||||||
|
// decltype(_attrSetter)::template trivial_conv_from<v_t, std::tuple_element_t<Is, tp_t>>,
|
||||||
|
// decltype(_attrSetter)::template trivial_conv_to<v_t, std::tuple_element_t<Is, tp_t>>)...)));
|
||||||
|
// }(std::make_index_sequence<sizeof...(UTs)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -340,9 +360,13 @@ public:
|
|||||||
auto tp = std::forward_as_tuple(std::forward<FuncTs>(cnv_pairs_cap)...);
|
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) {
|
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;
|
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>>;
|
||||||
|
|
||||||
static_assert(requires(v_t v, u_t u) { u = v; }, "Invalid deduced user type!");
|
// using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
|
||||||
|
using u_t = std::invoke_result_t<from_fn_t>::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](attr_getter_t<v_t> const& gt) -> adc_result_t<attr_getter_t<u_t>> {
|
||||||
return [&tpl, >]() -> adc_result_t<u_t> {
|
return [&tpl, >]() -> adc_result_t<u_t> {
|
||||||
@@ -359,9 +383,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto st_cnv_from_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT const& tpl) {
|
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;
|
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>>;
|
||||||
|
|
||||||
static_assert(requires(v_t v, u_t u) { u = v; }, "Invalid deduced user type!");
|
using u_t = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
|
||||||
|
|
||||||
|
// 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](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 {
|
return [&tpl, &st](u_t const& uval) -> adc_error_t {
|
||||||
@@ -371,12 +398,105 @@ public:
|
|||||||
return st(val.value());
|
return st(val.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::unexpected(val.error());
|
return val.error();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto gt_cnv_to_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT const& tpl) {
|
||||||
|
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 = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
|
||||||
|
|
||||||
|
// static_assert(requires(v_t v, u_t u) { v = u; }, "Invalid deduced user type!");
|
||||||
|
|
||||||
|
return [&tpl](attr_getter_t<u_t> const& gt) -> adc_result_t<attr_getter_t<v_t>> {
|
||||||
|
return [&tpl, >]() -> 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, TpT>>(std::get<I + 1>(tpl))(uv.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unexpected(uv.error());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto st_cnv_to_func = []<size_t I, snplib::snplib_tuple_c TpT>(TpT const& tpl) {
|
||||||
|
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 = adclib_attr_user_deduced_t<v_t, from_fn_t, to_fn_t>;
|
||||||
|
|
||||||
|
// static_assert(requires(v_t v, u_t u) { v = u; }, "Invalid deduced user type!");
|
||||||
|
|
||||||
|
return [&tpl](attr_setter_t<u_t> const& st) -> adc_result_t<attr_setter_t<v_t>> {
|
||||||
|
return [&tpl, &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, TpT>>(std::get<I>(tpl))(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, std::forward<decltype(getter_cap)>(getter_cap)),
|
||||||
|
std::tuple_cat(std::forward_as_tuple(gt_cnv_from_func.template operator()<Is>(tp),
|
||||||
|
gt_cnv_to_func.template operator()<Is>(tp))...)));
|
||||||
|
|
||||||
|
std::apply(
|
||||||
|
[this](auto&&... args) { _attrSetter.push(std::forward<decltype(args)>(args)...); },
|
||||||
|
std::tuple_cat(std::forward_as_tuple(id, std::forward<decltype(setter_cap)>(setter_cap)),
|
||||||
|
std::tuple_cat(std::forward_as_tuple(st_cnv_from_func.template operator()<Is>(tp),
|
||||||
|
st_cnv_to_func.template operator()<Is>(tp))...)));
|
||||||
}(std::make_index_sequence<NFUNCS / 2>{});
|
}(std::make_index_sequence<NFUNCS / 2>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add attribute of one of arithmetic type
|
||||||
|
template <typename GT, typename ST>
|
||||||
|
requires std::is_arithmetic_v<adclib_attr_value_deduced_t<GT, ST>>
|
||||||
|
void addArithAttr(ATTR_ID_T id, GT&& getter, ST&& setter)
|
||||||
|
{
|
||||||
|
addAttr(std::move(id), std::forward<GT>(getter), std::forward<ST>(setter), AdcGenericDevice::arithmetic_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
adc_error_t operator()(CMD_ID_T id)
|
||||||
|
{
|
||||||
|
if (auto it = _commands.find(id); it != _commands.end()) {
|
||||||
|
// return (*it)();
|
||||||
|
return it->second();
|
||||||
|
}
|
||||||
|
|
||||||
|
return AdcDeviceErrorCode::ERROR_NO_CMD_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto operator[](ATTR_ID_T id)
|
||||||
|
{
|
||||||
|
return attr_t{*this, std::move(id)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function-like access to attributes
|
||||||
|
template <typename VT>
|
||||||
|
adc_result_t<VT> attr(ATTR_ID_T id)
|
||||||
|
{
|
||||||
|
return attr_t{*this, std::move(id)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VT>
|
||||||
|
adc_error_t attr(ATTR_ID_T id, VT const& v)
|
||||||
|
{
|
||||||
|
return attr_t{*this, std::move(id)} = v;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user