]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/leaf/detail/function_traits.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / leaf / detail / function_traits.hpp
1 #ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
2 #define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
3
4 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
5
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)
8
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)
16 # endif
17 #endif
18
19 #include <boost/leaf/detail/mp11.hpp>
20 #include <tuple>
21
22 namespace boost { namespace leaf {
23
24 namespace leaf_detail
25 {
26 template<class...>
27 struct gcc49_workaround //Thanks Glen Fernandes
28 {
29 using type = void;
30 };
31
32 template<class... T>
33 using void_t = typename gcc49_workaround<T...>::type;
34
35 template<class F,class V=void>
36 struct function_traits
37 {
38 constexpr static int arity = -1;
39 };
40
41 template<class F>
42 struct function_traits<F, void_t<decltype(&F::operator())>>
43 {
44 private:
45
46 using tr = function_traits<decltype(&F::operator())>;
47
48 public:
49
50 using return_type = typename tr::return_type;
51 static constexpr int arity = tr::arity - 1;
52
53 using mp_args = typename leaf_detail_mp11::mp_rest<typename tr::mp_args>;
54
55 template <int I>
56 struct arg:
57 tr::template arg<I+1>
58 {
59 };
60 };
61
62 template<class R, class... A>
63 struct function_traits<R(A...)>
64 {
65 using return_type = R;
66 static constexpr int arity = sizeof...(A);
67
68 using mp_args = leaf_detail_mp11::mp_list<A...>;
69
70 template <int I>
71 struct arg
72 {
73 static_assert(I < arity, "I out of range");
74 using type = typename std::tuple_element<I,std::tuple<A...>>::type;
75 };
76 };
77
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&)> { };
86
87 template <class F>
88 using fn_return_type = typename function_traits<F>::return_type;
89
90 template <class F, int I>
91 using fn_arg_type = typename function_traits<F>::template arg<I>::type;
92
93 template <class F>
94 using fn_mp_args = typename function_traits<F>::mp_args;
95
96 }
97
98 } }
99
100 #endif