123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- // operator_tests_simple.cpp -- The Boost Lambda Library ---------------
- //
- // Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
- // Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // For more information, see www.boost.org
- // -----------------------------------------------------------------------
- #include <boost/test/minimal.hpp> // see "Header Implementation Option"
- #include "boost/lambda/lambda.hpp"
- #include "boost/lambda/detail/suppress_unused.hpp"
- #include <boost/shared_ptr.hpp>
- #include <vector>
- #include <map>
- #include <set>
- #include <string>
- #include <iostream>
- #ifndef BOOST_NO_STRINGSTREAM
- #include <sstream>
- #endif
- using namespace std;
- using namespace boost;
- using namespace boost::lambda;
- class unary_plus_tester {};
- unary_plus_tester operator+(const unary_plus_tester& a) { return a; }
- void cout_tests()
- {
- #ifndef BOOST_NO_STRINGSTREAM
- using std::cout;
- ostringstream os;
- int i = 10;
- (os << _1)(i);
- (os << constant("FOO"))();
- BOOST_CHECK(os.str() == std::string("10FOO"));
-
- istringstream is("ABC 1");
- std::string s;
- int k;
- is >> s;
- is >> k;
- BOOST_CHECK(s == std::string("ABC"));
- BOOST_CHECK(k == 1);
- // test for constant, constant_ref and var
- i = 5;
- constant_type<int>::type ci(constant(i));
- var_type<int>::type vi(var(i));
- (vi = _1)(make_const(100));
- BOOST_CHECK((ci)() == 5);
- BOOST_CHECK(i == 100);
- int a;
- constant_ref_type<int>::type cr(constant_ref(i));
- (++vi, var(a) = cr)();
- BOOST_CHECK(i == 101);
- #endif
- }
- void arithmetic_operators() {
- int i = 1; int j = 2; int k = 3;
- using namespace std;
- using namespace boost::lambda;
-
- BOOST_CHECK((_1 + 1)(i)==2);
- BOOST_CHECK(((_1 + 1) * _2)(i, j)==4);
- BOOST_CHECK((_1 - 1)(i)==0);
- BOOST_CHECK((_1 * 2)(j)==4);
- BOOST_CHECK((_1 / 2)(j)==1);
- BOOST_CHECK((_1 % 2)(k)==1);
- BOOST_CHECK((-_1)(i) == -1);
- BOOST_CHECK((+_1)(i) == 1);
-
- // test that unary plus really does something
- unary_plus_tester u;
- unary_plus_tester up = (+_1)(u);
- boost::lambda::detail::suppress_unused_variable_warnings(up);
- }
- void bitwise_operators() {
- unsigned int ui = 2;
- BOOST_CHECK((_1 << 1)(ui)==(2 << 1));
- BOOST_CHECK((_1 >> 1)(ui)==(2 >> 1));
- BOOST_CHECK((_1 & 1)(ui)==(2 & 1));
- BOOST_CHECK((_1 | 1)(ui)==(2 | 1));
- BOOST_CHECK((_1 ^ 1)(ui)==(2 ^ 1));
- BOOST_CHECK((~_1)(ui)==~2u);
- }
- void comparison_operators() {
- int i = 0, j = 1;
- BOOST_CHECK((_1 < _2)(i, j) == true);
- BOOST_CHECK((_1 <= _2)(i, j) == true);
- BOOST_CHECK((_1 == _2)(i, j) == false);
- BOOST_CHECK((_1 != _2)(i, j) == true);
- BOOST_CHECK((_1 > _2)(i, j) == false);
- BOOST_CHECK((_1 >= _2)(i, j) == false);
- BOOST_CHECK((!(_1 < _2))(i, j) == false);
- BOOST_CHECK((!(_1 <= _2))(i, j) == false);
- BOOST_CHECK((!(_1 == _2))(i, j) == true);
- BOOST_CHECK((!(_1 != _2))(i, j) == false);
- BOOST_CHECK((!(_1 > _2))(i, j) == true);
- BOOST_CHECK((!(_1 >= _2))(i, j) == true);
- }
- void logical_operators() {
- bool t = true, f = false;
- BOOST_CHECK((_1 && _2)(t, t) == true);
- BOOST_CHECK((_1 && _2)(t, f) == false);
- BOOST_CHECK((_1 && _2)(f, t) == false);
- BOOST_CHECK((_1 && _2)(f, f) == false);
- BOOST_CHECK((_1 || _2)(t, t) == true);
- BOOST_CHECK((_1 || _2)(t, f) == true);
- BOOST_CHECK((_1 || _2)(f, t) == true);
- BOOST_CHECK((_1 || _2)(f, f) == false);
- BOOST_CHECK((!_1)(t) == false);
- BOOST_CHECK((!_1)(f) == true);
- // test short circuiting
- int i=0;
- (false && ++_1)(i);
- BOOST_CHECK(i==0);
- i = 0;
- (true && ++_1)(i);
- BOOST_CHECK(i==1);
- i = 0;
- (false || ++_1)(i);
- BOOST_CHECK(i==1);
- i = 0;
- (true || ++_1)(i);
- BOOST_CHECK(i==0);
- i = 0;
- }
- void unary_incs_and_decs() {
- int i = 0;
- BOOST_CHECK(_1++(i) == 0);
- BOOST_CHECK(i == 1);
- i = 0;
- BOOST_CHECK(_1--(i) == 0);
- BOOST_CHECK(i == -1);
- i = 0;
- BOOST_CHECK((++_1)(i) == 1);
- BOOST_CHECK(i == 1);
- i = 0;
- BOOST_CHECK((--_1)(i) == -1);
- BOOST_CHECK(i == -1);
- i = 0;
- // the result of prefix -- and ++ are lvalues
- (++_1)(i) = 10;
- BOOST_CHECK(i==10);
- i = 0;
- (--_1)(i) = 10;
- BOOST_CHECK(i==10);
- i = 0;
- }
- void compound_operators() {
- int i = 1;
- // normal variable as the left operand
- (i += _1)(make_const(1));
- BOOST_CHECK(i == 2);
- (i -= _1)(make_const(1));
- BOOST_CHECK(i == 1);
- (i *= _1)(make_const(10));
- BOOST_CHECK(i == 10);
- (i /= _1)(make_const(2));
- BOOST_CHECK(i == 5);
- (i %= _1)(make_const(2));
- BOOST_CHECK(i == 1);
- // lambda expression as a left operand
- (_1 += 1)(i);
- BOOST_CHECK(i == 2);
- (_1 -= 1)(i);
- BOOST_CHECK(i == 1);
- (_1 *= 10)(i);
- BOOST_CHECK(i == 10);
- (_1 /= 2)(i);
- BOOST_CHECK(i == 5);
- (_1 %= 2)(i);
- BOOST_CHECK(i == 1);
-
- // lambda expression as a left operand with rvalue on RHS
- (_1 += (0 + 1))(i);
- BOOST_CHECK(i == 2);
- (_1 -= (0 + 1))(i);
- BOOST_CHECK(i == 1);
- (_1 *= (0 + 10))(i);
- BOOST_CHECK(i == 10);
- (_1 /= (0 + 2))(i);
- BOOST_CHECK(i == 5);
- (_1 %= (0 + 2))(i);
- BOOST_CHECK(i == 1);
-
- // shifts
- unsigned int ui = 2;
- (_1 <<= 1)(ui);
- BOOST_CHECK(ui==(2 << 1));
- ui = 2;
- (_1 >>= 1)(ui);
- BOOST_CHECK(ui==(2 >> 1));
- ui = 2;
- (ui <<= _1)(make_const(1));
- BOOST_CHECK(ui==(2 << 1));
- ui = 2;
- (ui >>= _1)(make_const(1));
- BOOST_CHECK(ui==(2 >> 1));
- // and, or, xor
- ui = 2;
- (_1 &= 1)(ui);
- BOOST_CHECK(ui==(2 & 1));
- ui = 2;
- (_1 |= 1)(ui);
- BOOST_CHECK(ui==(2 | 1));
- ui = 2;
- (_1 ^= 1)(ui);
- BOOST_CHECK(ui==(2 ^ 1));
- ui = 2;
- (ui &= _1)(make_const(1));
- BOOST_CHECK(ui==(2 & 1));
- ui = 2;
- (ui |= _1)(make_const(1));
- BOOST_CHECK(ui==(2 | 1));
- ui = 2;
- (ui ^= _1)(make_const(1));
- BOOST_CHECK(ui==(2 ^ 1));
-
- }
- void assignment_and_subscript() {
- // assignment and subscript need to be defined as member functions.
- // Hence, if you wish to use a normal variable as the left hand argument,
- // you must wrap it with var to turn it into a lambda expression
- using std::string;
- string s;
- (_1 = "one")(s);
- BOOST_CHECK(s == string("one"));
- (var(s) = "two")();
- BOOST_CHECK(s == string("two"));
- BOOST_CHECK((var(s)[_1])(make_const(2)) == 'o');
- BOOST_CHECK((_1[2])(s) == 'o');
- BOOST_CHECK((_1[_2])(s, make_const(2)) == 'o');
- // subscript returns lvalue
- (var(s)[_1])(make_const(1)) = 'o';
- BOOST_CHECK(s == "too");
-
- (_1[1])(s) = 'a';
- BOOST_CHECK(s == "tao");
- (_1[_2])(s, make_const(0)) = 'm';
- BOOST_CHECK(s == "mao");
- // TODO: tests for vector, set, map, multimap
- }
- class A {};
- void address_of_and_dereference() {
-
- A a; int i = 42;
-
- BOOST_CHECK((&_1)(a) == &a);
- BOOST_CHECK((*&_1)(i) == 42);
- std::vector<int> vi; vi.push_back(1);
- std::vector<int>::iterator it = vi.begin();
-
- (*_1 = 7)(it);
- BOOST_CHECK(vi[0] == 7);
- const std::vector<int>::iterator cit(it);
- (*_1 = 8)(cit);
- BOOST_CHECK(vi[0] == 8);
- // TODO: Add tests for more complex iterator types
- boost::shared_ptr<int> ptr(new int(0));
- (*_1 = 7)(ptr);
- BOOST_CHECK(*ptr == 7);
- const boost::shared_ptr<int> cptr(ptr);
- (*_1 = 8)(cptr);
- BOOST_CHECK(*ptr == 8);
- }
- void comma() {
- int i = 100;
- BOOST_CHECK((_1 = 10, 2 * _1)(i) == 20);
- // TODO: that the return type is the exact type of the right argument
- // (that r/l valueness is preserved)
- }
- void pointer_arithmetic() {
- int ia[4] = { 1, 2, 3, 4 };
- int* ip = ia;
- int* ia_last = &ia[3];
- const int cia[4] = { 1, 2, 3, 4 };
- const int* cip = cia;
- const int* cia_last = &cia[3];
-
- // non-const array
- BOOST_CHECK((*(_1 + 1))(ia) == 2);
- // non-const pointer
- BOOST_CHECK((*(_1 + 1))(ip) == 2);
- BOOST_CHECK((*(_1 - 1))(ia_last) == 3);
- // const array
- BOOST_CHECK((*(_1 + 1))(cia) == 2);
- // const pointer
- BOOST_CHECK((*(_1 + 1))(cip) == 2);
- BOOST_CHECK((*(_1 - 1))(cia_last) == 3);
-
- // pointer arithmetic should not make non-consts const
- (*(_1 + 2))(ia) = 0;
- (*(_1 + 3))(ip) = 0;
- BOOST_CHECK(ia[2] == 0);
- BOOST_CHECK(ia[3] == 0);
- // pointer - pointer
- BOOST_CHECK((_1 - _2)(ia_last, ia) == 3);
- BOOST_CHECK((_1 - _2)(cia_last, cia) == 3);
- BOOST_CHECK((ia_last - _1)(ia) == 3);
- BOOST_CHECK((cia_last - _1)(cia) == 3);
- BOOST_CHECK((cia_last - _1)(cip) == 3);
- }
- int test_main(int, char *[]) {
- arithmetic_operators();
- bitwise_operators();
- comparison_operators();
- logical_operators();
- unary_incs_and_decs();
- compound_operators();
- assignment_and_subscript();
- address_of_and_dereference();
- comma();
- pointer_arithmetic();
- cout_tests();
- return 0;
- }
|