...
This commit is contained in:
@@ -20,6 +20,8 @@ int main()
|
|||||||
},
|
},
|
||||||
std::tuple<double, long>{});
|
std::tuple<double, long>{});
|
||||||
|
|
||||||
|
dev.addAttr("2", [&d]() -> adc_result_t<double> { return d; }, nullptr);
|
||||||
|
|
||||||
adc_result_t<int> ri = dev["1"];
|
adc_result_t<int> ri = dev["1"];
|
||||||
if (ri) {
|
if (ri) {
|
||||||
std::println("dev[1] = {}", ri.value());
|
std::println("dev[1] = {}", ri.value());
|
||||||
@@ -39,5 +41,17 @@ int main()
|
|||||||
std::println("cannot get dev[1] as double: {}", rd.error().message());
|
std::println("cannot get dev[1] as double: {}", rd.error().message());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ri = dev["1"];
|
||||||
|
if (ri) {
|
||||||
|
std::println("dev[1] = {}", ri.value());
|
||||||
|
} else {
|
||||||
|
std::println("cannot get dev[1] as int: {}", ri.error().message());
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev["2"] = 0.29817;
|
||||||
|
if (err) {
|
||||||
|
std::println("cannot set dev[2] as double: {}", err.message());
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
// #include <snipplib/concepts/snplib_concepts.h>
|
#include <snipplib/concepts/snplib_traits.h>
|
||||||
#include <snipplib/containers/snplib_hmap.h>
|
#include <snipplib/containers/snplib_hmap.h>
|
||||||
#include <snipplib/serialization/snplib_serialization.h>
|
#include <snipplib/serialization/snplib_serialization.h>
|
||||||
|
|
||||||
@@ -102,6 +102,29 @@ inline std::error_code make_error_code(AdcDeviceErrorCode ec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace details
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept snplib_getter_c = std::same_as<T, std::nullptr_t> || requires(T t) {
|
||||||
|
{ t() } -> adc_result_c;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept snplib_setter_c =
|
||||||
|
std::same_as<T, std::nullptr_t> || (snplib::snplib_callable_c<T> && (snplib::snplib_func_traits_t<T>::arity >= 1) &&
|
||||||
|
std::same_as<adc_error_t, typename snplib::snplib_func_traits_t<T>::ret_t>);
|
||||||
|
|
||||||
|
|
||||||
|
// deduce value type from getter and setter
|
||||||
|
template <snplib_getter_c GT, snplib_setter_c ST>
|
||||||
|
using snplib_attr_value_deduced_t =
|
||||||
|
std::conditional_t<std::is_null_pointer_v<GT>,
|
||||||
|
std::conditional_t<std::is_null_pointer_v<ST>, void, snplib::snplib_func_arg1_t<ST>>,
|
||||||
|
typename std::invoke_result_t<GT>::value_type>;
|
||||||
|
|
||||||
|
} // namespace details
|
||||||
|
|
||||||
template <std::formattable<char> ATTR_ID_T = std::string_view, std::formattable<char> CMD_ID_T = std::string_view>
|
template <std::formattable<char> ATTR_ID_T = std::string_view, std::formattable<char> CMD_ID_T = std::string_view>
|
||||||
class AdcGenericDevice
|
class AdcGenericDevice
|
||||||
{
|
{
|
||||||
@@ -159,7 +182,11 @@ protected:
|
|||||||
{
|
{
|
||||||
auto const& attr = _dev._attrs.template get<attr_t<VT>>(_id);
|
auto const& attr = _dev._attrs.template get<attr_t<VT>>(_id);
|
||||||
if (attr) {
|
if (attr) {
|
||||||
return attr.value().getter();
|
if (attr.value().getter) {
|
||||||
|
return attr.value().getter();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unexpected(AdcDeviceErrorCode::ERROR_WO_ATTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// error
|
// error
|
||||||
@@ -175,7 +202,11 @@ protected:
|
|||||||
{
|
{
|
||||||
auto const& attr = _dev._attrs.template get<attr_t<VT>>(_id);
|
auto const& attr = _dev._attrs.template get<attr_t<VT>>(_id);
|
||||||
if (attr) {
|
if (attr) {
|
||||||
return attr.value().setter(std::forward<VT>(val));
|
if (attr.value().setter) {
|
||||||
|
return attr.value().setter(std::forward<VT>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
return AdcDeviceErrorCode::ERROR_RO_ATTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr.error() == snplib::HeterogenMap<ATTR_ID_T>::ERROR_NO_ELEM) {
|
if (attr.error() == snplib::HeterogenMap<ATTR_ID_T>::ERROR_NO_ELEM) {
|
||||||
@@ -197,6 +228,8 @@ public:
|
|||||||
typedef ATTR_ID_T attr_id_t;
|
typedef ATTR_ID_T attr_id_t;
|
||||||
typedef CMD_ID_T cmd_id_t;
|
typedef CMD_ID_T cmd_id_t;
|
||||||
|
|
||||||
|
enum AttrAccessType { ATTR_ACCESS_RW, ATTR_ACCESS_RO, ATTR_ACCESS_WO };
|
||||||
|
|
||||||
AdcGenericDevice() {}
|
AdcGenericDevice() {}
|
||||||
|
|
||||||
template <snplib::snplib_callable_c ET>
|
template <snplib::snplib_callable_c ET>
|
||||||
@@ -205,18 +238,30 @@ public:
|
|||||||
_commands.emplace(std::move(id), std::forward<ET>(exec_func));
|
_commands.emplace(std::move(id), std::forward<ET>(exec_func));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename GT, typename ST, typename... VTs>
|
// template <typename GT, typename ST, typename... VTs>
|
||||||
|
template <details::snplib_getter_c GT, details::snplib_setter_c ST, typename... VTs>
|
||||||
void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple<VTs...> = std::tuple())
|
void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple<VTs...> = std::tuple())
|
||||||
{
|
{
|
||||||
// deduce attribute value type
|
// static_assert(!(std::is_null_pointer_v<GT> && std::is_null_pointer_v<ST>),
|
||||||
using ret_t = std::invoke_result_t<GT>;
|
// "Getter and setter cannot be nullptr_t at the same time!");
|
||||||
using v_t = typename ret_t::value_type;
|
|
||||||
|
|
||||||
static_assert(adc_result_c<ret_t>, "Invalid return type of the getter!");
|
// // deduce attribute value type
|
||||||
|
// using ret_t = std::invoke_result_t<GT>;
|
||||||
|
|
||||||
static_assert(std::invocable<ST, v_t const&>, "Invalid setter type!");
|
// static_assert(adc_result_c<ret_t>, "Invalid return type of the getter!");
|
||||||
static_assert(std::convertible_to<std::invoke_result_t<ST, v_t const&>, adc_error_t>,
|
|
||||||
"Invalid return type of the setter!");
|
// using v_t = typename ret_t::value_type;
|
||||||
|
|
||||||
|
// static_assert(std::invocable<ST, v_t const&>, "Invalid setter type!");
|
||||||
|
// static_assert(std::convertible_to<std::invoke_result_t<ST, v_t const&>, adc_error_t>,
|
||||||
|
// "Invalid return type of the setter!");
|
||||||
|
|
||||||
|
using v_t = details::snplib_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!");
|
||||||
|
|
||||||
|
if constexpr (!std::is_null_pointer_v<GT> && !std::is_null_pointer_v<ST>) {
|
||||||
|
static_assert(std::invocable<ST, v_t const&>, "Invalid setter argument type!");
|
||||||
|
}
|
||||||
|
|
||||||
_attrs.push(std::move(id), attr_t<v_t>{.getter = std::forward<GT>(getter), .setter = std::forward<ST>(setter)});
|
_attrs.push(std::move(id), attr_t<v_t>{.getter = std::forward<GT>(getter), .setter = std::forward<ST>(setter)});
|
||||||
|
|
||||||
@@ -229,7 +274,22 @@ public:
|
|||||||
// }) {
|
// }) {
|
||||||
// static_assert(false, "Invalid user type!");
|
// static_assert(false, "Invalid user type!");
|
||||||
// }
|
// }
|
||||||
// _attrs.push(std::move(id), attr_t<u_t>{.getter = []() {}, .setter = []() {}});
|
|
||||||
|
// if constexpr (!std::same_as<u_t, v_t>) {
|
||||||
|
// _attrs.push(std::move(id), attr_t<u_t>{.getter = [id, this]() -> adc_result_t<u_t> {
|
||||||
|
// auto const& attr = _attrs.template
|
||||||
|
// get<attr_t<v_t>>(id); if (attr) {
|
||||||
|
// adc_result_t v = attr.getter();
|
||||||
|
// if (v) {
|
||||||
|
// return
|
||||||
|
// adc_result_t(static_cast<u_t>(v.value()));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return AdcDeviceErrorCode::ERROR_UNKNOWN;
|
||||||
|
// },
|
||||||
|
// .setter = []() {}});
|
||||||
|
// }
|
||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@@ -243,20 +303,22 @@ public:
|
|||||||
return AdcDeviceErrorCode::ERROR_NO_CMD_ID;
|
return AdcDeviceErrorCode::ERROR_NO_CMD_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto operator[](ATTR_ID_T id)
|
||||||
|
{
|
||||||
|
return attr_proxy_t{*this, std::move(id)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename VT>
|
template <typename VT>
|
||||||
adc_result_t<VT> attr(ATTR_ID_T id)
|
adc_result_t<VT> attr(ATTR_ID_T id)
|
||||||
{
|
{
|
||||||
|
return attr_proxy_t{*this, std::move(id)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VT>
|
template <typename VT>
|
||||||
adc_error_t attr(ATTR_ID_T id, VT const& v)
|
adc_error_t attr(ATTR_ID_T id, VT const& v)
|
||||||
{
|
{
|
||||||
}
|
return attr_proxy_t{*this, std::move(id)} = v;
|
||||||
|
|
||||||
auto operator[](ATTR_ID_T id)
|
|
||||||
{
|
|
||||||
return attr_proxy_t{*this, std::move(id)};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user