This commit is contained in:
Timur A. Fatkhullin
2024-01-21 01:57:15 +03:00
parent 096e74c099
commit 41a9c70e70
5 changed files with 224 additions and 43 deletions

View File

@@ -107,22 +107,13 @@ protected:
std::type_index _internalTypeIndex;
constexpr static std::tuple<char, short, int, long, long long, float, double> _defaultConvTypes{};
public:
// always-true validator
constexpr static auto AdcValueHolderDummyValidator = [](const auto&) { return true; };
/* CONSTRUCTORS AND DESTRUCTOR */
AdcValueHolder(std::invocable<> auto&& getter,
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
std::predicate<const arg_t<decltype(getter)>&> auto&& validator = AdcValueHolderDummyValidator)
: _internalTypeIndex(std::type_index(typeid(arg_t<decltype(getter)>)))
void init(std::invocable<> auto&& getter,
std::invocable<const arg_t<decltype(getter)>&> auto&& setter,
std::predicate<const arg_t<decltype(getter)>&> auto&& validator)
{
using value_t = arg_t<decltype(getter)>;
static_assert(std::is_same_v<value_t, void>, "THE getter MUST NOT RETURN void type!!!");
static_assert(std::is_same_v<value_t, void>, "THE getter MUST NOT RETURN void TYPE!!!");
using g_t = decltype(getter);
_getterWrapper = [wrapper = traits::adc_pf_wrapper(std::forward<g_t>(getter))](std::any& val) {
@@ -164,6 +155,40 @@ public:
_convertToInternal[_internalTypeIndex] = [](auto) {};
}
public:
// default trivial types (just arithmetic ones)
constexpr static std::tuple<char, short, int, long, long long, float, double> _defaultTrivialConvTypes{};
// always-true validator
constexpr static auto AdcValueHolderDummyValidator = [](const auto&) { return true; };
/* CONSTRUCTORS AND DESTRUCTOR */
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)
: _internalTypeIndex(std::type_index(typeid(arg_t<decltype(getter)>)))
{
init(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
std::forward<decltype(validator)>(validator));
}
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)
: AdcValueHolder(std::forward<decltype(getter)>(getter),
std::forward<decltype(setter)>(setter),
std::forward<decltype(validator)>(validator))
{
// setup trivially-defined conversion function
AdcValueHolder::setupTrivialConvertFunc<arg_t<decltype(getter)>, std::tuple<Ts...>>(this);
}
AdcValueHolder(const AdcValueHolder&) = default;
AdcValueHolder(AdcValueHolder&&) = default;
@@ -184,6 +209,38 @@ 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)
{
_convertFromInternal.clear();
_convertToInternal.clear();
init(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
std::forward<decltype(validator)>(validator));
return *this;
}
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)
{
resetValueHolder(std::forward<decltype(getter)>(getter), std::forward<decltype(setter)>(setter),
std::forward<decltype(validator)>(validator));
// setup trivially-defined conversion function
AdcValueHolder::setupTrivialConvertFunc<arg_t<decltype(getter)>, std::tuple<Ts...>>(this);
return *this;
}
template <typename UT>
AdcValueHolder& addConvertFunc(std::invocable<std::any&> auto&& func_to_internal,
std::invocable<std::any&> auto&& func_from_internal)
@@ -202,10 +259,11 @@ public:
template <typename UT = void>
AdcValueHolder& delConvertFunc()
{
if constexpr (std::is_same_v<UT, void>) {
if constexpr (std::is_same_v<UT, void>) { // delete all conversion functions
_convertFromInternal.clear();
_convertToInternal.clear();
// restore conversion functions for internal type
_convertFromInternal[_internalTypeIndex] = [](auto) {};
_convertToInternal[_internalTypeIndex] = [](auto) {};
} else {
@@ -261,47 +319,35 @@ public:
AdcValueHolder& operator=(const AdcValueHolder& other) = default;
template <typename ValueT, typename TupleT = decltype(AdcValueHolder::_defaultConvTypes)>
friend AdcValueHolder& setupDefaultConvFunc(AdcValueHolder& holder)
{
auto t_index = std::type_index(typeid(ValueT));
if (t_index != holder._internalTypeIndex) {
throw std::system_error(AdcValueHolderErrorCode::ERROR_INTERNAL_TYPE_MISMATCH);
}
AdcValueHolder::setupDefaultConvertFunc<ValueT, TupleT>(&holder);
return holder;
}
protected:
/* STATIC HELPER METHODS */
template <typename VT, size_t I, typename TupleT>
static void setupDefaultConvertFuncImpl(AdcValueHolder* holder)
static void setupTrivialConvertFuncImpl(AdcValueHolder* holder)
{
if constexpr (I < std::tuple_size_v<TupleT>) {
using elem_t = std::tuple_element_t<I, TupleT>;
auto t_index = std::type_index(typeid(elem_t));
holder->_convertToInternal[t_index] = [](std::any& val) {
val = std::make_any<VT>(std::any_cast<elem_t>(val));
};
if constexpr (!std::is_same_v<VT, elem_t>) {
auto t_index = std::type_index(typeid(elem_t));
holder->_convertFromInternal[t_index] = [](std::any& val) {
val = std::make_any<elem_t>(std::any_cast<VT>(val));
};
holder->_convertToInternal[t_index] = [](std::any& val) {
val = std::make_any<VT>(std::any_cast<elem_t>(val));
};
AdcValueHolder::setupDefaultConvertFuncImpl<VT, I + 1, TupleT>(holder);
holder->_convertFromInternal[t_index] = [](std::any& val) {
val = std::make_any<elem_t>(std::any_cast<VT>(val));
};
}
AdcValueHolder::setupTrivialConvertFuncImpl<VT, I + 1, TupleT>(holder);
}
}
template <typename VT, typename TupleT>
static void setupDefaultConvertFunc(AdcValueHolder* holder)
static void setupTrivialConvertFunc(AdcValueHolder* holder)
{
setupDefaultConvertFuncImpl<VT, 0, TupleT>(holder);
setupTrivialConvertFuncImpl<VT, 0, TupleT>(holder);
}
};