diff --git a/CMakeLists.txt b/CMakeLists.txt index 588bb58..cc6b8cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,8 @@ target_include_directories( "$" ) +target_link_libraries(${PROJECT_NAME} INTERFACE snipplib) + if(BUILD_EXAM) add_executable(device_exam examples/device_exam.cpp) target_link_libraries(device_exam PRIVATE ${PROJECT_NAME}) diff --git a/examples/device_exam.cpp b/examples/device_exam.cpp index 06acbce..5e46edd 100644 --- a/examples/device_exam.cpp +++ b/examples/device_exam.cpp @@ -13,15 +13,30 @@ int main() AdcGenericDevice<> dev; dev.addAttr( - "1", [&i]() { return adc_result_t{i}; }, + "1", [&i]() -> adc_result_t { return i; }, [&i](int ii) -> adc_error_t { i = ii; return AdcDeviceErrorCode::ERROR_OK; - }); + }, + std::tuple{}); adc_result_t ri = dev["1"]; if (ri) { std::println("dev[1] = {}", ri.value()); + } else { + std::println("cannot get dev[1] as int: {}", ri.error().message()); + } + + auto err = dev["1"] = 77; + if (err) { + std::println("cannot set dev[1] as int: {}", err.message()); + } + + adc_result_t rd = dev["1"]; + if (rd) { + std::println("dev[1] = {}", rd.value()); + } else { + std::println("cannot get dev[1] as double: {}", rd.error().message()); } return 0; diff --git a/include/adclib/adclib_device.h b/include/adclib/adclib_device.h index 83bdaa6..e07f45e 100644 --- a/include/adclib/adclib_device.h +++ b/include/adclib/adclib_device.h @@ -5,6 +5,8 @@ ****************************************************************************************/ #include +#include +#include #include #include #include @@ -69,9 +71,9 @@ struct AdcDeviceErrorCategory : std::error_category { case AdcDeviceErrorCode::ERROR_OK: return "OK"; case AdcDeviceErrorCode::ERROR_NO_CMD_ID: - return "invalud command ID"; + return "invalid command ID"; case AdcDeviceErrorCode::ERROR_NO_ATTR_ID: - return "invalud attribute ID"; + return "invalid attribute ID"; case AdcDeviceErrorCode::ERROR_RO_ATTR: return "read-only attribute"; case AdcDeviceErrorCode::ERROR_WO_ATTR: @@ -94,6 +96,11 @@ struct AdcDeviceErrorCategory : std::error_category { } }; +inline std::error_code make_error_code(AdcDeviceErrorCode ec) +{ + return std::error_code(static_cast(ec), AdcDeviceErrorCategory::get()); +} + template ATTR_ID_T = std::string_view, std::formattable CMD_ID_T = std::string_view> class AdcGenericDevice @@ -150,13 +157,13 @@ protected: template operator adc_result_t() { - auto v = _dev._attrs.template get(_id); - if (v) { - return v.value(); + auto const& attr = _dev._attrs.template get>(_id); + if (attr) { + return attr.value().getter(); } // error - if (v.error() == snplib::HeterogenMap::ERROR_NO_ELEM) { + if (attr.error() == snplib::HeterogenMap::ERROR_NO_ELEM) { return std::unexpected(AdcDeviceErrorCode::ERROR_NO_ATTR_ID); } @@ -166,10 +173,12 @@ protected: template adc_error_t operator=(VT&& val) { - auto err = _dev._attrs.set(_id, std::forward(val)); - if (err == snplib::HeterogenMap::ERROR_OK) { - return AdcDeviceErrorCode::ERROR_OK; - } else if (err == snplib::HeterogenMap::ERROR_NO_ELEM) { + auto const& attr = _dev._attrs.template get>(_id); + if (attr) { + return attr.value().setter(std::forward(val)); + } + + if (attr.error() == snplib::HeterogenMap::ERROR_NO_ELEM) { return AdcDeviceErrorCode::ERROR_NO_ATTR_ID; } else { return AdcDeviceErrorCode::ERROR_UNKNOWN; @@ -196,8 +205,8 @@ public: _commands.emplace(std::move(id), std::forward(exec_func)); } - template - void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter) + template + void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple = std::tuple()) { // deduce attribute value type using ret_t = std::invoke_result_t; @@ -210,6 +219,19 @@ public: "Invalid return type of the setter!"); _attrs.push(std::move(id), attr_t{.getter = std::forward(getter), .setter = std::forward(setter)}); + + // if constexpr (sizeof...(VTs)) { + // auto func = [id, this]() { + // using u_t = std::tuple_element_t>; + // if constexpr (!requires(u_t u, v_t v) { + // u = v; + // v = u; + // }) { + // static_assert(false, "Invalid user type!"); + // } + // _attrs.push(std::move(id), attr_t{.getter = []() {}, .setter = []() {}}); + // }; + // } } adc_error_t operator()(CMD_ID_T id)