Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/lambda/test/extending_rt_traits.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 18 years ago

added boost

File size: 8.5 KB
Line 
1//  extending_return_type_traits.cpp  -- The Boost Lambda Library --------
2//
3// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
4// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
5//
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)
9//
10// For more information, see www.boost.org
11
12// -----------------------------------------------------------------------
13
14
15#include <boost/test/minimal.hpp>    // see "Header Implementation Option"
16
17#include "boost/lambda/bind.hpp"
18#include "boost/lambda/lambda.hpp"
19
20#include <iostream>
21
22#include <functional>
23
24#include <algorithm>
25
26class A {};
27class B {};
28
29using namespace boost::lambda; 
30
31
32B operator--(const A&, int) { return B(); }
33B operator--(A&) { return B(); }
34B operator++(const A&, int) { return B(); }
35B operator++(A&) { return B(); }
36B operator-(const A&) { return B(); }
37B operator+(const A&) { return B(); }
38
39B operator!(const A&) { return B(); }
40
41B operator&(const A&) { return B(); }
42B operator*(const A&) { return B(); }
43
44namespace boost {
45namespace lambda {
46
47  // unary + and -
48template<class Act>
49struct plain_return_type_1<unary_arithmetic_action<Act>, A > {
50  typedef B type;
51};
52
53  // post incr/decr
54template<class Act>
55struct plain_return_type_1<post_increment_decrement_action<Act>, A > {
56  typedef B type;
57};
58
59  // pre incr/decr
60template<class Act>
61struct plain_return_type_1<pre_increment_decrement_action<Act>, A > {
62  typedef B type;
63};
64  // !
65template<> 
66struct plain_return_type_1<logical_action<not_action>, A> {
67  typedef B type;
68};
69  // &
70template<> 
71struct plain_return_type_1<other_action<addressof_action>, A> {
72  typedef B type;
73};
74  // *
75template<> 
76struct plain_return_type_1<other_action<contentsof_action>, A> {
77  typedef B type;
78};
79
80
81} // lambda
82} // boost
83
84void ok(B b) {}
85
86void test_unary_operators() 
87{
88  A a; int i = 1;
89  ok((++_1)(a));
90  ok((--_1)(a));
91  ok((_1++)(a));
92  ok((_1--)(a));
93  ok((+_1)(a));
94  ok((-_1)(a));
95  ok((!_1)(a));
96  ok((&_1)(a));
97  ok((*_1)(a));
98
99  BOOST_CHECK((*_1)(make_const(&i)) == 1);
100}
101
102class X {};
103class Y {};
104class Z {};
105
106Z operator+(const X&, const Y&) { return Z(); }
107Z operator-(const X&, const Y&) { return Z(); }
108X operator*(const X&, const Y&) { return X(); }
109
110Z operator/(const X&, const Y&) { return Z(); }
111Z operator%(const X&, const Y&) { return Z(); }
112
113class XX {};
114class YY {};
115class ZZ {};
116class VV {};
117
118// it is possible to support differently cv-qualified versions
119YY operator*(XX&, YY&) { return YY(); }
120ZZ operator*(const XX&, const YY&) { return ZZ(); }
121XX operator*(volatile XX&, volatile YY&) { return XX(); }
122VV operator*(const volatile XX&, const volatile YY&) { return VV(); }
123
124// the traits can be more complex:
125template <class T>
126class my_vector {};
127
128template<class A, class B> 
129my_vector<typename return_type_2<arithmetic_action<plus_action>, A&, B&>::type>
130operator+(const my_vector<A>& a, const my_vector<B>& b)
131{
132  typedef typename 
133    return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
134  return my_vector<res_type>();
135}
136
137
138
139// bitwise ops:
140X operator<<(const X&, const Y&) { return X(); }
141Z operator>>(const X&, const Y&) { return Z(); }
142Z operator&(const X&, const Y&) { return Z(); }
143Z operator|(const X&, const Y&) { return Z(); }
144Z operator^(const X&, const Y&) { return Z(); }
145
146// comparison ops:
147
148X operator<(const X&, const Y&) { return X(); }
149Z operator>(const X&, const Y&) { return Z(); }
150Z operator<=(const X&, const Y&) { return Z(); }
151Z operator>=(const X&, const Y&) { return Z(); }
152Z operator==(const X&, const Y&) { return Z(); }
153Z operator!=(const X&, const Y&) { return Z(); }
154
155// logical
156
157X operator&&(const X&, const Y&) { return X(); }
158Z operator||(const X&, const Y&) { return Z(); }
159
160// arithh assignment
161
162Z operator+=( X&, const Y&) { return Z(); }
163Z operator-=( X&, const Y&) { return Z(); }
164Y operator*=( X&, const Y&) { return Y(); }
165Z operator/=( X&, const Y&) { return Z(); }
166Z operator%=( X&, const Y&) { return Z(); }
167
168// bitwise assignment
169Z operator<<=( X&, const Y&) { return Z(); }
170Z operator>>=( X&, const Y&) { return Z(); }
171Y operator&=( X&, const Y&) { return Y(); }
172Z operator|=( X&, const Y&) { return Z(); }
173Z operator^=( X&, const Y&) { return Z(); }
174
175// assignment
176class Assign {
177public:
178  void operator=(const Assign& a) {}
179  X operator[](const int& i) { return X(); }
180};
181
182
183
184namespace boost {
185namespace lambda {
186 
187  // you can do action groups
188template<class Act> 
189struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
190  typedef Z type;
191};
192
193  // or specialize the exact action
194template<> 
195struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
196  typedef X type;
197};
198
199  // if you want to make a distinction between differently cv-qualified
200  // types, you need to specialize on a different level:
201template<> 
202struct return_type_2<arithmetic_action<multiply_action>, XX, YY> {
203  typedef YY type;
204};
205template<> 
206struct return_type_2<arithmetic_action<multiply_action>, const XX, const YY> {
207  typedef ZZ type;
208};
209template<> 
210struct return_type_2<arithmetic_action<multiply_action>, volatile XX, volatile YY> {
211  typedef XX type;
212};
213template<> 
214struct return_type_2<arithmetic_action<multiply_action>, volatile const XX, const volatile YY> {
215  typedef VV type;
216};
217
218  // the mapping can be more complex:
219template<class A, class B> 
220struct plain_return_type_2<arithmetic_action<plus_action>, my_vector<A>, my_vector<B> > {
221  typedef typename 
222    return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
223  typedef my_vector<res_type> type;
224};
225
226  // bitwise binary:
227  // you can do action groups
228template<class Act> 
229struct plain_return_type_2<bitwise_action<Act>, X, Y> {
230  typedef Z type;
231};
232
233  // or specialize the exact action
234template<> 
235struct plain_return_type_2<bitwise_action<leftshift_action>, X, Y> {
236  typedef X type;
237};
238
239  // comparison binary:
240  // you can do action groups
241template<class Act> 
242struct plain_return_type_2<relational_action<Act>, X, Y> {
243  typedef Z type;
244};
245
246  // or specialize the exact action
247template<> 
248struct plain_return_type_2<relational_action<less_action>, X, Y> {
249  typedef X type;
250};
251
252  // logical binary:
253  // you can do action groups
254template<class Act> 
255struct plain_return_type_2<logical_action<Act>, X, Y> {
256  typedef Z type;
257};
258
259  // or specialize the exact action
260template<> 
261struct plain_return_type_2<logical_action<and_action>, X, Y> {
262  typedef X type;
263};
264
265  // arithmetic assignment :
266  // you can do action groups
267template<class Act> 
268struct plain_return_type_2<arithmetic_assignment_action<Act>, X, Y> {
269  typedef Z type;
270};
271
272  // or specialize the exact action
273template<> 
274struct plain_return_type_2<arithmetic_assignment_action<multiply_action>, X, Y> {
275  typedef Y type;
276};
277
278  // arithmetic assignment :
279  // you can do action groups
280template<class Act> 
281struct plain_return_type_2<bitwise_assignment_action<Act>, X, Y> {
282  typedef Z type;
283};
284
285  // or specialize the exact action
286template<> 
287struct plain_return_type_2<bitwise_assignment_action<and_action>, X, Y> {
288  typedef Y type;
289};
290
291  // assignment
292template<> 
293struct plain_return_type_2<other_action<assignment_action>, Assign, Assign> {
294  typedef void type;
295};
296  // subscript
297template<> 
298struct plain_return_type_2<other_action<subscript_action>, Assign, int> {
299  typedef X type;
300};
301
302
303} // end lambda
304} // end boost
305
306
307
308void test_binary_operators() {
309
310  X x; Y y;
311  (_1 + _2)(x, y);
312  (_1 - _2)(x, y);
313  (_1 * _2)(x, y);
314  (_1 / _2)(x, y);
315  (_1 % _2)(x, y);
316
317
318  // make a distinction between differently cv-qualified operators
319  XX xx; YY yy;
320  const XX& cxx = xx;
321  const YY& cyy = yy;
322  volatile XX& vxx = xx;
323  volatile YY& vyy = yy;
324  const volatile XX& cvxx = xx;
325  const volatile YY& cvyy = yy;
326
327  ZZ dummy1 = (_1 * _2)(cxx, cyy);
328  YY dummy2 = (_1 * _2)(xx, yy);
329  XX dummy3 = (_1 * _2)(vxx, vyy);
330  VV dummy4 = (_1 * _2)(cvxx, cvyy);
331
332  my_vector<int> v1; my_vector<double> v2;
333  my_vector<double> d = (_1 + _2)(v1, v2);
334
335  // bitwise
336
337  (_1 << _2)(x, y);
338  (_1 >> _2)(x, y);
339  (_1 | _2)(x, y);
340  (_1 & _2)(x, y);
341  (_1 ^ _2)(x, y);
342
343  // comparison
344 
345  (_1 < _2)(x, y);
346  (_1 > _2)(x, y);
347  (_1 <= _2)(x, y);
348  (_1 >= _2)(x, y);
349  (_1 == _2)(x, y);
350  (_1 != _2)(x, y);
351
352  // logical
353 
354  (_1 || _2)(x, y);
355  (_1 && _2)(x, y);
356
357  // arithmetic assignment
358  (_1 += _2)(x, y);
359  (_1 -= _2)(x, y);
360  (_1 *= _2)(x, y);
361  (_1 /= _2)(x, y);
362  (_1 %= _2)(x, y);
363 
364  // bitwise assignment
365  (_1 <<= _2)(x, y);
366  (_1 >>= _2)(x, y);
367  (_1 |= _2)(x, y);
368  (_1 &= _2)(x, y);
369  (_1 ^= _2)(x, y);
370
371}
372
373
374int test_main(int, char *[]) {
375  test_unary_operators();
376  test_binary_operators();
377  return 0;
378}
379
380
381
382
383
384
Note: See TracBrowser for help on using the repository browser.