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/test/minimal.hpp> // see "Header Implementation Option"
17 #include "boost/lambda/bind.hpp"
18 #include "boost/lambda/lambda.hpp"
19 #include "boost/lambda/detail/suppress_unused.hpp"
27 using boost::lambda::detail::suppress_unused_variable_warnings
;
32 using namespace boost::lambda
;
35 B
operator--(const A
&, int) { return B(); }
36 B
operator--(A
&) { return B(); }
37 B
operator++(const A
&, int) { return B(); }
38 B
operator++(A
&) { return B(); }
39 B
operator-(const A
&) { return B(); }
40 B
operator+(const A
&) { return B(); }
42 B
operator!(const A
&) { return B(); }
44 B
operator&(const A
&) { return B(); }
45 B
operator*(const A
&) { return B(); }
52 struct plain_return_type_1
<unary_arithmetic_action
<Act
>, A
> {
58 struct plain_return_type_1
<post_increment_decrement_action
<Act
>, A
> {
64 struct plain_return_type_1
<pre_increment_decrement_action
<Act
>, A
> {
69 struct plain_return_type_1
<logical_action
<not_action
>, A
> {
74 struct plain_return_type_1
<other_action
<addressof_action
>, A
> {
79 struct plain_return_type_1
<other_action
<contentsof_action
>, A
> {
89 void test_unary_operators()
102 BOOST_CHECK((*_1
)(make_const(&i
)) == 1);
109 Z
operator+(const X
&, const Y
&) { return Z(); }
110 Z
operator-(const X
&, const Y
&) { return Z(); }
111 X
operator*(const X
&, const Y
&) { return X(); }
113 Z
operator/(const X
&, const Y
&) { return Z(); }
114 Z
operator%(const X
&, const Y
&) { return Z(); }
121 // it is possible to support differently cv-qualified versions
122 YY
operator*(XX
&, YY
&) { return YY(); }
123 ZZ
operator*(const XX
&, const YY
&) { return ZZ(); }
124 XX
operator*(volatile XX
&, volatile YY
&) { return XX(); }
125 VV
operator*(const volatile XX
&, const volatile YY
&) { return VV(); }
127 // the traits can be more complex:
131 template<class A
, class B
>
132 my_vector
<typename return_type_2
<arithmetic_action
<plus_action
>, A
&, B
&>::type
>
133 operator+(const my_vector
<A
>& /*a*/, const my_vector
<B
>& /*b*/)
136 return_type_2
<arithmetic_action
<plus_action
>, A
&, B
&>::type res_type
;
137 return my_vector
<res_type
>();
143 X
operator<<(const X
&, const Y
&) { return X(); }
144 Z
operator>>(const X
&, const Y
&) { return Z(); }
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(); }
151 X
operator<(const X
&, const Y
&) { return X(); }
152 Z
operator>(const X
&, const Y
&) { return Z(); }
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(); }
160 X
operator&&(const X
&, const Y
&) { return X(); }
161 Z
operator||(const X
&, const Y
&) { return Z(); }
165 Z
operator+=( X
&, const Y
&) { return Z(); }
166 Z
operator-=( X
&, const Y
&) { return Z(); }
167 Y
operator*=( X
&, const Y
&) { return Y(); }
168 Z
operator/=( X
&, const Y
&) { return Z(); }
169 Z
operator%=( X
&, const Y
&) { return Z(); }
171 // bitwise assignment
172 Z
operator<<=( X
&, const Y
&) { return Z(); }
173 Z
operator>>=( X
&, const Y
&) { return Z(); }
174 Y
operator&=( X
&, const Y
&) { return Y(); }
175 Z
operator|=( X
&, const Y
&) { return Z(); }
176 Z
operator^=( X
&, const Y
&) { return Z(); }
181 void operator=(const Assign
& /*a*/) {}
182 X
operator[](const int& /*i*/) { return X(); }
190 // you can do action groups
192 struct plain_return_type_2
<arithmetic_action
<Act
>, X
, Y
> {
196 // or specialize the exact action
198 struct plain_return_type_2
<arithmetic_action
<multiply_action
>, X
, Y
> {
202 // if you want to make a distinction between differently cv-qualified
203 // types, you need to specialize on a different level:
205 struct return_type_2
<arithmetic_action
<multiply_action
>, XX
, YY
> {
209 struct return_type_2
<arithmetic_action
<multiply_action
>, const XX
, const YY
> {
213 struct return_type_2
<arithmetic_action
<multiply_action
>, volatile XX
, volatile YY
> {
217 struct return_type_2
<arithmetic_action
<multiply_action
>, volatile const XX
, const volatile YY
> {
221 // the mapping can be more complex:
222 template<class A
, class B
>
223 struct plain_return_type_2
<arithmetic_action
<plus_action
>, my_vector
<A
>, my_vector
<B
> > {
225 return_type_2
<arithmetic_action
<plus_action
>, A
&, B
&>::type res_type
;
226 typedef my_vector
<res_type
> type
;
230 // you can do action groups
232 struct plain_return_type_2
<bitwise_action
<Act
>, X
, Y
> {
236 // or specialize the exact action
238 struct plain_return_type_2
<bitwise_action
<leftshift_action
>, X
, Y
> {
242 // comparison binary:
243 // you can do action groups
245 struct plain_return_type_2
<relational_action
<Act
>, X
, Y
> {
249 // or specialize the exact action
251 struct plain_return_type_2
<relational_action
<less_action
>, X
, Y
> {
256 // you can do action groups
258 struct plain_return_type_2
<logical_action
<Act
>, X
, Y
> {
262 // or specialize the exact action
264 struct plain_return_type_2
<logical_action
<and_action
>, X
, Y
> {
268 // arithmetic assignment :
269 // you can do action groups
271 struct plain_return_type_2
<arithmetic_assignment_action
<Act
>, X
, Y
> {
275 // or specialize the exact action
277 struct plain_return_type_2
<arithmetic_assignment_action
<multiply_action
>, X
, Y
> {
281 // arithmetic assignment :
282 // you can do action groups
284 struct plain_return_type_2
<bitwise_assignment_action
<Act
>, X
, Y
> {
288 // or specialize the exact action
290 struct plain_return_type_2
<bitwise_assignment_action
<and_action
>, X
, Y
> {
296 struct plain_return_type_2
<other_action
<assignment_action
>, Assign
, Assign
> {
301 struct plain_return_type_2
<other_action
<subscript_action
>, Assign
, int> {
311 void test_binary_operators() {
321 // make a distinction between differently cv-qualified operators
325 volatile XX
& vxx
= xx
;
326 volatile YY
& vyy
= yy
;
327 const volatile XX
& cvxx
= xx
;
328 const volatile YY
& cvyy
= yy
;
330 ZZ dummy1
= (_1
* _2
)(cxx
, cyy
);
331 YY dummy2
= (_1
* _2
)(xx
, yy
);
332 XX dummy3
= (_1
* _2
)(vxx
, vyy
);
333 VV dummy4
= (_1
* _2
)(cvxx
, cvyy
);
335 suppress_unused_variable_warnings(dummy1
);
336 suppress_unused_variable_warnings(dummy2
);
337 suppress_unused_variable_warnings(dummy3
);
338 suppress_unused_variable_warnings(dummy4
);
340 my_vector
<int> v1
; my_vector
<double> v2
;
341 my_vector
<double> d
= (_1
+ _2
)(v1
, v2
);
343 suppress_unused_variable_warnings(d
);
367 // arithmetic assignment
374 // bitwise assignment
384 int test_main(int, char *[]) {
385 test_unary_operators();
386 test_binary_operators();