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 | #if !defined(BOOST_PP_IS_ITERATING) |
15 | # error Boost result_of - do not include this file! |
16 | #endif |
17 | |
18 | // CWPro8 requires an argument in a function type specialization |
19 | #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0 |
20 | # define BOOST_RESULT_OF_ARGS void |
21 | #else |
22 | # define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T) |
23 | #endif |
24 | |
25 | #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
26 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
27 | struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)> |
28 | : mpl::if_< |
29 | mpl::or_< is_pointer<F>, is_member_function_pointer<F> > |
30 | , boost::detail::tr1_result_of_impl< |
31 | typename remove_cv<F>::type, |
32 | typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS), |
33 | (boost::detail::has_result_type<F>::value)> |
34 | , boost::detail::tr1_result_of_impl< |
35 | F, |
36 | F(BOOST_RESULT_OF_ARGS), |
37 | (boost::detail::has_result_type<F>::value)> >::type { }; |
38 | #endif |
39 | |
40 | #ifdef BOOST_RESULT_OF_USE_DECLTYPE |
41 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
42 | struct result_of<F(BOOST_RESULT_OF_ARGS)> |
43 | : detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> { }; |
44 | #endif // BOOST_RESULT_OF_USE_DECLTYPE |
45 | |
46 | #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK |
47 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
48 | struct result_of<F(BOOST_RESULT_OF_ARGS)> |
49 | : mpl::if_<mpl::or_<detail::has_result_type<F>, detail::has_result<F> >, |
50 | tr1_result_of<F(BOOST_RESULT_OF_ARGS)>, |
51 | detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { }; |
52 | #endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK |
53 | |
54 | #if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) |
55 | |
56 | namespace detail { |
57 | |
58 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
59 | struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> |
60 | : mpl::if_< |
61 | is_member_function_pointer<F> |
62 | , detail::tr1_result_of_impl< |
63 | typename remove_cv<F>::type, |
64 | typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false |
65 | > |
66 | , detail::cpp0x_result_of_impl< |
67 | F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) |
68 | > |
69 | >::type |
70 | {}; |
71 | |
72 | #ifdef BOOST_NO_SFINAE_EXPR |
73 | |
74 | template<typename F> |
75 | struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()); |
76 | |
77 | template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)> |
78 | struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))> { |
79 | R operator()(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const; |
80 | typedef result_of_private_type const &(*pfn_t)(...); |
81 | operator pfn_t() const volatile; |
82 | }; |
83 | |
84 | template<typename F> |
85 | struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()); |
86 | |
87 | template<typename F> |
88 | struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *> |
89 | : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> |
90 | {}; |
91 | |
92 | template<typename F> |
93 | struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F &> |
94 | : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> |
95 | {}; |
96 | |
97 | template<typename F> |
98 | struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION()) |
99 | : mpl::eval_if< |
100 | is_class<typename remove_reference<F>::type>, |
101 | result_of_wrap_callable_class<F>, |
102 | mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> > |
103 | > |
104 | {}; |
105 | |
106 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)> |
107 | struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) { |
108 | typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())<F>::type wrapper_t; |
109 | static const bool value = ( |
110 | sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type( |
111 | (boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type()) |
112 | )) |
113 | ); |
114 | typedef mpl::bool_<value> type; |
115 | }; |
116 | |
117 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
118 | struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true> |
119 | : lazy_enable_if< |
120 | BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION())<F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), T)> |
121 | , cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false> |
122 | > |
123 | {}; |
124 | |
125 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
126 | struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false> |
127 | { |
128 | typedef decltype( |
129 | boost::declval<F>()( |
130 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT) |
131 | ) |
132 | ) type; |
133 | }; |
134 | |
135 | #else // BOOST_NO_SFINAE_EXPR |
136 | |
137 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
138 | struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), |
139 | typename result_of_always_void<decltype( |
140 | boost::declval<F>()( |
141 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT) |
142 | ) |
143 | )>::type> { |
144 | typedef decltype( |
145 | boost::declval<F>()( |
146 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT) |
147 | ) |
148 | ) type; |
149 | }; |
150 | |
151 | #endif // BOOST_NO_SFINAE_EXPR |
152 | |
153 | } // namespace detail |
154 | |
155 | #else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) |
156 | |
157 | #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
158 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
159 | struct result_of<F(BOOST_RESULT_OF_ARGS)> |
160 | : tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { }; |
161 | #endif |
162 | |
163 | #endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) |
164 | |
165 | #undef BOOST_RESULT_OF_ARGS |
166 | |
167 | #if BOOST_PP_ITERATION() >= 1 |
168 | |
169 | namespace detail { |
170 | |
171 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
172 | struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> |
173 | { |
174 | typedef R type; |
175 | }; |
176 | |
177 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
178 | struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> |
179 | { |
180 | typedef R type; |
181 | }; |
182 | |
183 | #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
184 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
185 | struct tr1_result_of_impl<R (T0::*) |
186 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), |
187 | FArgs, false> |
188 | { |
189 | typedef R type; |
190 | }; |
191 | |
192 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
193 | struct tr1_result_of_impl<R (T0::*) |
194 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) |
195 | const, |
196 | FArgs, false> |
197 | { |
198 | typedef R type; |
199 | }; |
200 | |
201 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
202 | struct tr1_result_of_impl<R (T0::*) |
203 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) |
204 | volatile, |
205 | FArgs, false> |
206 | { |
207 | typedef R type; |
208 | }; |
209 | |
210 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
211 | struct tr1_result_of_impl<R (T0::*) |
212 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) |
213 | const volatile, |
214 | FArgs, false> |
215 | { |
216 | typedef R type; |
217 | }; |
218 | #endif |
219 | |
220 | } |
221 | #endif |
222 | |