operator_tests_simple.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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. #include <boost/test/minimal.hpp> // see "Header Implementation Option"
  13. #include "boost/lambda/lambda.hpp"
  14. #include "boost/lambda/detail/suppress_unused.hpp"
  15. #include <boost/shared_ptr.hpp>
  16. #include <vector>
  17. #include <map>
  18. #include <set>
  19. #include <string>
  20. #include <iostream>
  21. #ifndef BOOST_NO_STRINGSTREAM
  22. #include <sstream>
  23. #endif
  24. using namespace std;
  25. using namespace boost;
  26. using namespace boost::lambda;
  27. class unary_plus_tester {};
  28. unary_plus_tester operator+(const unary_plus_tester& a) { return a; }
  29. void cout_tests()
  30. {
  31. #ifndef BOOST_NO_STRINGSTREAM
  32. using std::cout;
  33. ostringstream os;
  34. int i = 10;
  35. (os << _1)(i);
  36. (os << constant("FOO"))();
  37. BOOST_CHECK(os.str() == std::string("10FOO"));
  38. istringstream is("ABC 1");
  39. std::string s;
  40. int k;
  41. is >> s;
  42. is >> k;
  43. BOOST_CHECK(s == std::string("ABC"));
  44. BOOST_CHECK(k == 1);
  45. // test for constant, constant_ref and var
  46. i = 5;
  47. constant_type<int>::type ci(constant(i));
  48. var_type<int>::type vi(var(i));
  49. (vi = _1)(make_const(100));
  50. BOOST_CHECK((ci)() == 5);
  51. BOOST_CHECK(i == 100);
  52. int a;
  53. constant_ref_type<int>::type cr(constant_ref(i));
  54. (++vi, var(a) = cr)();
  55. BOOST_CHECK(i == 101);
  56. #endif
  57. }
  58. void arithmetic_operators() {
  59. int i = 1; int j = 2; int k = 3;
  60. using namespace std;
  61. using namespace boost::lambda;
  62. BOOST_CHECK((_1 + 1)(i)==2);
  63. BOOST_CHECK(((_1 + 1) * _2)(i, j)==4);
  64. BOOST_CHECK((_1 - 1)(i)==0);
  65. BOOST_CHECK((_1 * 2)(j)==4);
  66. BOOST_CHECK((_1 / 2)(j)==1);
  67. BOOST_CHECK((_1 % 2)(k)==1);
  68. BOOST_CHECK((-_1)(i) == -1);
  69. BOOST_CHECK((+_1)(i) == 1);
  70. // test that unary plus really does something
  71. unary_plus_tester u;
  72. unary_plus_tester up = (+_1)(u);
  73. boost::lambda::detail::suppress_unused_variable_warnings(up);
  74. }
  75. void bitwise_operators() {
  76. unsigned int ui = 2;
  77. BOOST_CHECK((_1 << 1)(ui)==(2 << 1));
  78. BOOST_CHECK((_1 >> 1)(ui)==(2 >> 1));
  79. BOOST_CHECK((_1 & 1)(ui)==(2 & 1));
  80. BOOST_CHECK((_1 | 1)(ui)==(2 | 1));
  81. BOOST_CHECK((_1 ^ 1)(ui)==(2 ^ 1));
  82. BOOST_CHECK((~_1)(ui)==~2u);
  83. }
  84. void comparison_operators() {
  85. int i = 0, j = 1;
  86. BOOST_CHECK((_1 < _2)(i, j) == true);
  87. BOOST_CHECK((_1 <= _2)(i, j) == true);
  88. BOOST_CHECK((_1 == _2)(i, j) == false);
  89. BOOST_CHECK((_1 != _2)(i, j) == true);
  90. BOOST_CHECK((_1 > _2)(i, j) == false);
  91. BOOST_CHECK((_1 >= _2)(i, j) == false);
  92. BOOST_CHECK((!(_1 < _2))(i, j) == false);
  93. BOOST_CHECK((!(_1 <= _2))(i, j) == false);
  94. BOOST_CHECK((!(_1 == _2))(i, j) == true);
  95. BOOST_CHECK((!(_1 != _2))(i, j) == false);
  96. BOOST_CHECK((!(_1 > _2))(i, j) == true);
  97. BOOST_CHECK((!(_1 >= _2))(i, j) == true);
  98. }
  99. void logical_operators() {
  100. bool t = true, f = false;
  101. BOOST_CHECK((_1 && _2)(t, t) == true);
  102. BOOST_CHECK((_1 && _2)(t, f) == false);
  103. BOOST_CHECK((_1 && _2)(f, t) == false);
  104. BOOST_CHECK((_1 && _2)(f, f) == false);
  105. BOOST_CHECK((_1 || _2)(t, t) == true);
  106. BOOST_CHECK((_1 || _2)(t, f) == true);
  107. BOOST_CHECK((_1 || _2)(f, t) == true);
  108. BOOST_CHECK((_1 || _2)(f, f) == false);
  109. BOOST_CHECK((!_1)(t) == false);
  110. BOOST_CHECK((!_1)(f) == true);
  111. // test short circuiting
  112. int i=0;
  113. (false && ++_1)(i);
  114. BOOST_CHECK(i==0);
  115. i = 0;
  116. (true && ++_1)(i);
  117. BOOST_CHECK(i==1);
  118. i = 0;
  119. (false || ++_1)(i);
  120. BOOST_CHECK(i==1);
  121. i = 0;
  122. (true || ++_1)(i);
  123. BOOST_CHECK(i==0);
  124. i = 0;
  125. }
  126. void unary_incs_and_decs() {
  127. int i = 0;
  128. BOOST_CHECK(_1++(i) == 0);
  129. BOOST_CHECK(i == 1);
  130. i = 0;
  131. BOOST_CHECK(_1--(i) == 0);
  132. BOOST_CHECK(i == -1);
  133. i = 0;
  134. BOOST_CHECK((++_1)(i) == 1);
  135. BOOST_CHECK(i == 1);
  136. i = 0;
  137. BOOST_CHECK((--_1)(i) == -1);
  138. BOOST_CHECK(i == -1);
  139. i = 0;
  140. // the result of prefix -- and ++ are lvalues
  141. (++_1)(i) = 10;
  142. BOOST_CHECK(i==10);
  143. i = 0;
  144. (--_1)(i) = 10;
  145. BOOST_CHECK(i==10);
  146. i = 0;
  147. }
  148. void compound_operators() {
  149. int i = 1;
  150. // normal variable as the left operand
  151. (i += _1)(make_const(1));
  152. BOOST_CHECK(i == 2);
  153. (i -= _1)(make_const(1));
  154. BOOST_CHECK(i == 1);
  155. (i *= _1)(make_const(10));
  156. BOOST_CHECK(i == 10);
  157. (i /= _1)(make_const(2));
  158. BOOST_CHECK(i == 5);
  159. (i %= _1)(make_const(2));
  160. BOOST_CHECK(i == 1);
  161. // lambda expression as a left operand
  162. (_1 += 1)(i);
  163. BOOST_CHECK(i == 2);
  164. (_1 -= 1)(i);
  165. BOOST_CHECK(i == 1);
  166. (_1 *= 10)(i);
  167. BOOST_CHECK(i == 10);
  168. (_1 /= 2)(i);
  169. BOOST_CHECK(i == 5);
  170. (_1 %= 2)(i);
  171. BOOST_CHECK(i == 1);
  172. // lambda expression as a left operand with rvalue on RHS
  173. (_1 += (0 + 1))(i);
  174. BOOST_CHECK(i == 2);
  175. (_1 -= (0 + 1))(i);
  176. BOOST_CHECK(i == 1);
  177. (_1 *= (0 + 10))(i);
  178. BOOST_CHECK(i == 10);
  179. (_1 /= (0 + 2))(i);
  180. BOOST_CHECK(i == 5);
  181. (_1 %= (0 + 2))(i);
  182. BOOST_CHECK(i == 1);
  183. // shifts
  184. unsigned int ui = 2;
  185. (_1 <<= 1)(ui);
  186. BOOST_CHECK(ui==(2 << 1));
  187. ui = 2;
  188. (_1 >>= 1)(ui);
  189. BOOST_CHECK(ui==(2 >> 1));
  190. ui = 2;
  191. (ui <<= _1)(make_const(1));
  192. BOOST_CHECK(ui==(2 << 1));
  193. ui = 2;
  194. (ui >>= _1)(make_const(1));
  195. BOOST_CHECK(ui==(2 >> 1));
  196. // and, or, xor
  197. ui = 2;
  198. (_1 &= 1)(ui);
  199. BOOST_CHECK(ui==(2 & 1));
  200. ui = 2;
  201. (_1 |= 1)(ui);
  202. BOOST_CHECK(ui==(2 | 1));
  203. ui = 2;
  204. (_1 ^= 1)(ui);
  205. BOOST_CHECK(ui==(2 ^ 1));
  206. ui = 2;
  207. (ui &= _1)(make_const(1));
  208. BOOST_CHECK(ui==(2 & 1));
  209. ui = 2;
  210. (ui |= _1)(make_const(1));
  211. BOOST_CHECK(ui==(2 | 1));
  212. ui = 2;
  213. (ui ^= _1)(make_const(1));
  214. BOOST_CHECK(ui==(2 ^ 1));
  215. }
  216. void assignment_and_subscript() {
  217. // assignment and subscript need to be defined as member functions.
  218. // Hence, if you wish to use a normal variable as the left hand argument,
  219. // you must wrap it with var to turn it into a lambda expression
  220. using std::string;
  221. string s;
  222. (_1 = "one")(s);
  223. BOOST_CHECK(s == string("one"));
  224. (var(s) = "two")();
  225. BOOST_CHECK(s == string("two"));
  226. BOOST_CHECK((var(s)[_1])(make_const(2)) == 'o');
  227. BOOST_CHECK((_1[2])(s) == 'o');
  228. BOOST_CHECK((_1[_2])(s, make_const(2)) == 'o');
  229. // subscript returns lvalue
  230. (var(s)[_1])(make_const(1)) = 'o';
  231. BOOST_CHECK(s == "too");
  232. (_1[1])(s) = 'a';
  233. BOOST_CHECK(s == "tao");
  234. (_1[_2])(s, make_const(0)) = 'm';
  235. BOOST_CHECK(s == "mao");
  236. // TODO: tests for vector, set, map, multimap
  237. }
  238. class A {};
  239. void address_of_and_dereference() {
  240. A a; int i = 42;
  241. BOOST_CHECK((&_1)(a) == &a);
  242. BOOST_CHECK((*&_1)(i) == 42);
  243. std::vector<int> vi; vi.push_back(1);
  244. std::vector<int>::iterator it = vi.begin();
  245. (*_1 = 7)(it);
  246. BOOST_CHECK(vi[0] == 7);
  247. const std::vector<int>::iterator cit(it);
  248. (*_1 = 8)(cit);
  249. BOOST_CHECK(vi[0] == 8);
  250. // TODO: Add tests for more complex iterator types
  251. boost::shared_ptr<int> ptr(new int(0));
  252. (*_1 = 7)(ptr);
  253. BOOST_CHECK(*ptr == 7);
  254. const boost::shared_ptr<int> cptr(ptr);
  255. (*_1 = 8)(cptr);
  256. BOOST_CHECK(*ptr == 8);
  257. }
  258. void comma() {
  259. int i = 100;
  260. BOOST_CHECK((_1 = 10, 2 * _1)(i) == 20);
  261. // TODO: that the return type is the exact type of the right argument
  262. // (that r/l valueness is preserved)
  263. }
  264. void pointer_arithmetic() {
  265. int ia[4] = { 1, 2, 3, 4 };
  266. int* ip = ia;
  267. int* ia_last = &ia[3];
  268. const int cia[4] = { 1, 2, 3, 4 };
  269. const int* cip = cia;
  270. const int* cia_last = &cia[3];
  271. // non-const array
  272. BOOST_CHECK((*(_1 + 1))(ia) == 2);
  273. // non-const pointer
  274. BOOST_CHECK((*(_1 + 1))(ip) == 2);
  275. BOOST_CHECK((*(_1 - 1))(ia_last) == 3);
  276. // const array
  277. BOOST_CHECK((*(_1 + 1))(cia) == 2);
  278. // const pointer
  279. BOOST_CHECK((*(_1 + 1))(cip) == 2);
  280. BOOST_CHECK((*(_1 - 1))(cia_last) == 3);
  281. // pointer arithmetic should not make non-consts const
  282. (*(_1 + 2))(ia) = 0;
  283. (*(_1 + 3))(ip) = 0;
  284. BOOST_CHECK(ia[2] == 0);
  285. BOOST_CHECK(ia[3] == 0);
  286. // pointer - pointer
  287. BOOST_CHECK((_1 - _2)(ia_last, ia) == 3);
  288. BOOST_CHECK((_1 - _2)(cia_last, cia) == 3);
  289. BOOST_CHECK((ia_last - _1)(ia) == 3);
  290. BOOST_CHECK((cia_last - _1)(cia) == 3);
  291. BOOST_CHECK((cia_last - _1)(cip) == 3);
  292. }
  293. int test_main(int, char *[]) {
  294. arithmetic_operators();
  295. bitwise_operators();
  296. comparison_operators();
  297. logical_operators();
  298. unary_incs_and_decs();
  299. compound_operators();
  300. assignment_and_subscript();
  301. address_of_and_dereference();
  302. comma();
  303. pointer_arithmetic();
  304. cout_tests();
  305. return 0;
  306. }