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/detail/workaround.hpp>
14#include <boost/type_traits/is_class.hpp>
15#include <boost/type_traits/is_pointer.hpp>
16#include <boost/type_traits/is_member_function_pointer.hpp>
17#include <boost/type_traits/remove_cv.hpp>
18#include <boost/type_traits/remove_reference.hpp>
19#include <boost/type_traits/declval.hpp>
20#include <boost/type_traits/conditional.hpp>
21#include <boost/type_traits/type_identity.hpp>
22#include <boost/type_traits/integral_constant.hpp>
23#include <boost/core/enable_if.hpp>
24
25#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
26# undef BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES
27# define BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES
28#endif
29#ifdef BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES
30# include <boost/preprocessor/cat.hpp>
31# include <boost/preprocessor/iteration/iterate.hpp>
32# include <boost/preprocessor/repetition/enum_params.hpp>
33# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
34# include <boost/preprocessor/repetition/enum_binary_params.hpp>
35# include <boost/preprocessor/repetition/enum_shifted_params.hpp>
36# include <boost/preprocessor/facilities/intercept.hpp>
37#endif
38
39#ifndef BOOST_UTILITY_DOCS
40#ifndef BOOST_RESULT_OF_NUM_ARGS
41# define BOOST_RESULT_OF_NUM_ARGS 16
42#endif
43#endif // BOOST_UTILITY_DOCS
44
45// Use the decltype-based version of result_of by default if the compiler
46// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
47// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
48// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one!
49#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \
50 (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \
51 (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK))
52# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \
53 BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
54#endif
55
56#ifndef BOOST_UTILITY_DOCS
57#ifndef BOOST_RESULT_OF_USE_TR1
58# ifndef BOOST_RESULT_OF_USE_DECLTYPE
59# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
60# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
61# define BOOST_RESULT_OF_USE_DECLTYPE
62# else
63# define BOOST_RESULT_OF_USE_TR1
64# endif
65# endif
66# endif
67#endif
68#endif // BOOST_UTILITY_DOCS
69
70namespace boost {
71
72template<typename F> struct result_of;
73template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of
74
75#if !defined(BOOST_NO_SFINAE)
76namespace detail {
77
78typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1
79typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2
80
81template<class T> struct result_of_has_type {};
82
83template<class T> struct result_of_has_result_type_impl
84{
85 template<class U> static result_of_yes_type f( result_of_has_type<typename U::result_type>* );
86 template<class U> static result_of_no_type f( ... );
87
88 typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type;
89};
90
91template<class T> struct result_of_has_result_type: result_of_has_result_type_impl<T>::type
92{
93};
94
95// Work around a nvcc bug by only defining has_result when it's needed.
96#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
97
98template<template<class> class C> struct result_of_has_template {};
99
100template<class T> struct result_of_has_result_impl
101{
102 template<class U> static result_of_yes_type f( result_of_has_template<U::template result>* );
103 template<class U> static result_of_no_type f( ... );
104
105 typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type;
106};
107
108template<class T> struct result_of_has_result: result_of_has_result_impl<T>::type
109{
110};
111
112#endif
113
114template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
115
116template<typename F> struct cpp0x_result_of;
117
118#ifdef BOOST_NO_SFINAE_EXPR
119
120// There doesn't seem to be any other way to turn this off such that the presence of
121// the user-defined operator,() below doesn't cause spurious warning all over the place,
122// so unconditionally and globally turn it off. (https://svn.boost.org/trac10/ticket/7663)
123#ifdef BOOST_MSVC
124# pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used
125#endif
126
127struct result_of_private_type {};
128
129struct result_of_weird_type {
130 friend result_of_private_type operator,(result_of_private_type, result_of_weird_type);
131};
132
133template<typename T>
134result_of_no_type result_of_is_private_type(T const &);
135result_of_yes_type result_of_is_private_type(result_of_private_type);
136
137#ifdef BOOST_MSVC
138# pragma warning(push)
139# pragma warning(disable: 4512) // assignment operator could not be generated.
140#endif
141template<typename C>
142struct result_of_callable_class : C {
143 result_of_callable_class();
144 typedef result_of_private_type const &(*pfn_t)(...);
145 operator pfn_t() const volatile;
146};
147#ifdef BOOST_MSVC
148# pragma warning(pop)
149#endif
150
151template<typename C>
152struct result_of_wrap_callable_class {
153 typedef result_of_callable_class<C> type;
154};
155
156template<typename C>
157struct result_of_wrap_callable_class<C const> {
158 typedef result_of_callable_class<C> const type;
159};
160
161template<typename C>
162struct result_of_wrap_callable_class<C volatile> {
163 typedef result_of_callable_class<C> volatile type;
164};
165
166template<typename C>
167struct result_of_wrap_callable_class<C const volatile> {
168 typedef result_of_callable_class<C> const volatile type;
169};
170
171template<typename C>
172struct result_of_wrap_callable_class<C &> {
173 typedef typename result_of_wrap_callable_class<C>::type &type;
174};
175
176template<typename F, bool TestCallability = true> struct cpp0x_result_of_impl;
177
178#else // BOOST_NO_SFINAE_EXPR
179
180template<typename T>
181struct result_of_always_void
182{
183 typedef void type;
184};
185
186template<typename F, typename Enable = void> struct cpp0x_result_of_impl {};
187
188#endif // BOOST_NO_SFINAE_EXPR
189
190template<typename F>
191struct result_of_void_impl
192{
193 typedef void type;
194};
195
196template<typename R>
197struct result_of_void_impl<R (*)(void)>
198{
199 typedef R type;
200};
201
202template<typename R>
203struct result_of_void_impl<R (&)(void)>
204{
205 typedef R type;
206};
207
208// Determine the return type of a function pointer or pointer to member.
209template<typename F, typename FArgs>
210struct result_of_pointer
211 : tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
212
213template<typename F, typename FArgs>
214struct tr1_result_of_impl<F, FArgs, true>
215{
216 typedef typename F::result_type type;
217};
218
219template<typename FArgs>
220struct is_function_with_no_args : false_type {};
221
222template<typename F>
223struct is_function_with_no_args<F(void)> : true_type {};
224
225template<typename F, typename FArgs>
226struct result_of_nested_result : F::template result<FArgs>
227{};
228
229template<typename F, typename FArgs>
230struct tr1_result_of_impl<F, FArgs, false>
231 : conditional<is_function_with_no_args<FArgs>::value,
232 result_of_void_impl<F>,
233 result_of_nested_result<F, FArgs> >::type
234{};
235
236} // end namespace detail
237
238#ifndef BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES
239# include <boost/utility/detail/result_of_variadic.hpp>
240#else
241# define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
242# include BOOST_PP_ITERATE()
243#endif
244
245#if 0
246// inform dependency trackers, as they can't see through macro includes
247#include <boost/utility/detail/result_of_iterate.hpp>
248#endif
249
250#else
251# define BOOST_NO_RESULT_OF 1
252#endif
253
254}
255
256#endif // BOOST_RESULT_OF_HPP
257

source code of boost/libs/utility/include/boost/utility/result_of.hpp