1// Boost result_of library
2
3// Copyright Douglas Gregor 2004. Use, modification and
4// distribution is subject to the Boost Software License, Version
5// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7
8// Copyright Daniel Walker, Eric Niebler, Michel Morin 2008-2012.
9// Use, modification and distribution is subject to the Boost Software
10// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or
11// copy at http://www.boost.org/LICENSE_1_0.txt)
12
13// For more information, see http://www.boost.org/libs/utility
14
15#ifndef BOOST_RESULT_OF_HPP
16# error Boost result_of - do not include this file!
17#endif
18
19template<typename F, typename... Args>
20struct tr1_result_of<F(Args...)>
21 : conditional<
22 is_pointer<F>::value || is_member_function_pointer<F>::value
23 , boost::detail::tr1_result_of_impl<
24 typename remove_cv<F>::type,
25 typename remove_cv<F>::type(Args...),
26 (boost::detail::result_of_has_result_type<F>::value)>
27 , boost::detail::tr1_result_of_impl<
28 F,
29 F(Args...),
30 (boost::detail::result_of_has_result_type<F>::value)> >::type { };
31
32#ifdef BOOST_RESULT_OF_USE_DECLTYPE
33template<typename F, typename... Args>
34struct result_of<F(Args...)>
35 : detail::cpp0x_result_of<F(Args...)> { };
36#endif // BOOST_RESULT_OF_USE_DECLTYPE
37
38#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
39template<typename F, typename... Args>
40struct result_of<F(Args...)>
41 : conditional<detail::result_of_has_result_type<F>::value || detail::result_of_has_result<F>::value,
42 tr1_result_of<F(Args...)>,
43 detail::cpp0x_result_of<F(Args...)> >::type { };
44#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
45
46#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
47
48namespace detail {
49
50template<typename F, typename... Args>
51struct cpp0x_result_of<F(Args...)>
52 : conditional<
53 is_member_function_pointer<F>::value
54 , detail::tr1_result_of_impl<
55 typename remove_cv<F>::type,
56 typename remove_cv<F>::type(Args...), false
57 >
58 , detail::cpp0x_result_of_impl<
59 F(Args...)
60 >
61 >::type
62{};
63
64#ifdef BOOST_NO_SFINAE_EXPR
65
66template<typename F>
67struct result_of_callable_fun_2;
68
69template<typename R, typename... Args>
70struct result_of_callable_fun_2<R(Args...)> {
71 R operator()(Args...) const;
72 typedef result_of_private_type const &(*pfn_t)(...);
73 operator pfn_t() const volatile;
74};
75
76template<typename F>
77struct result_of_callable_fun
78 : result_of_callable_fun_2<F>
79{};
80
81template<typename F>
82struct result_of_callable_fun<F *>
83 : result_of_callable_fun_2<F>
84{};
85
86template<typename F>
87struct result_of_select_call_wrapper_type
88 : conditional<
89 is_class<typename remove_reference<F>::type>::value,
90 result_of_wrap_callable_class<F>,
91 type_identity<result_of_callable_fun<typename remove_cv<typename remove_reference<F>::type>::type> >
92 >::type
93{};
94
95template<typename F, typename... Args>
96struct result_of_is_callable {
97 typedef typename result_of_select_call_wrapper_type<F>::type wrapper_t;
98 static const bool value = (
99 sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type(
100 (boost::declval<wrapper_t>()(boost::declval<Args>()...), result_of_weird_type())
101 ))
102 );
103 typedef integral_constant<bool, value> type;
104};
105
106template<typename F, typename... Args>
107struct cpp0x_result_of_impl<F(Args...), true>
108 : lazy_enable_if<
109 result_of_is_callable<F, Args...>
110 , cpp0x_result_of_impl<F(Args...), false>
111 >
112{};
113
114template<typename F, typename... Args>
115struct cpp0x_result_of_impl<F(Args...), false>
116{
117 typedef decltype(
118 boost::declval<F>()(
119 boost::declval<Args>()...
120 )
121 ) type;
122};
123
124#else // BOOST_NO_SFINAE_EXPR
125
126template<typename F, typename... Args>
127struct cpp0x_result_of_impl<F(Args...),
128 typename result_of_always_void<decltype(
129 boost::declval<F>()(
130 boost::declval<Args>()...
131 )
132 )>::type> {
133 typedef decltype(
134 boost::declval<F>()(
135 boost::declval<Args>()...
136 )
137 ) type;
138};
139
140#endif // BOOST_NO_SFINAE_EXPR
141
142} // namespace detail
143
144#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
145
146template<typename F, typename... Args>
147struct result_of<F(Args...)>
148 : tr1_result_of<F(Args...)> { };
149
150#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
151
152namespace detail {
153
154template<typename R, typename FArgs, typename... Args>
155struct tr1_result_of_impl<R (*)(Args...), FArgs, false>
156{
157 typedef R type;
158};
159
160template<typename R, typename FArgs, typename... Args>
161struct tr1_result_of_impl<R (&)(Args...), FArgs, false>
162{
163 typedef R type;
164};
165
166template<typename R, typename FArgs, typename C, typename... Args>
167struct tr1_result_of_impl<R (C::*)(Args...), FArgs, false>
168{
169 typedef R type;
170};
171
172template<typename R, typename FArgs, typename C, typename... Args>
173struct tr1_result_of_impl<R (C::*)(Args...) const, FArgs, false>
174{
175 typedef R type;
176};
177
178template<typename R, typename FArgs, typename C, typename... Args>
179struct tr1_result_of_impl<R (C::*)(Args...) volatile, FArgs, false>
180{
181 typedef R type;
182};
183
184template<typename R, typename FArgs, typename C, typename... Args>
185struct tr1_result_of_impl<R (C::*)(Args...) const volatile, FArgs, false>
186{
187 typedef R type;
188};
189
190}
191