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(BOOST_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 | : conditional< |
29 | is_pointer<F>::value || is_member_function_pointer<F>::value |
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::result_of_has_result_type<F>::value)> |
34 | , boost::detail::tr1_result_of_impl< |
35 | F, |
36 | F(BOOST_RESULT_OF_ARGS), |
37 | (boost::detail::result_of_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 | : conditional<detail::result_of_has_result_type<F>::value || detail::result_of_has_result<F>::value, |
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 | : conditional< |
61 | is_member_function_pointer<F>::value |
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 | : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> |
87 | {}; |
88 | |
89 | template<typename F> |
90 | struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *> |
91 | : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> |
92 | {}; |
93 | |
94 | template<typename F> |
95 | struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION()) |
96 | : conditional< |
97 | is_class<typename remove_reference<F>::type>::value, |
98 | result_of_wrap_callable_class<F>, |
99 | type_identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<typename remove_reference<F>::type>::type> > |
100 | >::type |
101 | {}; |
102 | |
103 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)> |
104 | struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) { |
105 | typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())<F>::type wrapper_t; |
106 | static const bool value = ( |
107 | sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type( |
108 | (boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type()) |
109 | )) |
110 | ); |
111 | typedef integral_constant<bool, value> type; |
112 | }; |
113 | |
114 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
115 | struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true> |
116 | : lazy_enable_if< |
117 | BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION())<F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), T)> |
118 | , cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false> |
119 | > |
120 | {}; |
121 | |
122 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
123 | struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false> |
124 | { |
125 | typedef decltype( |
126 | boost::declval<F>()( |
127 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT) |
128 | ) |
129 | ) type; |
130 | }; |
131 | |
132 | #else // BOOST_NO_SFINAE_EXPR |
133 | |
134 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
135 | struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), |
136 | typename result_of_always_void<decltype( |
137 | boost::declval<F>()( |
138 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT) |
139 | ) |
140 | )>::type> { |
141 | typedef decltype( |
142 | boost::declval<F>()( |
143 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT) |
144 | ) |
145 | ) type; |
146 | }; |
147 | |
148 | #endif // BOOST_NO_SFINAE_EXPR |
149 | |
150 | } // namespace detail |
151 | |
152 | #else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) |
153 | |
154 | #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) |
155 | template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
156 | struct result_of<F(BOOST_RESULT_OF_ARGS)> |
157 | : tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { }; |
158 | #endif |
159 | |
160 | #endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) |
161 | |
162 | #undef BOOST_RESULT_OF_ARGS |
163 | |
164 | #if BOOST_PP_ITERATION() >= 1 |
165 | |
166 | namespace detail { |
167 | |
168 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
169 | struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> |
170 | { |
171 | typedef R type; |
172 | }; |
173 | |
174 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
175 | struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> |
176 | { |
177 | typedef R type; |
178 | }; |
179 | |
180 | #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) |
181 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
182 | struct tr1_result_of_impl<R (T0::*) |
183 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), |
184 | FArgs, false> |
185 | { |
186 | typedef R type; |
187 | }; |
188 | |
189 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
190 | struct tr1_result_of_impl<R (T0::*) |
191 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) |
192 | const, |
193 | FArgs, false> |
194 | { |
195 | typedef R type; |
196 | }; |
197 | |
198 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
199 | struct tr1_result_of_impl<R (T0::*) |
200 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) |
201 | volatile, |
202 | FArgs, false> |
203 | { |
204 | typedef R type; |
205 | }; |
206 | |
207 | template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> |
208 | struct tr1_result_of_impl<R (T0::*) |
209 | (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) |
210 | const volatile, |
211 | FArgs, false> |
212 | { |
213 | typedef R type; |
214 | }; |
215 | #endif |
216 | |
217 | } |
218 | #endif |
219 | |