1 // extending_return_type_traits.cpp -- The Boost Lambda Library --------
3 // Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
4 // Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
10 // For more information, see www.boost.org
12 // -----------------------------------------------------------------------
15 #include <boost/core/lightweight_test.hpp>
16 #define BOOST_CHECK BOOST_TEST
18 #include "boost/lambda/bind.hpp"
19 #include "boost/lambda/lambda.hpp"
20 #include "boost/lambda/detail/suppress_unused.hpp"
28 using boost::lambda::detail::suppress_unused_variable_warnings
;
33 using namespace boost::lambda
;
36 B
operator--(const A
&, int) { return B(); }
37 B
operator--(A
&) { return B(); }
38 B
operator++(const A
&, int) { return B(); }
39 B
operator++(A
&) { return B(); }
40 B
operator-(const A
&) { return B(); }
41 B
operator+(const A
&) { return B(); }
43 B
operator!(const A
&) { return B(); }
45 B
operator&(const A
&) { return B(); }
46 B
operator*(const A
&) { return B(); }
53 struct plain_return_type_1
<unary_arithmetic_action
<Act
>, A
> {
59 struct plain_return_type_1
<post_increment_decrement_action
<Act
>, A
> {
65 struct plain_return_type_1
<pre_increment_decrement_action
<Act
>, A
> {
70 struct plain_return_type_1
<logical_action
<not_action
>, A
> {
75 struct plain_return_type_1
<other_action
<addressof_action
>, A
> {
80 struct plain_return_type_1
<other_action
<contentsof_action
>, A
> {
90 void test_unary_operators()
103 BOOST_CHECK((*_1
)(make_const(&i
)) == 1);
110 Z
operator+(const X
&, const Y
&) { return Z(); }
111 Z
operator-(const X
&, const Y
&) { return Z(); }
112 X
operator*(const X
&, const Y
&) { return X(); }
114 Z
operator/(const X
&, const Y
&) { return Z(); }
115 Z
operator%(const X
&, const Y
&) { return Z(); }
122 // it is possible to support differently cv-qualified versions
123 YY
operator*(XX
&, YY
&) { return YY(); }
124 ZZ
operator*(const XX
&, const YY
&) { return ZZ(); }
125 XX
operator*(volatile XX
&, volatile YY
&) { return XX(); }
126 VV
operator*(const volatile XX
&, const volatile YY
&) { return VV(); }
128 // the traits can be more complex:
132 template<class A
, class B
>
133 my_vector
<typename return_type_2
<arithmetic_action
<plus_action
>, A
&, B
&>::type
>
134 operator+(const my_vector
<A
>& /*a*/, const my_vector
<B
>& /*b*/)
137 return_type_2
<arithmetic_action
<plus_action
>, A
&, B
&>::type res_type
;
138 return my_vector
<res_type
>();
144 X
operator<<(const X
&, const Y
&) { return X(); }
145 Z
operator>>(const X
&, const Y
&) { return Z(); }
146 Z
operator&(const X
&, const Y
&) { return Z(); }
147 Z
operator|(const X
&, const Y
&) { return Z(); }
148 Z
operator^(const X
&, const Y
&) { return Z(); }
152 X
operator<(const X
&, const Y
&) { return X(); }
153 Z
operator>(const X
&, const Y
&) { return Z(); }
154 Z
operator<=(const X
&, const Y
&) { return Z(); }
155 Z
operator>=(const X
&, const Y
&) { return Z(); }
156 Z
operator==(const X
&, const Y
&) { return Z(); }
157 Z
operator!=(const X
&, const Y
&) { return Z(); }
161 X
operator&&(const X
&, const Y
&) { return X(); }
162 Z
operator||(const X
&, const Y
&) { return Z(); }
166 Z
operator+=( X
&, const Y
&) { return Z(); }
167 Z
operator-=( X
&, const Y
&) { return Z(); }
168 Y
operator*=( X
&, const Y
&) { return Y(); }
169 Z
operator/=( X
&, const Y
&) { return Z(); }
170 Z
operator%=( X
&, const Y
&) { return Z(); }
172 // bitwise assignment
173 Z
operator<<=( X
&, const Y
&) { return Z(); }
174 Z
operator>>=( X
&, const Y
&) { return Z(); }
175 Y
operator&=( X
&, const Y
&) { return Y(); }
176 Z
operator|=( X
&, const Y
&) { return Z(); }
177 Z
operator^=( X
&, const Y
&) { return Z(); }
182 void operator=(const Assign
& /*a*/) {}
183 X
operator[](const int& /*i*/) { return X(); }
191 // you can do action groups
193 struct plain_return_type_2
<arithmetic_action
<Act
>, X
, Y
> {
197 // or specialize the exact action
199 struct plain_return_type_2
<arithmetic_action
<multiply_action
>, X
, Y
> {
203 // if you want to make a distinction between differently cv-qualified
204 // types, you need to specialize on a different level:
206 struct return_type_2
<arithmetic_action
<multiply_action
>, XX
, YY
> {
210 struct return_type_2
<arithmetic_action
<multiply_action
>, const XX
, const YY
> {
214 struct return_type_2
<arithmetic_action
<multiply_action
>, volatile XX
, volatile YY
> {
218 struct return_type_2
<arithmetic_action
<multiply_action
>, volatile const XX
, const volatile YY
> {
222 // the mapping can be more complex:
223 template<class A
, class B
>
224 struct plain_return_type_2
<arithmetic_action
<plus_action
>, my_vector
<A
>, my_vector
<B
> > {
226 return_type_2
<arithmetic_action
<plus_action
>, A
&, B
&>::type res_type
;
227 typedef my_vector
<res_type
> type
;
231 // you can do action groups
233 struct plain_return_type_2
<bitwise_action
<Act
>, X
, Y
> {
237 // or specialize the exact action
239 struct plain_return_type_2
<bitwise_action
<leftshift_action
>, X
, Y
> {
243 // comparison binary:
244 // you can do action groups
246 struct plain_return_type_2
<relational_action
<Act
>, X
, Y
> {
250 // or specialize the exact action
252 struct plain_return_type_2
<relational_action
<less_action
>, X
, Y
> {
257 // you can do action groups
259 struct plain_return_type_2
<logical_action
<Act
>, X
, Y
> {
263 // or specialize the exact action
265 struct plain_return_type_2
<logical_action
<and_action
>, X
, Y
> {
269 // arithmetic assignment :
270 // you can do action groups
272 struct plain_return_type_2
<arithmetic_assignment_action
<Act
>, X
, Y
> {
276 // or specialize the exact action
278 struct plain_return_type_2
<arithmetic_assignment_action
<multiply_action
>, X
, Y
> {
282 // arithmetic assignment :
283 // you can do action groups
285 struct plain_return_type_2
<bitwise_assignment_action
<Act
>, X
, Y
> {
289 // or specialize the exact action
291 struct plain_return_type_2
<bitwise_assignment_action
<and_action
>, X
, Y
> {
297 struct plain_return_type_2
<other_action
<assignment_action
>, Assign
, Assign
> {
302 struct plain_return_type_2
<other_action
<subscript_action
>, Assign
, int> {
312 void test_binary_operators() {
322 // make a distinction between differently cv-qualified operators
326 volatile XX
& vxx
= xx
;
327 volatile YY
& vyy
= yy
;
328 const volatile XX
& cvxx
= xx
;
329 const volatile YY
& cvyy
= yy
;
331 ZZ dummy1
= (_1
* _2
)(cxx
, cyy
);
332 YY dummy2
= (_1
* _2
)(xx
, yy
);
333 XX dummy3
= (_1
* _2
)(vxx
, vyy
);
334 VV dummy4
= (_1
* _2
)(cvxx
, cvyy
);
336 suppress_unused_variable_warnings(dummy1
);
337 suppress_unused_variable_warnings(dummy2
);
338 suppress_unused_variable_warnings(dummy3
);
339 suppress_unused_variable_warnings(dummy4
);
341 my_vector
<int> v1
; my_vector
<double> v2
;
342 my_vector
<double> d
= (_1
+ _2
)(v1
, v2
);
344 suppress_unused_variable_warnings(d
);
368 // arithmetic assignment
375 // bitwise assignment
386 test_unary_operators();
387 test_binary_operators();
388 return boost::report_errors();