diff --git a/include/adclib/adclib_device1.h b/include/adclib/adclib_device1.h index 999cca4..2a51576 100644 --- a/include/adclib/adclib_device1.h +++ b/include/adclib/adclib_device1.h @@ -7,6 +7,7 @@ ****************************************************************************************/ #include +#include #include #include #include @@ -248,7 +249,7 @@ protected: } else if constexpr (std::same_as && std::is_pointer_v) { 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(UR const&)> default_char_range_conv_to = default_char_range_conv_from; + // default convert functions for std::filesystem::path type + template + static inline std::function(std::filesystem::path const&)> default_fspath_conv_from = + [](std::filesystem::path const& val) -> adc_result_t { + if constexpr (std::same_as) { + return val; + } else if constexpr (std::constructible_from) { + return UT(val); + } else if constexpr (std::is_pointer_v> && std::same_as>) { // char*/wchar_t* + return val.c_str(); + } else if constexpr (snplib::snplib_char_range_c) { + using iter_t = std::filesystem::path::value_type*; + auto sz = val.native().size(); + if constexpr (std::constructible_from) { + return UT(val.c_str(), val.c_str() + sz); + } else if constexpr (std::constructible_from) { + return UT(val.c_str(), sz); + } else { + static_assert(false, "UNSUPPORTED CHAR-RANGE TYPE!"); + } + } else { + static_assert(false, "UNSUPPORTED TYPE!"); + } + }; + + template + static inline std::function(UT const&)> default_fspath_conv_to = + [](UT const& uval) -> adc_result_t { + if constexpr (std::same_as) { + return uval; + } else if constexpr (std::constructible_from) { + return std::filesystem::path(uval); + } else if constexpr (snplib::snplib_char_range_c) { + return std::filesystem::path(uval.begin(), uval.end()); + } else { + static_assert(false, "UNSUPPORTED TYPE!"); + } + }; + public: inline static constexpr std::tuple, std::list, const char*> char_ranges_t; +#ifdef _WIN32 + typedef std::tuple, std::list, const wchar_t*> fspath_repr_t; +#else + typedef std::tuple, std::list, 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>{}); } + // add attribute of std::filesystem::path type + template + requires std::same_as, std::filesystem::path> + void addFSPathAttr(ATTR_ID_T id, GT&& getter, ST&& setter) + { + using v_t = adclib_attr_value_deduced_t; + static_assert(!std::is_void_v, "Getter and setter cannot be nullptr_t at the same time!"); + + if constexpr (!std::is_null_pointer_v && !std::is_null_pointer_v) { + static_assert(std::invocable, "Invalid setter argument type!"); + } + + [&id, getter_cap = std::forward(getter), setter_cap = std::forward(setter), + this](std::index_sequence) mutable { + std::apply([this](auto&&... args) { addAttr(std::forward(args)...); }, + std::tuple_cat( + std::forward_as_tuple(id, std::forward(getter_cap), + std::forward(setter_cap)), + std::tuple_cat(std::forward_as_tuple( + default_fspath_conv_from>, + default_fspath_conv_to>)...))); + }(std::make_index_sequence>{}); + } + adc_error_t operator()(CMD_ID_T id) { if (auto it = _commands.find(id); it != _commands.end()) {