diff --git a/CMakeLists.txt b/CMakeLists.txt index cc6b8cc..2977509 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,12 +5,14 @@ project(adclib LANGUAGES CXX DESCRIPTION "Abstract Device Components Library") set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) -option(BUILD_EXAM "Build examples" ON) +option(ADCLIB_BUILD_EXAM "Build examples" ON) # ------- dependencies ------- include(FetchContent) +set(SNPLIB_BUILD_EXAMPLES OFF) + FetchContent_Declare( snplib GIT_REPOSITORY https://timur@git.sao.ru/timur/snipplib.git @@ -22,9 +24,10 @@ FetchContent_Declare( FetchContent_MakeAvailable(snplib) - -set(ADCLIB_HEADERS include/adclib/adclib_device.h - include/adclib/adclib_common.h) +set(ADCLIB_HEADERS + include/adclib/adclib_device.h + include/adclib/adclib_common.h +) add_library(${PROJECT_NAME} INTERFACE ${ADCLIB_HEADERS}) target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_23) @@ -37,13 +40,14 @@ target_include_directories( target_link_libraries(${PROJECT_NAME} INTERFACE snipplib) -if(BUILD_EXAM) +if(ADCLIB_BUILD_EXAM) add_executable(device_exam examples/device_exam.cpp) target_link_libraries(device_exam PRIVATE ${PROJECT_NAME}) endif() -include(GNUInstallDirs) -install(TARGETS ${PROJECT_NAME} +include(GNUInstallDirs) +install( + TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/examples/device_exam.cpp b/examples/device_exam.cpp index 73ff9fb..3eb5663 100644 --- a/examples/device_exam.cpp +++ b/examples/device_exam.cpp @@ -10,15 +10,14 @@ int main() double d = 8.1; std::string s{"dwedjkwlk"}; - AdcGenericDevice<> dev; + AdcGenericDevice<> dev("DEV#1"); dev.addAttr( "1", [&i]() -> adc_result_t { return i; }, [&i](int ii) -> adc_error_t { i = ii; return AdcDeviceErrorCode::ERROR_OK; - }, - std::tuple{}); + }); dev.addAttr("2", [&d]() -> adc_result_t { return d; }, nullptr); diff --git a/include/adclib/adclib_device.h b/include/adclib/adclib_device.h index c39a9d7..d3dad6e 100644 --- a/include/adclib/adclib_device.h +++ b/include/adclib/adclib_device.h @@ -102,37 +102,33 @@ inline std::error_code make_error_code(AdcDeviceErrorCode ec) } -namespace details -{ - template -concept snplib_getter_c = std::same_as || requires(T t) { +concept adclib_attr_getter_c = std::same_as || requires(T t) { { t() } -> adc_result_c; }; template -concept snplib_setter_c = +concept adclib_attr_setter_c = std::same_as || (snplib::snplib_callable_c && (snplib::snplib_func_traits_t::arity >= 1) && std::same_as::ret_t>); // deduce value type from getter and setter -template +template using snplib_attr_value_deduced_t = std::conditional_t, std::conditional_t, void, snplib::snplib_func_arg1_t>, typename std::invoke_result_t::value_type>; -} // namespace details -template ATTR_ID_T = std::string_view, std::formattable CMD_ID_T = std::string_view> +template DEV_ID_T = std::string, + std::formattable ATTR_ID_T = std::string, + std::formattable CMD_ID_T = std::string> class AdcGenericDevice { protected: template struct attr_t { - ATTR_ID_T id; - std::function()> getter; std::function setter; @@ -178,9 +174,9 @@ protected: attr_proxy_t(AdcGenericDevice& dev, ATTR_ID_T id) : _dev(dev), _id(std::move(id)) {} template - operator adc_result_t() + operator adc_result_t() const { - auto const& attr = _dev._attrs.template get>(_id); + auto attr = _dev._attrs.template get>(_id); if (attr) { if (attr.value().getter) { return attr.value().getter(); @@ -200,7 +196,7 @@ protected: template adc_error_t operator=(VT&& val) { - auto const& attr = _dev._attrs.template get>(_id); + auto attr = _dev._attrs.template get>(_id); if (attr) { if (attr.value().setter) { return attr.value().setter(std::forward(val)); @@ -221,16 +217,26 @@ protected: ATTR_ID_T _id; }; + DEV_ID_T _devId; + std::unordered_map> _commands{}; snplib::HeterogenMap _attrs{}; public: + typedef DEV_ID_T device_id_t; typedef ATTR_ID_T attr_id_t; typedef CMD_ID_T cmd_id_t; enum AttrAccessType { ATTR_ACCESS_RW, ATTR_ACCESS_RO, ATTR_ACCESS_WO }; - AdcGenericDevice() {} + AdcGenericDevice(device_id_t id) : _devId(id) {} + + virtual ~AdcGenericDevice() = default; + + device_id_t id() const + { + return _devId; + } template void addCommand(CMD_ID_T id, ET&& exec_func) @@ -239,24 +245,10 @@ public: } // template - template - void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter, std::tuple = std::tuple()) + template + void addAttr(ATTR_ID_T id, GT&& getter, ST&& setter) { - // static_assert(!(std::is_null_pointer_v && std::is_null_pointer_v), - // "Getter and setter cannot be nullptr_t at the same time!"); - - // // deduce attribute value type - // using ret_t = std::invoke_result_t; - - // static_assert(adc_result_c, "Invalid return type of the getter!"); - - // using v_t = typename ret_t::value_type; - - // static_assert(std::invocable, "Invalid setter type!"); - // static_assert(std::convertible_to, adc_error_t>, - // "Invalid return type of the setter!"); - - using v_t = details::snplib_attr_value_deduced_t; + using v_t = snplib_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) { @@ -264,34 +256,6 @@ public: } _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!"); - // } - - // if constexpr (!std::same_as) { - // _attrs.push(std::move(id), attr_t{.getter = [id, this]() -> adc_result_t { - // auto const& attr = _attrs.template - // get>(id); if (attr) { - // adc_result_t v = attr.getter(); - // if (v) { - // return - // adc_result_t(static_cast(v.value())); - // } - // } - - // return AdcDeviceErrorCode::ERROR_UNKNOWN; - // }, - // .setter = []() {}}); - // } - // }; - // } } adc_error_t operator()(CMD_ID_T id)