comparison DEPENDENCIES/generic/include/boost/proto/detail/poly_function.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file poly_function.hpp
3 /// A wrapper that makes a tr1-style function object that handles const
4 /// and non-const refs and reference_wrapper arguments, too, and forwards
5 /// the arguments on to the specified implementation.
6 //
7 // Copyright 2008 Eric Niebler. Distributed under the Boost
8 // Software License, Version 1.0. (See accompanying file
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifndef BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
12 #define BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
13
14 #include <boost/ref.hpp>
15 #include <boost/mpl/bool.hpp>
16 #include <boost/mpl/void.hpp>
17 #include <boost/mpl/size_t.hpp>
18 #include <boost/mpl/eval_if.hpp>
19 #include <boost/preprocessor/cat.hpp>
20 #include <boost/preprocessor/facilities/intercept.hpp>
21 #include <boost/preprocessor/iteration/iterate.hpp>
22 #include <boost/preprocessor/repetition/enum.hpp>
23 #include <boost/preprocessor/repetition/enum_params.hpp>
24 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
25 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
26 #include <boost/proto/proto_fwd.hpp>
27 #include <boost/proto/detail/is_noncopyable.hpp>
28
29 #ifdef _MSC_VER
30 # pragma warning(push)
31 # pragma warning(disable: 4181) // const applied to reference type
32 #endif
33
34 namespace boost { namespace proto { namespace detail
35 {
36
37 ////////////////////////////////////////////////////////////////////////////////////////////////
38 template<typename T>
39 struct normalize_arg
40 {
41 typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type type;
42 typedef T &reference;
43 };
44
45 template<typename T>
46 struct normalize_arg<T const>
47 {
48 typedef typename mpl::if_c<is_noncopyable<T>::value, T const &, T>::type type;
49 typedef T const &reference;
50 };
51
52 template<typename T>
53 struct normalize_arg<T &>
54 {
55 typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type type;
56 typedef T &reference;
57 };
58
59 template<typename T>
60 struct normalize_arg<T const &>
61 {
62 typedef typename mpl::if_c<is_noncopyable<T>::value, T const &, T>::type type;
63 typedef T const &reference;
64 };
65
66 template<typename T>
67 struct normalize_arg<boost::reference_wrapper<T> >
68 {
69 typedef T &type;
70 typedef T &reference;
71 };
72
73 template<typename T>
74 struct normalize_arg<boost::reference_wrapper<T> const>
75 {
76 typedef T &type;
77 typedef T &reference;
78 };
79
80 template<typename T>
81 struct normalize_arg<boost::reference_wrapper<T> &>
82 {
83 typedef T &type;
84 typedef T &reference;
85 };
86
87 template<typename T>
88 struct normalize_arg<boost::reference_wrapper<T> const &>
89 {
90 typedef T &type;
91 typedef T &reference;
92 };
93
94 ////////////////////////////////////////////////////////////////////////////////////////////////
95 template<typename T>
96 struct arg
97 {
98 typedef T const &type;
99
100 arg(type t)
101 : value(t)
102 {}
103
104 operator type() const
105 {
106 return this->value;
107 }
108
109 type operator()() const
110 {
111 return this->value;
112 }
113
114 private:
115 arg &operator =(arg const &);
116 type value;
117 };
118
119 template<typename T>
120 struct arg<T &>
121 {
122 typedef T &type;
123
124 arg(type t)
125 : value(t)
126 {}
127
128 operator type() const
129 {
130 return this->value;
131 }
132
133 type operator()() const
134 {
135 return this->value;
136 }
137
138 private:
139 arg &operator =(arg const &);
140 type value;
141 };
142
143 ////////////////////////////////////////////////////////////////////////////////////////////////
144 template<typename T, typename Void = void>
145 struct is_poly_function
146 : mpl::false_
147 {};
148
149 template<typename T>
150 struct is_poly_function<T, typename T::is_poly_function_base_>
151 : mpl::true_
152 {};
153
154 ////////////////////////////////////////////////////////////////////////////////////////////////
155 #define BOOST_PROTO_POLY_FUNCTION() \
156 typedef void is_poly_function_base_; \
157 /**/
158
159 ////////////////////////////////////////////////////////////////////////////////////////////////
160 struct poly_function_base
161 {
162 /// INTERNAL ONLY
163 BOOST_PROTO_POLY_FUNCTION()
164 };
165
166 ////////////////////////////////////////////////////////////////////////////////////////////////
167 template<typename Derived, typename NullaryResult = void>
168 struct poly_function
169 : poly_function_base
170 {
171 template<typename Sig>
172 struct result;
173
174 template<typename This>
175 struct result<This()>
176 : Derived::template impl<>
177 {
178 typedef typename result::result_type type;
179 };
180
181 NullaryResult operator()() const
182 {
183 result<Derived const()> impl;
184 return impl();
185 }
186
187 #include <boost/proto/detail/poly_function_funop.hpp>
188 };
189
190 template<typename T>
191 struct wrap_t;
192
193 typedef char poly_function_t;
194 typedef char (&mono_function_t)[2];
195 typedef char (&unknown_function_t)[3];
196
197 template<typename T> poly_function_t test_poly_function(T *, wrap_t<typename T::is_poly_function_base_> * = 0);
198 template<typename T> mono_function_t test_poly_function(T *, wrap_t<typename T::result_type> * = 0);
199 template<typename T> unknown_function_t test_poly_function(T *, ...);
200
201 ////////////////////////////////////////////////////////////////////////////////////////////////
202 template<typename Fun, typename Sig, typename Switch = mpl::size_t<sizeof(test_poly_function<Fun>(0,0))> >
203 struct poly_function_traits
204 {
205 typedef typename Fun::template result<Sig>::type result_type;
206 typedef Fun function_type;
207 };
208
209 ////////////////////////////////////////////////////////////////////////////////////////////////
210 template<typename Fun, typename Sig>
211 struct poly_function_traits<Fun, Sig, mpl::size_t<sizeof(mono_function_t)> >
212 {
213 typedef typename Fun::result_type result_type;
214 typedef Fun function_type;
215 };
216
217 ////////////////////////////////////////////////////////////////////////////////////////////////
218 template<typename PolyFunSig, bool IsPolyFunction>
219 struct as_mono_function_impl;
220
221 ////////////////////////////////////////////////////////////////////////////////////////////////
222 template<typename PolyFunSig>
223 struct as_mono_function;
224
225 #include <boost/proto/detail/poly_function_traits.hpp>
226
227 }}} // namespace boost::proto::detail
228
229 #ifdef _MSC_VER
230 # pragma warning(pop)
231 #endif
232
233 #endif
234