This commit is contained in:
2026-09-15 12:09:05 +03:00
parent 80feb1b490
commit d0502e0df0

View File

@@ -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()) {