...
This commit is contained in:
@@ -21,6 +21,7 @@ int main()
|
|||||||
i = ii;
|
i = ii;
|
||||||
return AdcDeviceErrorCode::ERROR_OK;
|
return AdcDeviceErrorCode::ERROR_OK;
|
||||||
});
|
});
|
||||||
|
|
||||||
// dev.addAttr(
|
// dev.addAttr(
|
||||||
// id1, [&i]() -> adc_result_t<int> { return i; },
|
// id1, [&i]() -> adc_result_t<int> { return i; },
|
||||||
// [&i](int ii) -> adc_error_t {
|
// [&i](int ii) -> adc_error_t {
|
||||||
@@ -49,6 +50,14 @@ int main()
|
|||||||
// // }
|
// // }
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
std::println("add RW-attr with id='{}' (val={})", id3, s);
|
||||||
|
dev.addCharRangeAttr(
|
||||||
|
id3, [&s]() -> adc_result_t<std::string> { return s; },
|
||||||
|
[&s](std::string const& sv) -> adc_error_t {
|
||||||
|
s = sv;
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
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];
|
||||||
if (ri) {
|
if (ri) {
|
||||||
@@ -115,6 +124,14 @@ int main()
|
|||||||
std::println("OK");
|
std::println("OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::print("get '{}'-attr value as native string:\t", id3);
|
||||||
|
rs = dev[id3];
|
||||||
|
if (rs) {
|
||||||
|
std::println("dev[{}] = {}", id3, rs.value());
|
||||||
|
} else {
|
||||||
|
std::println("cannot get dev[{}] as string: {}", id3, rs.error().message());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <concepts>
|
#include <concepts>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -223,62 +224,75 @@ 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> _attrSetter{};
|
|
||||||
snplib::hmap<ATTR_ID_T> _attrGetter{};
|
snplib::hmap<ATTR_ID_T> _attrGetter{};
|
||||||
snplib::hmap<ATTR_ID_T> _attrSetter{};
|
snplib::hmap<ATTR_ID_T> _attrSetter{};
|
||||||
|
|
||||||
|
|
||||||
template <typename GT, typename UGT>
|
// default convert functions for char-range types
|
||||||
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> {
|
template <typename VR, typename UR>
|
||||||
auto v = g();
|
requires((snplib::snplib_char_range_c<VR> || snplib::snplib_pointer_to_char_c<VR>) &&
|
||||||
|
(snplib::snplib_char_range_c<UR> || snplib::snplib_pointer_to_char_c<UR>))
|
||||||
if (v) {
|
static inline std::function<adc_result_t<UR>(VR const&)> default_char_range_conv_from = [](VR const& val)
|
||||||
return static_cast<u_t>(v.value());
|
-> adc_result_t<UR> {
|
||||||
}
|
if constexpr (std::same_as<VR, UR>) {
|
||||||
|
return val;
|
||||||
return v.error();
|
} else if constexpr (std::constructible_from<UR, VR>) {
|
||||||
};
|
return UR(val);
|
||||||
|
} else if constexpr (std::is_pointer_v<std::decay_t<VR>>) { // char*, const char*, char[]
|
||||||
|
return default_char_range_conv_from<std::string_view, UR>(std::string_view(val));
|
||||||
|
} else if constexpr (std::constructible_from<UR, std::ranges::iterator_t<VR>, std::ranges::sentinel_t<VR>>) {
|
||||||
|
return UR(val.begin(), val.end());
|
||||||
|
} else if constexpr (std::constructible_from<UR, std::ranges::const_iterator_t<VR>,
|
||||||
|
std::ranges::const_sentinel_t<VR>>) {
|
||||||
|
return UR(val.cbegin(), val.cend());
|
||||||
|
} else if constexpr (std::same_as<VR, std::string> && std::is_pointer_v<UR>) {
|
||||||
|
return val.data();
|
||||||
|
} else {
|
||||||
|
static_assert(false, "UNSUPPORTED CHAR-RANGE TYPES!");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename GT, typename UGT>
|
template <typename VR, typename UR>
|
||||||
requires requires(std::invoke_result_t<GT> v, std::invoke_result_t<UGT> u) { v = u; }
|
static inline std::function<adc_result_t<VR>(UR const&)> default_char_range_conv_to =
|
||||||
inline static auto default_cnv_to_func = [](UGT const& g) -> adc_result_t<GT> {
|
default_char_range_conv_from<UR, VR>;
|
||||||
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:
|
public:
|
||||||
static constexpr std::tuple<bool,
|
inline static constexpr std::tuple<bool,
|
||||||
char,
|
char,
|
||||||
short,
|
short,
|
||||||
int,
|
int,
|
||||||
long,
|
long,
|
||||||
long long,
|
long long,
|
||||||
unsigned char,
|
unsigned char,
|
||||||
unsigned short,
|
unsigned short,
|
||||||
unsigned int,
|
unsigned int,
|
||||||
unsigned long,
|
unsigned long,
|
||||||
unsigned long long,
|
unsigned long long,
|
||||||
float,
|
float,
|
||||||
double,
|
double,
|
||||||
long double>
|
long double>
|
||||||
arithmetic_types{};
|
arithmetic_types{};
|
||||||
|
|
||||||
|
typedef std::tuple<bool,
|
||||||
|
char,
|
||||||
|
short,
|
||||||
|
int,
|
||||||
|
long,
|
||||||
|
long long,
|
||||||
|
unsigned char,
|
||||||
|
unsigned short,
|
||||||
|
unsigned int,
|
||||||
|
unsigned long,
|
||||||
|
unsigned long long,
|
||||||
|
float,
|
||||||
|
double,
|
||||||
|
long double>
|
||||||
|
arithmetics_t;
|
||||||
|
|
||||||
|
typedef std::tuple<std::string, std::string_view, std::vector<char>, std::list<char>, const char*> char_ranges_t;
|
||||||
|
|
||||||
typedef DEV_ID_T device_id_t;
|
typedef DEV_ID_T device_id_t;
|
||||||
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;
|
||||||
@@ -477,7 +491,35 @@ public:
|
|||||||
requires std::is_arithmetic_v<adclib_attr_value_deduced_t<GT, ST>>
|
requires std::is_arithmetic_v<adclib_attr_value_deduced_t<GT, ST>>
|
||||||
void addArithAttr(ATTR_ID_T id, GT&& getter, ST&& setter)
|
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);
|
// addAttr(std::move(id), std::forward<GT>(getter), std::forward<ST>(setter),
|
||||||
|
// AdcGenericDevice::arithmetic_types);
|
||||||
|
addAttr(std::move(id), std::forward<GT>(getter), std::forward<ST>(setter), AdcGenericDevice::arithmetics_t{});
|
||||||
|
}
|
||||||
|
|
||||||
|
// add attribute of char-range type
|
||||||
|
template <typename GT, typename ST>
|
||||||
|
requires snplib::snplib_char_range_c<adclib_attr_value_deduced_t<GT, ST>>
|
||||||
|
void addCharRangeAttr(ATTR_ID_T id, GT&& getter, ST&& setter)
|
||||||
|
{
|
||||||
|
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!");
|
||||||
|
|
||||||
|
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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
[&id, getter_cap = std::forward<GT>(getter), setter_cap = std::forward<ST>(setter),
|
||||||
|
this]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||||
|
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(
|
||||||
|
default_char_range_conv_from<v_t, std::tuple_element_t<Is, AdcGenericDevice::char_ranges_t>>,
|
||||||
|
default_char_range_conv_to<v_t,
|
||||||
|
std::tuple_element_t<Is, AdcGenericDevice::char_ranges_t>>)...)));
|
||||||
|
}(std::make_index_sequence<std::tuple_size_v<AdcGenericDevice::char_ranges_t>>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
adc_error_t operator()(CMD_ID_T id)
|
adc_error_t operator()(CMD_ID_T id)
|
||||||
|
|||||||
Reference in New Issue
Block a user