diff options
Diffstat (limited to 'libs/lambda/test/operator_tests_simple.cpp')
-rw-r--r-- | libs/lambda/test/operator_tests_simple.cpp | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/libs/lambda/test/operator_tests_simple.cpp b/libs/lambda/test/operator_tests_simple.cpp new file mode 100644 index 000000000..34711fbbc --- /dev/null +++ b/libs/lambda/test/operator_tests_simple.cpp @@ -0,0 +1,431 @@ +// 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; +} + + + + + + |