105 lines
3.1 KiB
C++
105 lines
3.1 KiB
C++
#ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
|
|
#define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
|
|
|
|
/// Copyright (c) 2018-2021 Emil Dotchevski and Reverge Studios, Inc.
|
|
|
|
/// 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)
|
|
|
|
#ifndef BOOST_LEAF_ENABLE_WARNINGS ///
|
|
# if defined(_MSC_VER) ///
|
|
# pragma warning(push,1) ///
|
|
# elif defined(__clang__) ///
|
|
# pragma clang system_header ///
|
|
# elif (__GNUC__*100+__GNUC_MINOR__>301) ///
|
|
# pragma GCC system_header ///
|
|
# endif ///
|
|
#endif ///
|
|
|
|
#include <boost/leaf/detail/mp11.hpp>
|
|
#include <tuple>
|
|
|
|
namespace boost { namespace leaf {
|
|
|
|
namespace leaf_detail
|
|
{
|
|
template<class...>
|
|
struct gcc49_workaround //Thanks Glen Fernandes
|
|
{
|
|
using type = void;
|
|
};
|
|
|
|
template<class... T>
|
|
using void_t = typename gcc49_workaround<T...>::type;
|
|
|
|
template<class F,class V=void>
|
|
struct function_traits
|
|
{
|
|
constexpr static int arity = -1;
|
|
};
|
|
|
|
template<class F>
|
|
struct function_traits<F, void_t<decltype(&F::operator())>>
|
|
{
|
|
private:
|
|
|
|
using tr = function_traits<decltype(&F::operator())>;
|
|
|
|
public:
|
|
|
|
using return_type = typename tr::return_type;
|
|
static constexpr int arity = tr::arity - 1;
|
|
|
|
using mp_args = typename leaf_detail_mp11::mp_rest<typename tr::mp_args>;
|
|
|
|
template <int I>
|
|
struct arg:
|
|
tr::template arg<I+1>
|
|
{
|
|
};
|
|
};
|
|
|
|
template<class R, class... A>
|
|
struct function_traits<R(A...)>
|
|
{
|
|
using return_type = R;
|
|
static constexpr int arity = sizeof...(A);
|
|
|
|
using mp_args = leaf_detail_mp11::mp_list<A...>;
|
|
|
|
template <int I>
|
|
struct arg
|
|
{
|
|
static_assert(I < arity, "I out of range");
|
|
using type = typename std::tuple_element<I,std::tuple<A...>>::type;
|
|
};
|
|
};
|
|
|
|
template<class F> struct function_traits<F&> : function_traits<F> { };
|
|
template<class F> struct function_traits<F&&> : function_traits<F> { };
|
|
template<class R, class... A> struct function_traits<R(*)(A...)> : function_traits<R(A...)> { };
|
|
template<class R, class... A> struct function_traits<R(* &)(A...)> : function_traits<R(A...)> { };
|
|
template<class R, class... A> struct function_traits<R(* const &)(A...)> : function_traits<R(A...)> { };
|
|
template<class C, class R, class... A> struct function_traits<R(C::*)(A...)> : function_traits<R(C&,A...)> { };
|
|
template<class C, class R, class... A> struct function_traits<R(C::*)(A...) const> : function_traits<R(C const &,A...)> { };
|
|
template<class C, class R> struct function_traits<R(C::*)> : function_traits<R(C&)> { };
|
|
|
|
template <class F>
|
|
using fn_return_type = typename function_traits<F>::return_type;
|
|
|
|
template <class F, int I>
|
|
using fn_arg_type = typename function_traits<F>::template arg<I>::type;
|
|
|
|
template <class F>
|
|
using fn_mp_args = typename function_traits<F>::mp_args;
|
|
|
|
}
|
|
|
|
} }
|
|
|
|
#if defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) ///
|
|
#pragma warning(pop) ///
|
|
#endif ///
|
|
|
|
#endif
|