AdcValueHolder class: tests are passed

This commit is contained in:
Timur A. Fatkhullin 2024-03-24 23:48:52 +03:00
parent a963db2900
commit fad61ea1df
2 changed files with 178 additions and 48 deletions

View File

@ -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

View File

@ -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);
}