1 #ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
2 #define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
4 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 #ifndef BOOST_LEAF_ENABLE_WARNINGS
10 # if defined(__clang__)
11 # pragma clang system_header
12 # elif (__GNUC__*100+__GNUC_MINOR__>301)
13 # pragma GCC system_header
14 # elif defined(_MSC_VER)
15 # pragma warning(push,1)
19 #include <boost/leaf/detail/mp11.hpp>
22 namespace boost { namespace leaf {
27 struct gcc49_workaround //Thanks Glen Fernandes
33 using void_t = typename gcc49_workaround<T...>::type;
35 template<class F,class V=void>
36 struct function_traits
38 constexpr static int arity = -1;
42 struct function_traits<F, void_t<decltype(&F::operator())>>
46 using tr = function_traits<decltype(&F::operator())>;
50 using return_type = typename tr::return_type;
51 static constexpr int arity = tr::arity - 1;
53 using mp_args = typename leaf_detail_mp11::mp_rest<typename tr::mp_args>;
62 template<class R, class... A>
63 struct function_traits<R(A...)>
65 using return_type = R;
66 static constexpr int arity = sizeof...(A);
68 using mp_args = leaf_detail_mp11::mp_list<A...>;
73 static_assert(I < arity, "I out of range");
74 using type = typename std::tuple_element<I,std::tuple<A...>>::type;
78 template<class F> struct function_traits<F&> : function_traits<F> { };
79 template<class F> struct function_traits<F&&> : function_traits<F> { };
80 template<class R, class... A> struct function_traits<R(*)(A...)> : function_traits<R(A...)> { };
81 template<class R, class... A> struct function_traits<R(* &)(A...)> : function_traits<R(A...)> { };
82 template<class R, class... A> struct function_traits<R(* const &)(A...)> : function_traits<R(A...)> { };
83 template<class C, class R, class... A> struct function_traits<R(C::*)(A...)> : function_traits<R(C&,A...)> { };
84 template<class C, class R, class... A> struct function_traits<R(C::*)(A...) const> : function_traits<R(C const &,A...)> { };
85 template<class C, class R> struct function_traits<R(C::*)> : function_traits<R(C&)> { };
88 using fn_return_type = typename function_traits<F>::return_type;
90 template <class F, int I>
91 using fn_arg_type = typename function_traits<F>::template arg<I>::type;
94 using fn_mp_args = typename function_traits<F>::mp_args;