]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/lambda/test/extending_rt_traits.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / lambda / test / extending_rt_traits.cpp
1 // extending_return_type_traits.cpp -- The Boost Lambda Library --------
2 //
3 // Copyright (C) 2000-2003 Jaakko Jarvi (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/core/lightweight_test.hpp>
16 #define BOOST_CHECK BOOST_TEST
17
18 #include "boost/lambda/bind.hpp"
19 #include "boost/lambda/lambda.hpp"
20 #include "boost/lambda/detail/suppress_unused.hpp"
21
22 #include <iostream>
23
24 #include <functional>
25
26 #include <algorithm>
27
28 using boost::lambda::detail::suppress_unused_variable_warnings;
29
30 class A {};
31 class B {};
32
33 using namespace boost::lambda;
34
35
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(); }
42
43 B operator!(const A&) { return B(); }
44
45 B operator&(const A&) { return B(); }
46 B operator*(const A&) { return B(); }
47
48 namespace boost {
49 namespace lambda {
50
51 // unary + and -
52 template<class Act>
53 struct plain_return_type_1<unary_arithmetic_action<Act>, A > {
54 typedef B type;
55 };
56
57 // post incr/decr
58 template<class Act>
59 struct plain_return_type_1<post_increment_decrement_action<Act>, A > {
60 typedef B type;
61 };
62
63 // pre incr/decr
64 template<class Act>
65 struct plain_return_type_1<pre_increment_decrement_action<Act>, A > {
66 typedef B type;
67 };
68 // !
69 template<>
70 struct plain_return_type_1<logical_action<not_action>, A> {
71 typedef B type;
72 };
73 // &
74 template<>
75 struct plain_return_type_1<other_action<addressof_action>, A> {
76 typedef B type;
77 };
78 // *
79 template<>
80 struct plain_return_type_1<other_action<contentsof_action>, A> {
81 typedef B type;
82 };
83
84
85 } // lambda
86 } // boost
87
88 void ok(B /*b*/) {}
89
90 void test_unary_operators()
91 {
92 A a; int i = 1;
93 ok((++_1)(a));
94 ok((--_1)(a));
95 ok((_1++)(a));
96 ok((_1--)(a));
97 ok((+_1)(a));
98 ok((-_1)(a));
99 ok((!_1)(a));
100 ok((&_1)(a));
101 ok((*_1)(a));
102
103 BOOST_CHECK((*_1)(make_const(&i)) == 1);
104 }
105
106 class X {};
107 class Y {};
108 class Z {};
109
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(); }
113
114 Z operator/(const X&, const Y&) { return Z(); }
115 Z operator%(const X&, const Y&) { return Z(); }
116
117 class XX {};
118 class YY {};
119 class ZZ {};
120 class VV {};
121
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(); }
127
128 // the traits can be more complex:
129 template <class T>
130 class my_vector {};
131
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*/)
135 {
136 typedef typename
137 return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
138 return my_vector<res_type>();
139 }
140
141
142
143 // bitwise ops:
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(); }
149
150 // comparison ops:
151
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(); }
158
159 // logical
160
161 X operator&&(const X&, const Y&) { return X(); }
162 Z operator||(const X&, const Y&) { return Z(); }
163
164 // arithh assignment
165
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(); }
171
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(); }
178
179 // assignment
180 class Assign {
181 public:
182 void operator=(const Assign& /*a*/) {}
183 X operator[](const int& /*i*/) { return X(); }
184 };
185
186
187
188 namespace boost {
189 namespace lambda {
190
191 // you can do action groups
192 template<class Act>
193 struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
194 typedef Z type;
195 };
196
197 // or specialize the exact action
198 template<>
199 struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
200 typedef X type;
201 };
202
203 // if you want to make a distinction between differently cv-qualified
204 // types, you need to specialize on a different level:
205 template<>
206 struct return_type_2<arithmetic_action<multiply_action>, XX, YY> {
207 typedef YY type;
208 };
209 template<>
210 struct return_type_2<arithmetic_action<multiply_action>, const XX, const YY> {
211 typedef ZZ type;
212 };
213 template<>
214 struct return_type_2<arithmetic_action<multiply_action>, volatile XX, volatile YY> {
215 typedef XX type;
216 };
217 template<>
218 struct return_type_2<arithmetic_action<multiply_action>, volatile const XX, const volatile YY> {
219 typedef VV type;
220 };
221
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> > {
225 typedef typename
226 return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
227 typedef my_vector<res_type> type;
228 };
229
230 // bitwise binary:
231 // you can do action groups
232 template<class Act>
233 struct plain_return_type_2<bitwise_action<Act>, X, Y> {
234 typedef Z type;
235 };
236
237 // or specialize the exact action
238 template<>
239 struct plain_return_type_2<bitwise_action<leftshift_action>, X, Y> {
240 typedef X type;
241 };
242
243 // comparison binary:
244 // you can do action groups
245 template<class Act>
246 struct plain_return_type_2<relational_action<Act>, X, Y> {
247 typedef Z type;
248 };
249
250 // or specialize the exact action
251 template<>
252 struct plain_return_type_2<relational_action<less_action>, X, Y> {
253 typedef X type;
254 };
255
256 // logical binary:
257 // you can do action groups
258 template<class Act>
259 struct plain_return_type_2<logical_action<Act>, X, Y> {
260 typedef Z type;
261 };
262
263 // or specialize the exact action
264 template<>
265 struct plain_return_type_2<logical_action<and_action>, X, Y> {
266 typedef X type;
267 };
268
269 // arithmetic assignment :
270 // you can do action groups
271 template<class Act>
272 struct plain_return_type_2<arithmetic_assignment_action<Act>, X, Y> {
273 typedef Z type;
274 };
275
276 // or specialize the exact action
277 template<>
278 struct plain_return_type_2<arithmetic_assignment_action<multiply_action>, X, Y> {
279 typedef Y type;
280 };
281
282 // arithmetic assignment :
283 // you can do action groups
284 template<class Act>
285 struct plain_return_type_2<bitwise_assignment_action<Act>, X, Y> {
286 typedef Z type;
287 };
288
289 // or specialize the exact action
290 template<>
291 struct plain_return_type_2<bitwise_assignment_action<and_action>, X, Y> {
292 typedef Y type;
293 };
294
295 // assignment
296 template<>
297 struct plain_return_type_2<other_action<assignment_action>, Assign, Assign> {
298 typedef void type;
299 };
300 // subscript
301 template<>
302 struct plain_return_type_2<other_action<subscript_action>, Assign, int> {
303 typedef X type;
304 };
305
306
307 } // end lambda
308 } // end boost
309
310
311
312 void test_binary_operators() {
313
314 X x; Y y;
315 (_1 + _2)(x, y);
316 (_1 - _2)(x, y);
317 (_1 * _2)(x, y);
318 (_1 / _2)(x, y);
319 (_1 % _2)(x, y);
320
321
322 // make a distinction between differently cv-qualified operators
323 XX xx; YY yy;
324 const XX& cxx = xx;
325 const YY& cyy = yy;
326 volatile XX& vxx = xx;
327 volatile YY& vyy = yy;
328 const volatile XX& cvxx = xx;
329 const volatile YY& cvyy = yy;
330
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);
335
336 suppress_unused_variable_warnings(dummy1);
337 suppress_unused_variable_warnings(dummy2);
338 suppress_unused_variable_warnings(dummy3);
339 suppress_unused_variable_warnings(dummy4);
340
341 my_vector<int> v1; my_vector<double> v2;
342 my_vector<double> d = (_1 + _2)(v1, v2);
343
344 suppress_unused_variable_warnings(d);
345
346 // bitwise
347
348 (_1 << _2)(x, y);
349 (_1 >> _2)(x, y);
350 (_1 | _2)(x, y);
351 (_1 & _2)(x, y);
352 (_1 ^ _2)(x, y);
353
354 // comparison
355
356 (_1 < _2)(x, y);
357 (_1 > _2)(x, y);
358 (_1 <= _2)(x, y);
359 (_1 >= _2)(x, y);
360 (_1 == _2)(x, y);
361 (_1 != _2)(x, y);
362
363 // logical
364
365 (_1 || _2)(x, y);
366 (_1 && _2)(x, y);
367
368 // arithmetic assignment
369 (_1 += _2)(x, y);
370 (_1 -= _2)(x, y);
371 (_1 *= _2)(x, y);
372 (_1 /= _2)(x, y);
373 (_1 %= _2)(x, y);
374
375 // bitwise assignment
376 (_1 <<= _2)(x, y);
377 (_1 >>= _2)(x, y);
378 (_1 |= _2)(x, y);
379 (_1 &= _2)(x, y);
380 (_1 ^= _2)(x, y);
381
382 }
383
384
385 int main() {
386 test_unary_operators();
387 test_binary_operators();
388 return boost::report_errors();
389 }