diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/generic/function.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/generic/function.h')
-rw-r--r-- | util/generic/function.h | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/util/generic/function.h b/util/generic/function.h new file mode 100644 index 0000000000..62fa84e0cb --- /dev/null +++ b/util/generic/function.h @@ -0,0 +1,103 @@ +#pragma once + +#include "typetraits.h" +#include "typelist.h" + +#include <functional> + +namespace NPrivate { + template <class F> + struct TRemoveClassImpl { + using TSignature = F; + }; + + template <typename C, typename R, typename... Args> + struct TRemoveClassImpl<R (C::*)(Args...)> { + typedef R TSignature(Args...); + }; + + template <typename C, typename R, typename... Args> + struct TRemoveClassImpl<R (C::*)(Args...) const> { + typedef R TSignature(Args...); + }; + + template <class T> + struct TRemoveNoExceptImpl { + using Type = T; + }; + + template <typename R, typename... Args> + struct TRemoveNoExceptImpl<R(Args...) noexcept> { + using Type = R(Args...); + }; + + template <typename R, typename C, typename... Args> + struct TRemoveNoExceptImpl<R (C::*)(Args...) noexcept> { + using Type = R (C::*)(Args...); + }; + + template <class T> + using TRemoveNoExcept = typename TRemoveNoExceptImpl<T>::Type; + + template <class F> + using TRemoveClass = typename TRemoveClassImpl<TRemoveNoExcept<F>>::TSignature; + + template <class C> + struct TFuncInfo { + using TSignature = TRemoveClass<decltype(&C::operator())>; + }; + + template <class R, typename... Args> + struct TFuncInfo<R(Args...)> { + using TResult = R; + typedef R TSignature(Args...); + }; +} + +template <class C> +using TFunctionSignature = typename ::NPrivate::TFuncInfo<::NPrivate::TRemoveClass<std::remove_reference_t<std::remove_pointer_t<C>>>>::TSignature; + +template <typename F> +struct TCallableTraits: public TCallableTraits<TFunctionSignature<F>> { +}; + +template <typename R, typename... Args> +struct TCallableTraits<R(Args...)> { + using TResult = R; + using TArgs = TTypeList<Args...>; + typedef R TSignature(Args...); +}; + +template <typename C> +using TFunctionResult = typename TCallableTraits<C>::TResult; + +template <typename C> +using TFunctionArgs = typename TCallableTraits<C>::TArgs; + +template <typename C, size_t N> +struct TFunctionArgImpl { + using TArgs = TFunctionArgs<C>; + using TResult = typename TArgs::template TGet<N>; +}; + +template <typename C, size_t N> +using TFunctionArg = typename TFunctionArgImpl<C, N>::TResult; + +// temporary before std::apply appearance + +template <typename F, typename Tuple, size_t... I> +auto ApplyImpl(F&& f, Tuple&& t, std::index_sequence<I...>) { + return f(std::get<I>(std::forward<Tuple>(t))...); +} + +// change to std::apply after c++ 17 +template <typename F, typename Tuple> +auto Apply(F&& f, Tuple&& t) { + return ApplyImpl(f, t, std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}); +} + +// change to std::apply after c++ 17 +template <typename F> +auto Apply(F&& f, std::tuple<>) { + return f(); +} |