aboutsummaryrefslogtreecommitdiffstats
path: root/util/generic/function.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/generic/function.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/generic/function.h')
-rw-r--r--util/generic/function.h103
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();
+}