#pragma once #include "typetraits.h" #include "typelist.h" #include namespace NPrivate { template struct TRemoveClassImpl { using TSignature = F; }; template struct TRemoveClassImpl { typedef R TSignature(Args...); }; template struct TRemoveClassImpl { typedef R TSignature(Args...); }; template struct TRemoveNoExceptImpl { using Type = T; }; template struct TRemoveNoExceptImpl { using Type = R(Args...); }; template struct TRemoveNoExceptImpl { using Type = R (C::*)(Args...); }; 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(); }