]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | // For more information, see http://www.boost.org/libs/utility | |
9 | #ifndef BOOST_RESULT_OF_HPP | |
10 | #define BOOST_RESULT_OF_HPP | |
11 | ||
12 | #include <boost/config.hpp> | |
13 | #include <boost/preprocessor/cat.hpp> | |
14 | #include <boost/preprocessor/iteration/iterate.hpp> | |
15 | #include <boost/preprocessor/repetition/enum_params.hpp> | |
16 | #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
17 | #include <boost/preprocessor/repetition/enum_binary_params.hpp> | |
18 | #include <boost/preprocessor/repetition/enum_shifted_params.hpp> | |
19 | #include <boost/preprocessor/facilities/intercept.hpp> | |
20 | #include <boost/detail/workaround.hpp> | |
21 | #include <boost/mpl/has_xxx.hpp> | |
22 | #include <boost/mpl/if.hpp> | |
23 | #include <boost/mpl/eval_if.hpp> | |
24 | #include <boost/mpl/bool.hpp> | |
25 | #include <boost/mpl/identity.hpp> | |
26 | #include <boost/mpl/or.hpp> | |
27 | #include <boost/type_traits/is_class.hpp> | |
28 | #include <boost/type_traits/is_pointer.hpp> | |
29 | #include <boost/type_traits/is_member_function_pointer.hpp> | |
30 | #include <boost/type_traits/remove_cv.hpp> | |
31 | #include <boost/type_traits/remove_reference.hpp> | |
32 | #include <boost/utility/declval.hpp> | |
33 | #include <boost/utility/enable_if.hpp> | |
34 | ||
35 | #ifndef BOOST_RESULT_OF_NUM_ARGS | |
36 | # define BOOST_RESULT_OF_NUM_ARGS 16 | |
37 | #endif | |
38 | ||
39 | // Use the decltype-based version of result_of by default if the compiler | |
40 | // supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>. | |
41 | // The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE, | |
42 | // BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one! | |
43 | #if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \ | |
44 | (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \ | |
45 | (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) | |
46 | # error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \ | |
47 | BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time. | |
48 | #endif | |
49 | ||
50 | #if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) | |
51 | # error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined. | |
52 | #endif | |
53 | ||
54 | #ifndef BOOST_RESULT_OF_USE_TR1 | |
55 | # ifndef BOOST_RESULT_OF_USE_DECLTYPE | |
56 | # ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | |
57 | # ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) | |
58 | # define BOOST_RESULT_OF_USE_DECLTYPE | |
59 | # else | |
60 | # define BOOST_RESULT_OF_USE_TR1 | |
61 | # endif | |
62 | # endif | |
63 | # endif | |
64 | #endif | |
65 | ||
66 | namespace boost { | |
67 | ||
68 | template<typename F> struct result_of; | |
69 | template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of | |
70 | ||
71 | #if !defined(BOOST_NO_SFINAE) | |
72 | namespace detail { | |
73 | ||
74 | BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) | |
75 | ||
76 | // Work around a nvcc bug by only defining has_result when it's needed. | |
77 | #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | |
78 | BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result) | |
79 | #endif | |
80 | ||
81 | template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl; | |
82 | ||
83 | template<typename F> struct cpp0x_result_of; | |
84 | ||
85 | #ifdef BOOST_NO_SFINAE_EXPR | |
86 | ||
87 | // There doesn't seem to be any other way to turn this off such that the presence of | |
88 | // the user-defined operator,() below doesn't cause spurious warning all over the place, | |
89 | // so unconditionally turn it off. | |
90 | #if BOOST_MSVC | |
91 | # pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used | |
92 | #endif | |
93 | ||
94 | struct result_of_private_type {}; | |
95 | ||
96 | struct result_of_weird_type { | |
97 | friend result_of_private_type operator,(result_of_private_type, result_of_weird_type); | |
98 | }; | |
99 | ||
100 | typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1 | |
101 | typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2 | |
102 | ||
103 | template<typename T> | |
104 | result_of_no_type result_of_is_private_type(T const &); | |
105 | result_of_yes_type result_of_is_private_type(result_of_private_type); | |
106 | ||
107 | template<typename C> | |
108 | struct result_of_callable_class : C { | |
109 | result_of_callable_class(); | |
110 | typedef result_of_private_type const &(*pfn_t)(...); | |
111 | operator pfn_t() const volatile; | |
112 | }; | |
113 | ||
114 | template<typename C> | |
115 | struct result_of_wrap_callable_class { | |
116 | typedef result_of_callable_class<C> type; | |
117 | }; | |
118 | ||
119 | template<typename C> | |
120 | struct result_of_wrap_callable_class<C const> { | |
121 | typedef result_of_callable_class<C> const type; | |
122 | }; | |
123 | ||
124 | template<typename C> | |
125 | struct result_of_wrap_callable_class<C volatile> { | |
126 | typedef result_of_callable_class<C> volatile type; | |
127 | }; | |
128 | ||
129 | template<typename C> | |
130 | struct result_of_wrap_callable_class<C const volatile> { | |
131 | typedef result_of_callable_class<C> const volatile type; | |
132 | }; | |
133 | ||
134 | template<typename C> | |
135 | struct result_of_wrap_callable_class<C &> { | |
136 | typedef typename result_of_wrap_callable_class<C>::type &type; | |
137 | }; | |
138 | ||
139 | template<typename F, bool TestCallability = true> struct cpp0x_result_of_impl; | |
140 | ||
141 | #else // BOOST_NO_SFINAE_EXPR | |
142 | ||
143 | template<typename T> | |
144 | struct result_of_always_void | |
145 | { | |
146 | typedef void type; | |
147 | }; | |
148 | ||
149 | template<typename F, typename Enable = void> struct cpp0x_result_of_impl {}; | |
150 | ||
151 | #endif // BOOST_NO_SFINAE_EXPR | |
152 | ||
153 | template<typename F> | |
154 | struct result_of_void_impl | |
155 | { | |
156 | typedef void type; | |
157 | }; | |
158 | ||
159 | template<typename R> | |
160 | struct result_of_void_impl<R (*)(void)> | |
161 | { | |
162 | typedef R type; | |
163 | }; | |
164 | ||
165 | template<typename R> | |
166 | struct result_of_void_impl<R (&)(void)> | |
167 | { | |
168 | typedef R type; | |
169 | }; | |
170 | ||
171 | // Determine the return type of a function pointer or pointer to member. | |
172 | template<typename F, typename FArgs> | |
173 | struct result_of_pointer | |
174 | : tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { }; | |
175 | ||
176 | template<typename F, typename FArgs> | |
177 | struct tr1_result_of_impl<F, FArgs, true> | |
178 | { | |
179 | typedef typename F::result_type type; | |
180 | }; | |
181 | ||
182 | template<typename FArgs> | |
183 | struct is_function_with_no_args : mpl::false_ {}; | |
184 | ||
185 | template<typename F> | |
186 | struct is_function_with_no_args<F(void)> : mpl::true_ {}; | |
187 | ||
188 | template<typename F, typename FArgs> | |
189 | struct result_of_nested_result : F::template result<FArgs> | |
190 | {}; | |
191 | ||
192 | template<typename F, typename FArgs> | |
193 | struct tr1_result_of_impl<F, FArgs, false> | |
194 | : mpl::if_<is_function_with_no_args<FArgs>, | |
195 | result_of_void_impl<F>, | |
196 | result_of_nested_result<F, FArgs> >::type | |
197 | {}; | |
198 | ||
199 | } // end namespace detail | |
200 | ||
201 | #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>)) | |
202 | #include BOOST_PP_ITERATE() | |
203 | ||
204 | #else | |
205 | # define BOOST_NO_RESULT_OF 1 | |
206 | #endif | |
207 | ||
208 | } | |
209 | ||
210 | #endif // BOOST_RESULT_OF_HPP |