#pragma once #include "typetraits.h" #include "typelist.h" #include namespace NPrivate { template struct TRemoveClassImpl { using TSignature = F; }; #define Y_EMPTY_REF_QUALIFIER #define Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(XX) \ XX(Y_EMPTY_REF_QUALIFIER) \ XX(&) \ XX(&&) \ XX(const) \ XX(const&) \ XX(const&&) #define Y_DECLARE_REMOVE_CLASS_IMPL(qualifiers) \ template \ struct TRemoveClassImpl { \ typedef R TSignature(Args...); \ }; Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(Y_DECLARE_REMOVE_CLASS_IMPL) #undef Y_DECLARE_REMOVE_CLASS_IMPL template struct TRemoveNoExceptImpl { using Type = T; }; template struct TRemoveNoExceptImpl { using Type = R(Args...); }; #define Y_DECLARE_REMOVE_NOEXCEPT_IMPL(qualifiers) \ template \ struct TRemoveNoExceptImpl { \ using Type = R (C::*)(Args...); \ }; Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(Y_DECLARE_REMOVE_NOEXCEPT_IMPL) #undef Y_DECLARE_REMOVE_NOEXCEPT_IMPL #undef Y_FOR_EACH_REF_QUALIFIERS_COMBINATION #undef Y_EMPTY_REF_QUALIFIER template using TRemoveNoExcept = typename TRemoveNoExceptImpl::Type; template using TRemoveClass = typename TRemoveClassImpl>::TSignature; template struct TFuncInfo { using TSignature = TRemoveClass; }; template struct TFuncInfo { using TResult = R; typedef R TSignature(Args...); }; } template using TFunctionSignature = typename ::NPrivate::TFuncInfo<::NPrivate::TRemoveClass>>>::TSignature; template struct TCallableTraits: public TCallableTraits> { }; template struct TCallableTraits { using TResult = R; using TArgs = TTypeList; typedef R TSignature(Args...); }; template using TFunctionResult = typename TCallableTraits::TResult; template using TFunctionArgs = typename TCallableTraits::TArgs; template struct TFunctionArgImpl { using TArgs = TFunctionArgs; using TResult = typename TArgs::template TGet; }; template using TFunctionArg = typename TFunctionArgImpl::TResult; // temporary before std::apply appearance template auto ApplyImpl(F&& f, Tuple&& t, std::index_sequence) { return f(std::get(std::forward(t))...); } // change to std::apply after c++ 17 template auto Apply(F&& f, Tuple&& t) { return ApplyImpl(f, t, std::make_index_sequence>::value>{}); } // change to std::apply after c++ 17 template auto Apply(F&& f, std::tuple<>) { return f(); }