...
This commit is contained in:
parent
0d64e0cf44
commit
6de9127e58
@ -25,6 +25,9 @@ if (BUILD_TESTS)
|
|||||||
set(VALUEHOLDER_TEST_APP adc_valueholder_test)
|
set(VALUEHOLDER_TEST_APP adc_valueholder_test)
|
||||||
add_executable(${VALUEHOLDER_TEST_APP} tests/adc_valueholder_test.cpp)
|
add_executable(${VALUEHOLDER_TEST_APP} tests/adc_valueholder_test.cpp)
|
||||||
|
|
||||||
|
set(DEVATTR_TEST_APP adc_devattr_test)
|
||||||
|
add_executable(${DEVATTR_TEST_APP} tests/adc_devattr_test.cpp)
|
||||||
|
|
||||||
if (NOT doctest_FOUND)
|
if (NOT doctest_FOUND)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
|
|||||||
@ -36,7 +36,9 @@ static ValueT AdcFromChars(R&& range)
|
|||||||
#ifdef _LIBCPP_VERSION // clang's libc++ does not have floating-point overloads for std::from_chars
|
#ifdef _LIBCPP_VERSION // clang's libc++ does not have floating-point overloads for std::from_chars
|
||||||
if constexpr (traits::adc_is_any_v<v_t, char, int, long, long long, __int128>) {
|
if constexpr (traits::adc_is_any_v<v_t, char, int, long, long long, __int128>) {
|
||||||
#else
|
#else
|
||||||
if constexpr (traits::adc_is_any_of_v<v_t, char, int, long, long long, __int128, float, double, long double>) {
|
if constexpr (traits::adc_is_any_of_v<v_t, unsigned char, char, unsigned short, short, unsigned long, long,
|
||||||
|
unsigned long long, long long, unsigned int, int, unsigned __int128, __int128,
|
||||||
|
float, double, long double>) {
|
||||||
#endif
|
#endif
|
||||||
v_t v;
|
v_t v;
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ namespace adc
|
|||||||
struct AdcValueHolderErrorCategory : public std::error_category {
|
struct AdcValueHolderErrorCategory : public std::error_category {
|
||||||
AdcValueHolderErrorCategory() : std::error_category() {}
|
AdcValueHolderErrorCategory() : std::error_category() {}
|
||||||
|
|
||||||
const char* name() const noexcept { return "DEVA_DEVICE_ATTRIBUTE"; }
|
const char* name() const noexcept { return "ADC_VALUEHOLDER_CATEGORY"; }
|
||||||
|
|
||||||
std::string message(int ec) const
|
std::string message(int ec) const
|
||||||
{
|
{
|
||||||
@ -404,6 +404,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef SerializedT serialized_t;
|
||||||
|
|
||||||
/* CONSTRUCTORS AND DESTRUCTOR */
|
/* CONSTRUCTORS AND DESTRUCTOR */
|
||||||
|
|
||||||
template <typename GT,
|
template <typename GT,
|
||||||
|
|||||||
@ -1 +1,143 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
ABSTRACT DEVICE COMPONENTS LIBRARY
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "../common/adc_value.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace adc
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename IdentT, typename SerializedT = std::string>
|
||||||
|
class AdcDeviceAttribute : public AdcSerializingValueHolder<SerializedT>
|
||||||
|
{
|
||||||
|
using base_t = AdcSerializingValueHolder<SerializedT>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using ret_value_t = base_t::template ret_value_t<T>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef IdentT ident_t;
|
||||||
|
typedef SerializedT serialized_t;
|
||||||
|
|
||||||
|
enum AccessType { ReadOnly, WriteOnly, ReadWrite };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr static T DummyGetter()
|
||||||
|
{
|
||||||
|
return std::declval<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr static void DummySetter(const T&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr static SerializedT DummySerializer(const T&)
|
||||||
|
{
|
||||||
|
return std::declval<SerializedT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr static T DummyDeserializer(const SerializedT&)
|
||||||
|
{
|
||||||
|
return std::declval<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CONSTRUCTORS AND DESTRUCTOR */
|
||||||
|
|
||||||
|
// general read-write attribute constructor
|
||||||
|
template <typename GT,
|
||||||
|
typename ST,
|
||||||
|
typename VALT = ret_value_t<GT>,
|
||||||
|
typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<VALT>),
|
||||||
|
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>),
|
||||||
|
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)>
|
||||||
|
AdcDeviceAttribute(const IdentT& ident,
|
||||||
|
AccessType access_type,
|
||||||
|
GT&& getter,
|
||||||
|
ST&& setter,
|
||||||
|
VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator<VALT>,
|
||||||
|
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>,
|
||||||
|
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)
|
||||||
|
requires std::invocable<GT> && std::invocable<ST, const VALT&> && std::predicate<VT, const VALT&> &&
|
||||||
|
std::invocable<SRT, const VALT&> && std::invocable<DSRT, const SerializedT&>
|
||||||
|
: base_t(std::forward<GT>(getter),
|
||||||
|
std::forward<ST>(setter),
|
||||||
|
std::forward<VT>(validator),
|
||||||
|
std::forward<SRT>(serializer),
|
||||||
|
std::forward<DSRT>(deserializer)),
|
||||||
|
_ident(ident),
|
||||||
|
_accessType(access_type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// read-only attribute constructor
|
||||||
|
template <typename GT,
|
||||||
|
typename VALT = ret_value_t<GT>,
|
||||||
|
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>)>
|
||||||
|
AdcDeviceAttribute(const IdentT& ident,
|
||||||
|
GT&& getter,
|
||||||
|
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>)
|
||||||
|
requires std::invocable<GT> && std::invocable<SRT, const VALT&>
|
||||||
|
: AdcDeviceAttribute(ident,
|
||||||
|
ReadOnly,
|
||||||
|
std::forward<GT>(getter),
|
||||||
|
AdcDeviceAttribute::DummySetter<VALT>,
|
||||||
|
AdcValueHolder::AdcValueHolderDummyValidator<VALT>,
|
||||||
|
std::forward<SRT>(serializer),
|
||||||
|
AdcDeviceAttribute::DummyDeserializer<VALT>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// write-only attribute constructor
|
||||||
|
template <typename ST,
|
||||||
|
typename VALT = std::decay_t<traits::adc_func_arg1_t<ST>>,
|
||||||
|
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)>
|
||||||
|
AdcDeviceAttribute(const IdentT& ident,
|
||||||
|
ST&& setter,
|
||||||
|
std::predicate<const VALT&> auto&& validator,
|
||||||
|
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)
|
||||||
|
requires std::invocable<DSRT, const SerializedT&>
|
||||||
|
: AdcDeviceAttribute(ident,
|
||||||
|
WriteOnly,
|
||||||
|
AdcDeviceAttribute::DummyGetter<VALT>,
|
||||||
|
std::forward<ST>(setter),
|
||||||
|
std::forward<decltype(validator)>(validator),
|
||||||
|
AdcDeviceAttribute::DummySerializer<VALT>,
|
||||||
|
std::forward<DSRT>(deserializer))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// constructor of attribute with trivially casting type converters
|
||||||
|
template <typename... TrivCastTs, typename... Ts>
|
||||||
|
AdcDeviceAttribute(const std::tuple<TrivCastTs...>&, Ts&&... ctor_args)
|
||||||
|
: AdcDeviceAttribute(std::forward<Ts>(ctor_args)...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AdcDeviceAttribute() = default;
|
||||||
|
|
||||||
|
IdentT ident() const { return _ident; }
|
||||||
|
|
||||||
|
AccessType accessType() const { return _accessType; }
|
||||||
|
|
||||||
|
using base_t::operator=;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IdentT _ident;
|
||||||
|
AccessType _accessType;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace adc
|
||||||
|
|||||||
44
tests/adc_devattr_test.cpp
Normal file
44
tests/adc_devattr_test.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||||
|
#include <doctest/doctest.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
#include "../device/adc_device_attribute.h"
|
||||||
|
|
||||||
|
using namespace adc;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct V {
|
||||||
|
static T getter() { return _v; }
|
||||||
|
static void setter(const T& v) { _v = v; }
|
||||||
|
|
||||||
|
static bool validator(const T& v)
|
||||||
|
{
|
||||||
|
if (v < 1)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline static T _v = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("[ADC DEVICE ATTRIBUTE]")
|
||||||
|
{
|
||||||
|
double av = -10;
|
||||||
|
using vv = V<unsigned>;
|
||||||
|
|
||||||
|
using attr_t = AdcDeviceAttribute<std::string_view>;
|
||||||
|
|
||||||
|
// attr_t attr(AdcValueHolder::_defaultTrivialConvTypes, "ATTR_A", attr_t::ReadWrite, vv::getter, vv::setter,
|
||||||
|
// vv::validator);
|
||||||
|
attr_t attr("ATTR_A", attr_t::ReadWrite, vv::getter, vv::setter, vv::validator);
|
||||||
|
|
||||||
|
// attr = 10.7;
|
||||||
|
// av = attr;
|
||||||
|
|
||||||
|
// std::cout << "ATTR = " << av << "\n";
|
||||||
|
std::cout << "ATTR = " << (unsigned)attr << "\n";
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user