...
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <concepts>
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
@@ -248,7 +249,7 @@ protected:
|
||||
} 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!");
|
||||
static_assert(false, "UNSUPPORTED CHAR-RANGE TYPE!");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -257,6 +258,46 @@ protected:
|
||||
static inline std::function<adc_result_t<VR>(UR const&)> default_char_range_conv_to =
|
||||
default_char_range_conv_from<UR, VR>;
|
||||
|
||||
// default convert functions for std::filesystem::path type
|
||||
template <typename UT>
|
||||
static inline std::function<adc_result_t<UT>(std::filesystem::path const&)> default_fspath_conv_from =
|
||||
[](std::filesystem::path const& val) -> adc_result_t<UT> {
|
||||
if constexpr (std::same_as<std::filesystem::path, UT>) {
|
||||
return val;
|
||||
} else if constexpr (std::constructible_from<UT, std::filesystem::path>) {
|
||||
return UT(val);
|
||||
} else if constexpr (std::is_pointer_v<std::decay_t<UT>> && std::same_as<std::filesystem::path::value_type*,
|
||||
std::decay_t<UT>>) { // char*/wchar_t*
|
||||
return val.c_str();
|
||||
} else if constexpr (snplib::snplib_char_range_c<UT>) {
|
||||
using iter_t = std::filesystem::path::value_type*;
|
||||
auto sz = val.native().size();
|
||||
if constexpr (std::constructible_from<UT, iter_t, iter_t>) {
|
||||
return UT(val.c_str(), val.c_str() + sz);
|
||||
} else if constexpr (std::constructible_from<UT, iter_t, decltype(sz)>) {
|
||||
return UT(val.c_str(), sz);
|
||||
} else {
|
||||
static_assert(false, "UNSUPPORTED CHAR-RANGE TYPE!");
|
||||
}
|
||||
} else {
|
||||
static_assert(false, "UNSUPPORTED TYPE!");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename UT>
|
||||
static inline std::function<adc_result_t<std::filesystem::path>(UT const&)> default_fspath_conv_to =
|
||||
[](UT const& uval) -> adc_result_t<std::filesystem::path> {
|
||||
if constexpr (std::same_as<std::filesystem::path, UT>) {
|
||||
return uval;
|
||||
} else if constexpr (std::constructible_from<std::filesystem::path, UT>) {
|
||||
return std::filesystem::path(uval);
|
||||
} else if constexpr (snplib::snplib_char_range_c<UT>) {
|
||||
return std::filesystem::path(uval.begin(), uval.end());
|
||||
} else {
|
||||
static_assert(false, "UNSUPPORTED TYPE!");
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
inline static constexpr std::tuple<bool,
|
||||
char,
|
||||
@@ -292,6 +333,12 @@ public:
|
||||
|
||||
typedef std::tuple<std::string, std::string_view, std::vector<char>, std::list<char>, const char*> char_ranges_t;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef std::tuple<std::string, std::string_view, std::vector<char>, std::list<char>, const wchar_t*> fspath_repr_t;
|
||||
#else
|
||||
typedef std::tuple<std::string, std::string_view, std::vector<char>, std::list<char>, const char*> fspath_repr_t;
|
||||
#endif
|
||||
|
||||
typedef DEV_ID_T device_id_t;
|
||||
typedef ATTR_ID_T attr_id_t;
|
||||
typedef CMD_ID_T cmd_id_t;
|
||||
@@ -630,6 +677,30 @@ public:
|
||||
}(std::make_index_sequence<std::tuple_size_v<AdcGenericDevice::char_ranges_t>>{});
|
||||
}
|
||||
|
||||
// add attribute of std::filesystem::path type
|
||||
template <typename GT, typename ST>
|
||||
requires std::same_as<adclib_attr_value_deduced_t<GT, ST>, std::filesystem::path>
|
||||
void addFSPathAttr(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_fspath_conv_from<std::tuple_element_t<Is, AdcGenericDevice::fspath_repr_t>>,
|
||||
default_fspath_conv_to<std::tuple_element_t<Is, AdcGenericDevice::fspath_repr_t>>)...)));
|
||||
}(std::make_index_sequence<std::tuple_size_v<AdcGenericDevice::fspath_repr_t>>{});
|
||||
}
|
||||
|
||||
adc_error_t operator()(CMD_ID_T id)
|
||||
{
|
||||
if (auto it = _commands.find(id); it != _commands.end()) {
|
||||
|
||||
Reference in New Issue
Block a user