// Copyright satoren // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #pragma once #include #include "kaguya/config.hpp" namespace kaguya { namespace util { struct null_type {}; template struct TypeTuple {}; template struct FunctionSignatureType { typedef Ret result_type; typedef TypeTuple argument_type_tuple; static const size_t argument_count = sizeof...(Args); typedef Ret (*c_function_type)(Args...); }; template struct FunctorSignature {}; template struct FunctorSignature { typedef FunctionSignatureType type; }; template struct FunctorSignature { typedef FunctionSignatureType type; }; #if defined(_MSC_VER) && _MSC_VER < 1900 template struct FunctionSignature : public FunctorSignature {}; #else template struct FunctionSignature; template struct has_operator_fn : std::false_type {}; template struct has_operator_fn::value>::type> : std::true_type {}; template struct FunctionSignature< T, typename std::enable_if::value>::type> : public FunctorSignature {}; #endif template struct FunctionSignature { typedef FunctionSignatureType type; }; template struct FunctionSignature { typedef FunctionSignatureType type; }; #if defined(_MSC_VER) && _MSC_VER >= 1900 || defined(__cpp_ref_qualifiers) template struct FunctionSignature { typedef FunctionSignatureType type; }; template struct FunctionSignature { typedef FunctionSignatureType type; }; #endif template struct FunctionSignature { typedef FunctionSignatureType type; }; template struct FunctionSignature { typedef FunctionSignatureType type; }; template struct FunctionResultType { typedef typename FunctionSignature::type::result_type type; }; template struct TypeIndexGet; template struct TypeIndexGet, true> { typedef Arg type; }; template struct TypeIndexGet, false> : TypeIndexGet > {}; template struct ArgumentType { typedef typename TypeIndexGet< N, typename FunctionSignature::type::argument_type_tuple>::type type; }; namespace detail { template auto invoke_helper(F &&f, ThisType &&this_, Args &&... args) -> decltype((std::forward(this_).* f)(std::forward(args)...)) { return (std::forward(this_).*f)(std::forward(args)...); } template auto invoke_helper(F &&f, Args &&... args) -> decltype(f(std::forward(args)...)) { return f(std::forward(args)...); } } template typename FunctionResultType::type>::type invoke(F &&f, Args &&... args) { return detail::invoke_helper(std::forward(f), std::forward(args)...); } } }