This commit is contained in:
Timur A. Fatkhullin 2024-04-30 22:30:04 +03:00
parent b4a4722583
commit 066cb7cf95
3 changed files with 266 additions and 142 deletions

View File

@ -67,7 +67,7 @@ struct adc_func_traits_helper_t<R, Arg, Args...> {
// callable traits
template <typename F>
template <typename F, typename = void>
struct adc_func_traits;
template <typename R, typename... Args>
@ -87,9 +87,17 @@ struct adc_func_traits<R (C::*)(Args...) const> : adc_func_traits_helper_t<R, Ar
};
template <typename F>
struct adc_func_traits : adc_func_traits<decltype(&std::remove_reference_t<F>::operator())> {
// struct adc_func_traits : adc_func_traits<decltype(&std::remove_reference_t<F>::operator())> {
struct adc_func_traits<F, std::enable_if_t<std::is_class_v<F>>> : adc_func_traits<decltype(&F::operator())> {
};
template <typename F>
struct adc_func_traits<F&> : adc_func_traits<F> {
};
template <typename F>
struct adc_func_traits<F&&> : adc_func_traits<F> {
};
template <typename T>
using adc_retval_t = typename adc_func_traits<T>::ret_t;

View File

@ -92,6 +92,9 @@ inline std::error_code make_error_code(AdcValueHolderErrorCode ec)
class AdcValueHolder
{
protected:
template <typename T>
using ret_value_t = std::decay_t<traits::adc_retval_t<T>>;
template <typename VT>
inline static std::unordered_map<const AdcValueHolder*, std::function<VT()>> _getterFunc{};
@ -101,10 +104,10 @@ protected:
std::function<void()> _clearFunc;
void init(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)
std::invocable<const ret_value_t<decltype(getter)>&> auto&& setter,
std::predicate<const ret_value_t<decltype(getter)>&> auto&& validator)
{
using value_t = std::decay_t<traits::adc_retval_t<decltype(getter)>>;
using value_t = ret_value_t<decltype(getter)>;
static_assert(!std::is_same_v<value_t, void>, "THE getter MUST NOT RETURN void TYPE!!!");
@ -162,7 +165,7 @@ public:
/* CONSTRUCTORS AND DESTRUCTOR */
template <typename GT,
typename VALT = traits::adc_retval_t<GT>,
typename VALT = ret_value_t<GT>,
typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<VALT>)>
AdcValueHolder(GT&& getter,
std::invocable<const VALT&> auto&& setter,
@ -176,21 +179,21 @@ public:
template <typename... Ts>
AdcValueHolder(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,
std::invocable<const ret_value_t<decltype(getter)>&> auto&& setter,
std::predicate<const ret_value_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))
{
// setup trivially-defined conversion function
AdcValueHolder::setupTrivialConvertFunc<traits::adc_retval_t<decltype(getter)>, std::tuple<Ts...>>();
AdcValueHolder::setupTrivialConvertFunc<ret_value_t<decltype(getter)>, std::tuple<Ts...>>();
}
template <typename... Ts>
AdcValueHolder(std::invocable<> auto&& getter,
std::invocable<const traits::adc_retval_t<decltype(getter)>&> auto&& setter,
std::invocable<const ret_value_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),
@ -209,13 +212,11 @@ public:
/* PUBLIC METHODS */
template <typename GT,
typename VALT = traits::adc_retval_t<GT>,
typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<VALT>)>
template <typename GT, typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<ret_value_t<GT>>)>
AdcValueHolder& resetValueHolder(GT&& getter,
std::invocable<const VALT&> auto&& setter,
VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator<VALT>)
requires std::invocable<GT> && std::predicate<VT, const VALT&>
std::invocable<const ret_value_t<GT>&> auto&& setter,
VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator<ret_value_t<GT>>)
requires std::invocable<GT> && std::predicate<VT, const ret_value_t<GT>&>
{
_clearFunc();
@ -228,15 +229,15 @@ public:
template <typename... Ts>
AdcValueHolder& resetValueHolder(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,
std::invocable<const ret_value_t<decltype(getter)>&> auto&& setter,
std::predicate<const ret_value_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));
// setup trivially-defined conversion function
setupTrivialConvertFunc<traits::adc_retval_t<decltype(getter)>, std::tuple<Ts...>>();
setupTrivialConvertFunc<ret_value_t<decltype(getter)>, std::tuple<Ts...>>();
return *this;
}
@ -244,24 +245,26 @@ public:
template <typename... Ts>
AdcValueHolder& resetValueHolder(std::invocable<> auto&& getter,
std::invocable<const traits::adc_retval_t<decltype(getter)>&> auto&& setter,
std::invocable<const ret_value_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);
AdcValueHolder::AdcValueHolderDummyValidator<ret_value_t<decltype(getter)>>, t);
}
template <typename FromFuncT, typename ToFuncT>
AdcValueHolder& addConvertFunc(FromFuncT&& func_from_internal, ToFuncT&& func_to_internal)
requires std::invocable<FromFuncT, std::decay_t<traits::adc_retval_t<ToFuncT>>> &&
std::invocable<ToFuncT, std::decay_t<traits::adc_retval_t<FromFuncT>>>
requires std::invocable<FromFuncT, const ret_value_t<ToFuncT>&> &&
std::invocable<ToFuncT, const ret_value_t<FromFuncT>&>
{
using from_sig_t = typename traits::adc_func_traits<FromFuncT>;
using to_sig_t = typename traits::adc_func_traits<ToFuncT>;
using value_t = std::decay_t<typename to_sig_t::ret_t>; // internal value type
using user_t = std::decay_t<typename from_sig_t::ret_t>;
// using from_sig_t = typename traits::adc_func_traits<FromFuncT>;
// using to_sig_t = typename traits::adc_func_traits<ToFuncT>;
// using value_t = std::decay_t<typename to_sig_t::ret_t>; // internal value type
// using user_t = std::decay_t<typename from_sig_t::ret_t>;
using value_t = ret_value_t<ToFuncT>; // it must be internal value type
using user_t = ret_value_t<FromFuncT>;
_getterFunc<user_t>[this] = [wrapper = traits::adc_pf_wrapper(std::forward<FromFuncT>(func_from_internal)),
this]() {
@ -319,8 +322,8 @@ public:
auto setter = _setterFunc<val_t>[this];
if (setter) {
// setter(std::forward<UT>(value));
setter(value);
setter(std::forward<UT>(value));
// setter(value);
} else {
throw std::system_error(AdcValueHolderErrorCode::ERROR_NO_CONV_FUNC);
}
@ -357,6 +360,181 @@ protected:
};
/* */
template <typename SerializedT = std::string>
class AdcSerializingValueHolder : public AdcValueHolder
{
protected:
std::function<SerializedT()> _serializerWrapper;
std::function<void(const SerializedT&)> _deserializerWrapper;
template <typename ValueT, typename SRT, typename DSRT>
void initWrappers(SRT&& serializer, DSRT&& deserializer)
requires std::invocable<SRT, const ValueT&> && std::invocable<DSRT, const SerializedT&>
{
static_assert(std::is_convertible_v<traits::adc_retval_t<SRT>, SerializedT>,
"INVALID RETURNED TYPE OF SERIALIZING CALLABLE!!!");
static_assert(std::is_convertible_v<traits::adc_retval_t<DSRT>, ValueT>,
"INVALID RETURNED TYPE OF DESERIALIZING CALLABLE!!!");
_serializerWrapper = [wrapper = traits::adc_pf_wrapper(std::forward<SRT>(serializer)), this]() {
auto& serializer = std::get<0>(wrapper);
auto val = _getterFunc<ValueT>[this]();
return serializer(val);
};
_deserializerWrapper = [wrapper = traits::adc_pf_wrapper(std::forward<DSRT>(deserializer)),
this](const SerializedT& sval) {
auto& deserializer = std::get<0>(wrapper);
ValueT val = deserializer(sval);
_setterFunc<ValueT>[this](val);
};
}
public:
/* CONSTRUCTORS AND DESTRUCTOR */
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>)>
AdcSerializingValueHolder(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&>
: AdcValueHolder(std::forward<GT>(getter), std::forward<ST>(setter), std::forward<VT>(validator))
{
initWrappers<VALT>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
template <typename GT,
typename ST,
typename VALT = ret_value_t<GT>,
typename VT,
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>),
typename... Ts>
AdcSerializingValueHolder(GT&& getter,
ST&& setter,
VT&& validator,
const std::tuple<Ts...>&,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)
: AdcValueHolder(std::forward<GT>(getter),
std::forward<ST>(setter),
std::forward<VT>(validator),
std::tuple<Ts...>{})
{
initWrappers<VALT>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
template <typename GT,
typename ST,
typename VALT = ret_value_t<GT>,
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>),
typename... Ts>
AdcSerializingValueHolder(GT&& getter,
ST&& setter,
const std::tuple<Ts...>&,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)
: AdcValueHolder(std::forward<GT>(getter),
std::forward<ST>(setter),
AdcValueHolder::AdcValueHolderDummyValidator<VALT>,
std::tuple<Ts...>{})
{
initWrappers<VALT>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
virtual ~AdcSerializingValueHolder() = default;
/* PUBLIC METHODS */
template <typename GT,
typename ST,
typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<ret_value_t<GT>>),
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, ret_value_t<GT>>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<ret_value_t<GT>, SerializedT>)>
AdcSerializingValueHolder& resetValueHolder(
GT&& getter,
ST&& setter,
VT&& validator = AdcValueHolder::AdcValueHolderDummyValidator<ret_value_t<GT>>,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, ret_value_t<GT>>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<ret_value_t<GT>, SerializedT>)
{
AdcValueHolder::resetValueHolder(std::forward<GT>(getter), std::forward<ST>(setter),
std::forward<VT>(validator));
initWrappers<ret_value_t<GT>>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
template <typename GT,
typename ST,
typename VT,
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, ret_value_t<GT>>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<ret_value_t<GT>, SerializedT>),
typename... Ts>
AdcSerializingValueHolder& resetValueHolder(
GT&& getter,
ST&& setter,
VT&& validator,
const std::tuple<Ts...>&,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, ret_value_t<GT>>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<ret_value_t<GT>, SerializedT>)
{
AdcValueHolder::resetValueHolder(std::forward<GT>(getter), std::forward<ST>(setter),
std::forward<VT>(validator), std::tuple<Ts...>{});
initWrappers<ret_value_t<GT>>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
template <typename GT,
typename ST,
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, ret_value_t<GT>>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<ret_value_t<GT>, SerializedT>),
typename... Ts>
AdcSerializingValueHolder& resetValueHolder(
GT&& getter,
ST&& setter,
const std::tuple<Ts...>&,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, ret_value_t<GT>>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<ret_value_t<GT>, SerializedT>)
{
AdcValueHolder::resetValueHolder(std::forward<GT>(getter), std::forward<ST>(setter), std::tuple<Ts...>{});
initWrappers<ret_value_t<GT>>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
SerializedT serialize() { return _serializerWrapper(); }
void deserialize(const SerializedT& sval) { _deserializerWrapper(sval); }
using AdcValueHolder::operator=;
};
/*
factory functions
@ -382,117 +560,5 @@ AdcValueHolder make_arith_valueholder(GT&& getter,
}
/* */
template <typename SerializedT = std::string>
class AdcSerializingValueHolder : public AdcValueHolder
{
protected:
std::function<SerializedT()> _serializerWrapper;
std::function<void(const SerializedT&)> _deserializerWrapper;
template <typename ValueT, typename SRT, typename DSRT>
void initWrappers(SRT&& serializer, DSRT&& deserializer)
{
static_assert(std::is_convertible_v<traits::adc_retval_t<SRT>, SerializedT>,
"INVALID RETURNED TYPE OF SERIALIZING CALLABLE!!!");
static_assert(std::is_convertible_v<traits::adc_retval_t<DSRT>, ValueT>,
"INVALID RETURNED TYPE OF DESERIALIZING CALLABLE!!!");
_serializerWrapper = [wrapper = traits::adc_pf_wrapper(std::forward<SRT>(serializer)), this]() {
auto& serializer = std::get<0>(wrapper);
auto val = _getterFunc<ValueT>[this]();
return serializer(val);
};
_serializerWrapper = [wrapper = traits::adc_pf_wrapper(std::forward<DSRT>(deserializer)),
this](const SerializedT& sval) {
auto& deserializer = std::get<0>(wrapper);
ValueT val = deserializer(sval);
_setterFunc<ValueT>[this](val);
};
}
public:
/* CONSTRUCTORS AND DESTRUCTOR */
template <typename GT,
typename ST,
typename VALT = std::decay_t<traits::adc_retval_t<GT>>,
typename VT = decltype(AdcValueHolder::AdcValueHolderDummyValidator<VALT>),
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)>
AdcSerializingValueHolder(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<SRT, VALT> && std::invocable<DSRT, SerializedT>
: AdcValueHolder(std::forward<GT>(getter), std::forward<ST>(setter), std::forward<VT>(validator))
{
initWrappers<VALT>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
template <typename GT,
typename ST,
typename VALT = std::decay_t<traits::adc_retval_t<GT>>,
typename VT,
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>),
typename... Ts>
AdcSerializingValueHolder(GT&& getter,
ST&& setter,
VT&& validator,
const std::tuple<Ts...>&,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)
: AdcValueHolder(std::forward<GT>(getter),
std::forward<ST>(setter),
std::forward<VT>(validator),
std::tuple<Ts...>{})
{
initWrappers<VALT>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
template <typename GT,
typename ST,
typename VALT = std::decay_t<traits::adc_retval_t<GT>>,
typename SRT = decltype(utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>),
typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>),
typename... Ts>
AdcSerializingValueHolder(GT&& getter,
ST&& setter,
const std::tuple<Ts...>&,
SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize<SerializedT, VALT>,
DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize<VALT, SerializedT>)
: AdcValueHolder(std::forward<GT>(getter),
std::forward<ST>(setter),
AdcValueHolder::AdcValueHolderDummyValidator<VALT>,
std::tuple<Ts...>{})
{
initWrappers<VALT>(std::forward<SRT>(serializer), std::forward<DSRT>(deserializer));
}
virtual ~AdcSerializingValueHolder() = default;
/* PUBLIC METHODS */
SerializedT serialize() { return _serializerWrapper(); }
void deserialize(const SerializedT& sval) { _deserializerWrapper(sval); }
};
} // namespace adc

View File

@ -8,6 +8,31 @@
// #include "../common/adc_value_holder.h"
#include "../common/adc_value.h"
static double dbl_val = 99.99;
double gdbl()
{
return dbl_val;
}
void sdbl(const double& v)
{
dbl_val = v;
}
bool vdbl(const double& v)
{
if (v < 1.0) {
return false;
}
return true;
}
TEST_CASE("[ADC VALUEHOLDER]")
{
int int_val = 10;
@ -149,4 +174,29 @@ TEST_CASE("[ADC VALUEHOLDER]")
std::cout << "ZZ = " << zz << "\n";
std::cout << "ELAPS: " << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << " mksec\n";
adc::AdcSerializingValueHolder svh(getter, setter, validator, adc::AdcValueHolder::_defaultTrivialConvTypes);
svh = 77.65412;
std::cout << "SERIALIZED: " << svh.serialize() << "\n";
svh.deserialize("123");
float fl = svh;
std::cout << "DESERIALIZED: " << fl << "\n";
// vsh.resetValueHolder(gdbl, sdbl, vdbl, adc::AdcValueHolder::_defaultTrivialConvTypes);
// fl = vsh;
// std::cout << "VSH: " << fl << "\n";
// svh.resetValueHolder(gdbl, sdbl, vdbl, adc::AdcValueHolder::_defaultTrivialConvTypes);
svh.resetValueHolder([]() { return dbl_val; }, [](const double& v) { dbl_val = v; },
[](const double&) { return true; }, adc::AdcValueHolder::_defaultTrivialConvTypes);
std::cout << "SERIALIZED: " << svh.serialize() << "\n";
svh.deserialize("123.123");
res = svh;
std::cout << "DESERIALIZED: " << res << "\n";
}