AdcValueHolder class: tests are passed
This commit is contained in:
parent
a963db2900
commit
fad61ea1df
@ -97,7 +97,6 @@ class AdcValueHolder
|
||||
{
|
||||
protected:
|
||||
template <typename T>
|
||||
// using arg_t = typename traits::adc_func_traits<T>::ret_t;
|
||||
using arg_t = typename traits::adc_func_traits<std::remove_reference_t<T>>::ret_t;
|
||||
|
||||
std::function<void(std::any&)> _getterWrapper;
|
||||
@ -158,7 +157,21 @@ protected:
|
||||
|
||||
public:
|
||||
// default trivial types (just arithmetic ones)
|
||||
constexpr static std::tuple<char, short, int, long, long long, float, double> _defaultTrivialConvTypes{};
|
||||
constexpr static std::tuple<bool,
|
||||
char,
|
||||
short,
|
||||
int,
|
||||
long,
|
||||
long long,
|
||||
unsigned char,
|
||||
unsigned short,
|
||||
unsigned int,
|
||||
unsigned long,
|
||||
unsigned long long,
|
||||
float,
|
||||
double,
|
||||
long double>
|
||||
_defaultTrivialConvTypes{};
|
||||
|
||||
// always-true validator
|
||||
// constexpr static auto AdcValueHolderDummyValidator = [](const auto&) { return true; };
|
||||
@ -172,8 +185,7 @@ public:
|
||||
|
||||
AdcValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator =
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<arg_t<decltype(getter)>>)
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator)
|
||||
: _internalTypeIndex(std::type_index(typeid(arg_t<decltype(getter)>)))
|
||||
{
|
||||
init(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
|
||||
@ -181,12 +193,20 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// NOTE: due to using of concepts one cannot use of default value for validator callable!!!
|
||||
AdcValueHolder(std::invocable<> auto&& getter, std::invocable<const arg_t<decltype(getter)>&> auto&& setter)
|
||||
: AdcValueHolder(std::forward<decltype(getter)>(getter),
|
||||
std::forward<decltype(setter)>(setter),
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<traits::adc_retval_t<decltype(getter)>>)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename... Ts>
|
||||
AdcValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
const std::tuple<Ts...>& trivialConvTypes,
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator =
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<arg_t<decltype(getter)>>)
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator,
|
||||
const std::tuple<Ts...>& /* tuple-of-trivially-converting-types */)
|
||||
: AdcValueHolder(std::forward<decltype(getter)>(getter),
|
||||
std::forward<decltype(setter)>(setter),
|
||||
std::forward<decltype(validator)>(validator))
|
||||
@ -196,6 +216,18 @@ public:
|
||||
}
|
||||
|
||||
|
||||
template <typename... Ts>
|
||||
AdcValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
const std::tuple<Ts...>& t /* tuple-of-trivially-converting-types */)
|
||||
: AdcValueHolder(std::forward<decltype(getter)>(getter),
|
||||
std::forward<decltype(setter)>(setter),
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<traits::adc_retval_t<decltype(getter)>>,
|
||||
t)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AdcValueHolder(const AdcValueHolder&) = default;
|
||||
AdcValueHolder(AdcValueHolder&&) = default;
|
||||
|
||||
@ -215,10 +247,10 @@ public:
|
||||
}
|
||||
|
||||
|
||||
AdcValueHolder& resetValueHolder(
|
||||
std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator = AdcValueHolderDummyValidator)
|
||||
AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator =
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<arg_t<decltype(getter)>>)
|
||||
{
|
||||
_convertFromInternal.clear();
|
||||
_convertToInternal.clear();
|
||||
@ -230,12 +262,19 @@ public:
|
||||
}
|
||||
|
||||
|
||||
AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter)
|
||||
{
|
||||
return resetValueHolder(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<traits::adc_retval_t<decltype(getter)>>);
|
||||
}
|
||||
|
||||
|
||||
template <typename... Ts>
|
||||
AdcValueHolder& resetValueHolder(
|
||||
std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
const std::tuple<Ts...>& trivialConvTypes,
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator = AdcValueHolderDummyValidator)
|
||||
AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
std::predicate<const arg_t<decltype(getter)>&> auto&& validator,
|
||||
const std::tuple<Ts...>& /* tuple-of-trivially-converting-types */)
|
||||
{
|
||||
resetValueHolder(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
|
||||
std::forward<decltype(validator)>(validator));
|
||||
@ -247,11 +286,22 @@ public:
|
||||
}
|
||||
|
||||
|
||||
template <typename... Ts>
|
||||
AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter,
|
||||
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
|
||||
const std::tuple<Ts...>& t /* tuple-of-trivially-converting-types */)
|
||||
{
|
||||
return resetValueHolder(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<traits::adc_retval_t<decltype(getter)>>,
|
||||
t);
|
||||
}
|
||||
|
||||
|
||||
template <typename UT>
|
||||
AdcValueHolder& addConvertFunc(std::invocable<std::any&> auto&& func_to_internal,
|
||||
std::invocable<std::any&> auto&& func_from_internal)
|
||||
{
|
||||
static_assert(std::is_same_v<UT, void>, "void IS NOT VALID TYPE!!!");
|
||||
static_assert(!std::is_same_v<UT, void>, "void IS NOT VALID TYPE!!!");
|
||||
|
||||
auto t_index = std::type_index(typeid(UT));
|
||||
|
||||
@ -286,9 +336,13 @@ public:
|
||||
template <typename UT>
|
||||
operator UT()
|
||||
{
|
||||
using v_t = std::remove_reference_t<UT>;
|
||||
using val_t = std::conditional_t<std::is_array_v<v_t>, std::add_pointer_t<std::remove_extent_t<v_t>>, v_t>;
|
||||
|
||||
std::any val;
|
||||
|
||||
auto t_index = std::type_index(typeid(UT));
|
||||
// auto t_index = std::type_index(typeid(UT));
|
||||
auto t_index = std::type_index(typeid(val_t));
|
||||
auto it = _convertFromInternal.find(t_index);
|
||||
|
||||
if (it == _convertFromInternal.end()) {
|
||||
@ -298,15 +352,21 @@ public:
|
||||
_getterWrapper(val);
|
||||
it->second(val); // call conversion function
|
||||
|
||||
return std::any_cast<UT>(val);
|
||||
// return std::any_cast<UT>(val);
|
||||
return std::any_cast<val_t>(val);
|
||||
}
|
||||
|
||||
template <typename UT>
|
||||
AdcValueHolder& operator=(const UT& value)
|
||||
AdcValueHolder& operator=(UT&& value)
|
||||
{
|
||||
std::any val = std::make_any<UT>(value);
|
||||
using v_t = std::remove_reference_t<UT>;
|
||||
using val_t = std::conditional_t<std::is_array_v<v_t>, std::add_pointer_t<std::remove_extent_t<v_t>>, v_t>;
|
||||
|
||||
auto t_index = std::type_index(typeid(UT));
|
||||
// std::any val = std::make_any<UT>(value);
|
||||
std::any val = std::make_any<val_t>(value);
|
||||
|
||||
// auto t_index = std::type_index(typeid(UT));
|
||||
auto t_index = std::type_index(typeid(val_t));
|
||||
auto it = _convertToInternal.find(t_index);
|
||||
|
||||
if (it == _convertToInternal.end()) {
|
||||
@ -358,5 +418,33 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
factory functions
|
||||
|
||||
*/
|
||||
|
||||
AdcValueHolder make_arith_valueholder(std::invocable<> auto&& getter,
|
||||
std::invocable<const traits::adc_retval_t<decltype(getter)>&> auto&& setter,
|
||||
std::predicate<const traits::adc_retval_t<decltype(getter)>&> auto&& validator)
|
||||
{
|
||||
using val_t = traits::adc_retval_t<decltype(getter)>;
|
||||
|
||||
static_assert(std::predicate<decltype(validator), const traits::adc_retval_t<decltype(getter)>&>,
|
||||
"INVALID VALIDATOR TYPE!!!");
|
||||
|
||||
static_assert(std::is_arithmetic_v<val_t>, "GETTER MUST RETURN AN ARITHMETIC TYPE VALUE!!!");
|
||||
|
||||
return AdcValueHolder(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
|
||||
std::forward<decltype(validator)>(validator), AdcValueHolder::_defaultTrivialConvTypes);
|
||||
}
|
||||
|
||||
|
||||
AdcValueHolder make_arith_valueholder(std::invocable<> auto&& getter,
|
||||
std::invocable<const traits::adc_retval_t<decltype(getter)>&> auto&& setter)
|
||||
{
|
||||
return make_arith_valueholder(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
|
||||
AdcValueHolder::AdcValueHolderDummyValidator<traits::adc_retval_t<decltype(getter)>>);
|
||||
}
|
||||
|
||||
|
||||
} // namespace adc
|
||||
|
||||
@ -1,32 +1,17 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include <doctest/doctest.h>
|
||||
#include <iostream>
|
||||
// #include <doctest/doctest.h>
|
||||
|
||||
|
||||
#include "../common/adc_value_holder.h"
|
||||
|
||||
// TEST_CASE("[ADC VALUEHOLDER]")
|
||||
// {
|
||||
// int ch_i = 10;
|
||||
|
||||
// auto getter = [&ch_i]() { return ch_i; };
|
||||
// auto setter = [&ch_i](const int& v) { ch_i = v; };
|
||||
// auto validator = [&ch_i](const int& v) {
|
||||
// if (v < 0)
|
||||
// return false;
|
||||
// else
|
||||
// return true;
|
||||
// };
|
||||
|
||||
// adc::AdcValueHolder vh(getter, setter, validator);
|
||||
// }
|
||||
|
||||
|
||||
int main()
|
||||
TEST_CASE("[ADC VALUEHOLDER]")
|
||||
{
|
||||
int ch_i = 10;
|
||||
int int_val = 10;
|
||||
|
||||
auto getter = [&ch_i]() { return ch_i; };
|
||||
auto setter = [&ch_i](const int& v) { ch_i = v; };
|
||||
auto validator = [&ch_i](const int& v) {
|
||||
auto getter = [&int_val]() { return int_val; };
|
||||
auto setter = [&int_val](const int& v) { int_val = v; };
|
||||
auto validator = [](const int& v) {
|
||||
if (v < 0)
|
||||
return false;
|
||||
else
|
||||
@ -34,11 +19,68 @@ int main()
|
||||
};
|
||||
|
||||
// adc::AdcValueHolder vh(getter, setter, validator);
|
||||
adc::AdcValueHolder vh(getter, setter, adc::AdcValueHolder::_defaultTrivialConvTypes, validator);
|
||||
adc::AdcValueHolder vh(getter, setter, validator);
|
||||
auto vah = adc::make_arith_valueholder(getter, setter);
|
||||
|
||||
vh = 77;
|
||||
|
||||
std::cout << "(vh = 77) => ch_i = " << ch_i << "\n";
|
||||
REQUIRE_EQ(int_val, 77);
|
||||
|
||||
std::cout << (double)vh << "\n";
|
||||
vh = 100;
|
||||
|
||||
int res = vh;
|
||||
|
||||
REQUIRE_EQ(res, 100);
|
||||
|
||||
CHECK_THROWS_WITH_AS(vh = 1.1, "conversion function is not defined", std::system_error);
|
||||
CHECK_THROWS_WITH_AS(vh = -3, "user value is not valid", std::system_error);
|
||||
|
||||
double dv = 33.33;
|
||||
vah = dv;
|
||||
|
||||
REQUIRE_EQ(int_val, 33);
|
||||
|
||||
vah = 100;
|
||||
auto res_long = static_cast<unsigned long>(vah);
|
||||
|
||||
REQUIRE_EQ(res_long, 100ul);
|
||||
|
||||
vah = -10.1234;
|
||||
REQUIRE_EQ(int_val, -10);
|
||||
|
||||
|
||||
/* std::string holder */
|
||||
|
||||
std::string str = "THIS IS A STRING";
|
||||
|
||||
auto sget = [&str]() { return str; };
|
||||
auto sset = [&str](const std::string& s) { str = s; };
|
||||
auto sval = [](const std::string& s) {
|
||||
if (s.size())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
adc::AdcValueHolder vsh(sget, sset, sval);
|
||||
|
||||
vsh.addConvertFunc<const char*>([](std::any& v) { v = std::string(std::any_cast<const char*>(v)); },
|
||||
[](std::any& v) {
|
||||
auto sval = std::any_cast<std::string>(&v);
|
||||
v = sval->c_str();
|
||||
});
|
||||
|
||||
|
||||
vsh = "NEW VALUE";
|
||||
|
||||
REQUIRE_EQ(str, "NEW VALUE");
|
||||
|
||||
const char* sptr = vsh;
|
||||
|
||||
REQUIRE_EQ(std::strcmp(sptr, "NEW VALUE"), 0);
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
CHECK_THROWS_WITH_AS(vsh = ""s, "user value is not valid", std::system_error);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user