• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  operator_tests_simple.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 
16 #include <boost/core/lightweight_test.hpp>
17 
18 #include "boost/lambda/lambda.hpp"
19 
20 #include "boost/lambda/detail/suppress_unused.hpp"
21 
22 #include <boost/shared_ptr.hpp>
23 
24 #include <vector>
25 #include <map>
26 #include <set>
27 #include <string>
28 
29 #include <iostream>
30 
31 #ifndef BOOST_NO_STRINGSTREAM
32 #include <sstream>
33 #endif
34 
35 using namespace std;
36 using namespace boost;
37 
38 using namespace boost::lambda;
39 
40 
41 class unary_plus_tester {};
operator +(const unary_plus_tester & a)42 unary_plus_tester operator+(const unary_plus_tester& a) { return a; }
43 
cout_tests()44 void cout_tests()
45 {
46 #ifndef BOOST_NO_STRINGSTREAM
47   using std::cout;
48   ostringstream os;
49   int i = 10;
50   (os << _1)(i);
51 
52   (os << constant("FOO"))();
53 
54   BOOST_TEST_EQ(os.str(), std::string("10FOO"));
55 
56 
57   istringstream is("ABC 1");
58   std::string s;
59   int k;
60 
61   is >> s;
62   is >> k;
63 
64   BOOST_TEST_EQ(s, std::string("ABC"));
65   BOOST_TEST_EQ(k, 1);
66   // test for constant, constant_ref and var
67   i = 5;
68   constant_type<int>::type ci(constant(i));
69   var_type<int>::type vi(var(i));
70 
71   (vi = _1)(make_const(100));
72   BOOST_TEST_EQ((ci)(), 5);
73   BOOST_TEST_EQ(i, 100);
74 
75   int a;
76   constant_ref_type<int>::type cr(constant_ref(i));
77   (++vi, var(a) = cr)();
78   BOOST_TEST_EQ(i, 101);
79 #endif
80 }
81 
arithmetic_operators()82 void arithmetic_operators() {
83   int i = 1; int j = 2; int k = 3;
84 
85   using namespace std;
86   using namespace boost::lambda;
87 
88   BOOST_TEST_EQ((_1 + 1)(i), 2);
89   BOOST_TEST_EQ(((_1 + 1) * _2)(i, j), 4);
90   BOOST_TEST_EQ((_1 - 1)(i), 0);
91 
92   BOOST_TEST_EQ((_1 * 2)(j), 4);
93   BOOST_TEST_EQ((_1 / 2)(j), 1);
94 
95   BOOST_TEST_EQ((_1 % 2)(k), 1);
96 
97   BOOST_TEST_EQ((-_1)(i), -1);
98   BOOST_TEST_EQ((+_1)(i), 1);
99 
100   // test that unary plus really does something
101   unary_plus_tester u;
102   unary_plus_tester up = (+_1)(u);
103 
104   boost::lambda::detail::suppress_unused_variable_warnings(up);
105 }
106 
bitwise_operators()107 void bitwise_operators() {
108   unsigned int ui = 2;
109 
110   BOOST_TEST_EQ((_1 << 1)(ui), (2 << 1));
111   BOOST_TEST_EQ((_1 >> 1)(ui), (2 >> 1));
112 
113   BOOST_TEST_EQ((_1 & 1)(ui), (2 & 1));
114   BOOST_TEST_EQ((_1 | 1)(ui), (2 | 1));
115   BOOST_TEST_EQ((_1 ^ 1)(ui), (2 ^ 1));
116   BOOST_TEST_EQ((~_1)(ui), ~2u);
117 }
118 
comparison_operators()119 void comparison_operators() {
120   int i = 0, j = 1;
121 
122   BOOST_TEST((_1 < _2)(i, j));
123   BOOST_TEST((_1 <= _2)(i, j));
124   BOOST_TEST(!(_1 == _2)(i, j));
125   BOOST_TEST((_1 != _2)(i, j));
126   BOOST_TEST(!(_1 > _2)(i, j));
127   BOOST_TEST(!(_1 >= _2)(i, j));
128 
129   BOOST_TEST(!(!(_1 < _2))(i, j));
130   BOOST_TEST(!(!(_1 <= _2))(i, j));
131   BOOST_TEST((!(_1 == _2))(i, j));
132   BOOST_TEST(!(!(_1 != _2))(i, j));
133   BOOST_TEST((!(_1 > _2))(i, j));
134   BOOST_TEST((!(_1 >= _2))(i, j));
135 }
136 
logical_operators()137 void logical_operators() {
138 
139   bool t = true, f = false;
140   BOOST_TEST((_1 && _2)(t, t));
141   BOOST_TEST(!(_1 && _2)(t, f));
142   BOOST_TEST(!(_1 && _2)(f, t));
143   BOOST_TEST(!(_1 && _2)(f, f));
144 
145   BOOST_TEST((_1 || _2)(t, t));
146   BOOST_TEST((_1 || _2)(t, f));
147   BOOST_TEST((_1 || _2)(f, t));
148   BOOST_TEST(!(_1 || _2)(f, f));
149 
150   BOOST_TEST(!(!_1)(t));
151   BOOST_TEST((!_1)(f));
152 
153   // test short circuiting
154   int i=0;
155 
156   (false && ++_1)(i);
157   BOOST_TEST_EQ(i, 0);
158   i = 0;
159 
160   (true && ++_1)(i);
161   BOOST_TEST_EQ(i, 1);
162   i = 0;
163 
164   (false || ++_1)(i);
165   BOOST_TEST_EQ(i, 1);
166   i = 0;
167 
168   (true || ++_1)(i);
169   BOOST_TEST_EQ(i, 0);
170   i = 0;
171 }
172 
unary_incs_and_decs()173 void unary_incs_and_decs() {
174   int i = 0;
175 
176   BOOST_TEST_EQ(_1++(i), 0);
177   BOOST_TEST_EQ(i, 1);
178   i = 0;
179 
180   BOOST_TEST_EQ(_1--(i), 0);
181   BOOST_TEST_EQ(i, -1);
182   i = 0;
183 
184   BOOST_TEST_EQ((++_1)(i), 1);
185   BOOST_TEST_EQ(i, 1);
186   i = 0;
187 
188   BOOST_TEST_EQ((--_1)(i), -1);
189   BOOST_TEST_EQ(i, -1);
190   i = 0;
191 
192   // the result of prefix -- and ++ are lvalues
193   (++_1)(i) = 10;
194   BOOST_TEST_EQ(i, 10);
195   i = 0;
196 
197   (--_1)(i) = 10;
198   BOOST_TEST_EQ(i, 10);
199   i = 0;
200 }
201 
compound_operators()202 void compound_operators() {
203 
204   int i = 1;
205 
206   // normal variable as the left operand
207   (i += _1)(make_const(1));
208   BOOST_TEST_EQ(i, 2);
209 
210   (i -= _1)(make_const(1));
211   BOOST_TEST_EQ(i, 1);
212 
213   (i *= _1)(make_const(10));
214   BOOST_TEST_EQ(i, 10);
215 
216   (i /= _1)(make_const(2));
217   BOOST_TEST_EQ(i, 5);
218 
219   (i %= _1)(make_const(2));
220   BOOST_TEST_EQ(i, 1);
221 
222   // lambda expression as a left operand
223   (_1 += 1)(i);
224   BOOST_TEST_EQ(i, 2);
225 
226   (_1 -= 1)(i);
227   BOOST_TEST_EQ(i, 1);
228 
229   (_1 *= 10)(i);
230   BOOST_TEST_EQ(i, 10);
231 
232   (_1 /= 2)(i);
233   BOOST_TEST_EQ(i, 5);
234 
235   (_1 %= 2)(i);
236   BOOST_TEST_EQ(i, 1);
237 
238   // lambda expression as a left operand with rvalue on RHS
239   (_1 += (0 + 1))(i);
240   BOOST_TEST_EQ(i, 2);
241 
242   (_1 -= (0 + 1))(i);
243   BOOST_TEST_EQ(i, 1);
244 
245   (_1 *= (0 + 10))(i);
246   BOOST_TEST_EQ(i, 10);
247 
248   (_1 /= (0 + 2))(i);
249   BOOST_TEST_EQ(i, 5);
250 
251   (_1 %= (0 + 2))(i);
252   BOOST_TEST_EQ(i, 1);
253 
254   // shifts
255   unsigned int ui = 2;
256   (_1 <<= 1)(ui);
257   BOOST_TEST_EQ(ui, (2 << 1));
258 
259   ui = 2;
260   (_1 >>= 1)(ui);
261   BOOST_TEST_EQ(ui, (2 >> 1));
262 
263   ui = 2;
264   (ui <<= _1)(make_const(1));
265   BOOST_TEST_EQ(ui, (2 << 1));
266 
267   ui = 2;
268   (ui >>= _1)(make_const(1));
269   BOOST_TEST_EQ(ui, (2 >> 1));
270 
271   // and, or, xor
272   ui = 2;
273   (_1 &= 1)(ui);
274   BOOST_TEST_EQ(ui, (2 & 1));
275 
276   ui = 2;
277   (_1 |= 1)(ui);
278   BOOST_TEST_EQ(ui, (2 | 1));
279 
280   ui = 2;
281   (_1 ^= 1)(ui);
282   BOOST_TEST_EQ(ui, (2 ^ 1));
283 
284   ui = 2;
285   (ui &= _1)(make_const(1));
286   BOOST_TEST_EQ(ui, (2 & 1));
287 
288   ui = 2;
289   (ui |= _1)(make_const(1));
290   BOOST_TEST_EQ(ui, (2 | 1));
291 
292   ui = 2;
293   (ui ^= _1)(make_const(1));
294   BOOST_TEST_EQ(ui, (2 ^ 1));
295 
296 }
297 
assignment_and_subscript()298 void assignment_and_subscript() {
299 
300   // assignment and subscript need to be defined as member functions.
301   // Hence, if you wish to use a normal variable as the left hand argument,
302   // you must wrap it with var to turn it into a lambda expression
303 
304   using std::string;
305   string s;
306 
307   (_1 = "one")(s);
308   BOOST_TEST_EQ(s, string("one"));
309 
310   (var(s) = "two")();
311   BOOST_TEST_EQ(s, string("two"));
312 
313   BOOST_TEST_EQ((var(s)[_1])(make_const(2)), 'o');
314   BOOST_TEST_EQ((_1[2])(s), 'o');
315   BOOST_TEST_EQ((_1[_2])(s, make_const(2)), 'o');
316 
317   // subscript returns lvalue
318   (var(s)[_1])(make_const(1)) = 'o';
319   BOOST_TEST_EQ(s, "too");
320 
321   (_1[1])(s) = 'a';
322   BOOST_TEST_EQ(s, "tao");
323 
324   (_1[_2])(s, make_const(0)) = 'm';
325   BOOST_TEST_EQ(s, "mao");
326 
327   // TODO: tests for vector, set, map, multimap
328 }
329 
330 class A {};
331 
address_of_and_dereference()332 void address_of_and_dereference() {
333 
334   A a; int i = 42;
335 
336   BOOST_TEST_EQ((&_1)(a), &a);
337   BOOST_TEST_EQ((*&_1)(i), 42);
338 
339   std::vector<int> vi; vi.push_back(1);
340   std::vector<int>::iterator it = vi.begin();
341 
342   (*_1 = 7)(it);
343   BOOST_TEST_EQ(vi[0], 7);
344   const std::vector<int>::iterator cit(it);
345   (*_1 = 8)(cit);
346   BOOST_TEST_EQ(vi[0], 8);
347 
348   // TODO: Add tests for more complex iterator types
349 
350   boost::shared_ptr<int> ptr(new int(0));
351   (*_1 = 7)(ptr);
352   BOOST_TEST_EQ(*ptr, 7);
353   const boost::shared_ptr<int> cptr(ptr);
354   (*_1 = 8)(cptr);
355   BOOST_TEST_EQ(*ptr, 8);
356 }
357 
358 
359 
comma()360 void comma() {
361 
362   int i = 100;
363   BOOST_TEST_EQ((_1 = 10, 2 * _1)(i), 20);
364 
365   // TODO: that the return type is the exact type of the right argument
366   // (that r/l valueness is preserved)
367 
368 }
369 
pointer_arithmetic()370 void pointer_arithmetic() {
371 
372   int ia[4] = { 1, 2, 3, 4 };
373   int* ip = ia;
374   int* ia_last = &ia[3];
375 
376   const int cia[4] = { 1, 2, 3, 4 };
377   const int* cip = cia;
378   const int* cia_last = &cia[3];
379 
380 
381   // non-const array
382   BOOST_TEST_EQ((*(_1 + 1))(ia), 2);
383 
384   // non-const pointer
385   BOOST_TEST_EQ((*(_1 + 1))(ip), 2);
386 
387   BOOST_TEST_EQ((*(_1 - 1))(ia_last), 3);
388 
389   // const array
390   BOOST_TEST_EQ((*(_1 + 1))(cia), 2);
391   // const pointer
392   BOOST_TEST_EQ((*(_1 + 1))(cip), 2);
393   BOOST_TEST_EQ((*(_1 - 1))(cia_last), 3);
394 
395   // pointer arithmetic should not make non-consts const
396     (*(_1 + 2))(ia) = 0;
397     (*(_1 + 3))(ip) = 0;
398 
399   BOOST_TEST_EQ(ia[2], 0);
400   BOOST_TEST_EQ(ia[3], 0);
401 
402   // pointer - pointer
403   BOOST_TEST_EQ((_1 - _2)(ia_last, ia), 3);
404   BOOST_TEST_EQ((_1 - _2)(cia_last, cia), 3);
405   BOOST_TEST_EQ((ia_last - _1)(ia), 3);
406   BOOST_TEST_EQ((cia_last - _1)(cia), 3);
407   BOOST_TEST_EQ((cia_last - _1)(cip), 3);
408 
409 }
410 
main()411 int main()
412 {
413   arithmetic_operators();
414   bitwise_operators();
415   comparison_operators();
416   logical_operators();
417   unary_incs_and_decs();
418   compound_operators();
419   assignment_and_subscript();
420   address_of_and_dereference();
421   comma();
422   pointer_arithmetic();
423   cout_tests();
424   return boost::report_errors();
425 }
426