/src/boost_1_50_0/libs/lambda/test/extending_rt_traits.cpp
https://bitbucket.org/johnny_lai/labvvis · C++ · 394 lines · 253 code · 88 blank · 53 comment · 5 complexity · ef6f23d5d69e91fb4e21c54a1e239228 MD5 · raw file
- // extending_return_type_traits.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/bind.hpp"
- #include "boost/lambda/lambda.hpp"
- #include "boost/lambda/detail/suppress_unused.hpp"
-
- #include <iostream>
-
- #include <functional>
-
- #include <algorithm>
-
- using boost::lambda::detail::suppress_unused_variable_warnings;
-
- class A {};
- class B {};
-
- using namespace boost::lambda;
-
-
- B operator--(const A&, int) { return B(); }
- B operator--(A&) { return B(); }
- B operator++(const A&, int) { return B(); }
- B operator++(A&) { return B(); }
- B operator-(const A&) { return B(); }
- B operator+(const A&) { return B(); }
-
- B operator!(const A&) { return B(); }
-
- B operator&(const A&) { return B(); }
- B operator*(const A&) { return B(); }
-
- namespace boost {
- namespace lambda {
-
- // unary + and -
- template<class Act>
- struct plain_return_type_1<unary_arithmetic_action<Act>, A > {
- typedef B type;
- };
-
- // post incr/decr
- template<class Act>
- struct plain_return_type_1<post_increment_decrement_action<Act>, A > {
- typedef B type;
- };
-
- // pre incr/decr
- template<class Act>
- struct plain_return_type_1<pre_increment_decrement_action<Act>, A > {
- typedef B type;
- };
- // !
- template<>
- struct plain_return_type_1<logical_action<not_action>, A> {
- typedef B type;
- };
- // &
- template<>
- struct plain_return_type_1<other_action<addressof_action>, A> {
- typedef B type;
- };
- // *
- template<>
- struct plain_return_type_1<other_action<contentsof_action>, A> {
- typedef B type;
- };
-
-
- } // lambda
- } // boost
-
- void ok(B /*b*/) {}
-
- void test_unary_operators()
- {
- A a; int i = 1;
- ok((++_1)(a));
- ok((--_1)(a));
- ok((_1++)(a));
- ok((_1--)(a));
- ok((+_1)(a));
- ok((-_1)(a));
- ok((!_1)(a));
- ok((&_1)(a));
- ok((*_1)(a));
-
- BOOST_CHECK((*_1)(make_const(&i)) == 1);
- }
-
- class X {};
- class Y {};
- class Z {};
-
- Z operator+(const X&, const Y&) { return Z(); }
- Z operator-(const X&, const Y&) { return Z(); }
- X operator*(const X&, const Y&) { return X(); }
-
- Z operator/(const X&, const Y&) { return Z(); }
- Z operator%(const X&, const Y&) { return Z(); }
-
- class XX {};
- class YY {};
- class ZZ {};
- class VV {};
-
- // it is possible to support differently cv-qualified versions
- YY operator*(XX&, YY&) { return YY(); }
- ZZ operator*(const XX&, const YY&) { return ZZ(); }
- XX operator*(volatile XX&, volatile YY&) { return XX(); }
- VV operator*(const volatile XX&, const volatile YY&) { return VV(); }
-
- // the traits can be more complex:
- template <class T>
- class my_vector {};
-
- template<class A, class B>
- my_vector<typename return_type_2<arithmetic_action<plus_action>, A&, B&>::type>
- operator+(const my_vector<A>& /*a*/, const my_vector<B>& /*b*/)
- {
- typedef typename
- return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
- return my_vector<res_type>();
- }
-
-
-
- // bitwise ops:
- X operator<<(const X&, const Y&) { return X(); }
- Z operator>>(const X&, const Y&) { return Z(); }
- Z operator&(const X&, const Y&) { return Z(); }
- Z operator|(const X&, const Y&) { return Z(); }
- Z operator^(const X&, const Y&) { return Z(); }
-
- // comparison ops:
-
- X operator<(const X&, const Y&) { return X(); }
- Z operator>(const X&, const Y&) { return Z(); }
- Z operator<=(const X&, const Y&) { return Z(); }
- Z operator>=(const X&, const Y&) { return Z(); }
- Z operator==(const X&, const Y&) { return Z(); }
- Z operator!=(const X&, const Y&) { return Z(); }
-
- // logical
-
- X operator&&(const X&, const Y&) { return X(); }
- Z operator||(const X&, const Y&) { return Z(); }
-
- // arithh assignment
-
- Z operator+=( X&, const Y&) { return Z(); }
- Z operator-=( X&, const Y&) { return Z(); }
- Y operator*=( X&, const Y&) { return Y(); }
- Z operator/=( X&, const Y&) { return Z(); }
- Z operator%=( X&, const Y&) { return Z(); }
-
- // bitwise assignment
- Z operator<<=( X&, const Y&) { return Z(); }
- Z operator>>=( X&, const Y&) { return Z(); }
- Y operator&=( X&, const Y&) { return Y(); }
- Z operator|=( X&, const Y&) { return Z(); }
- Z operator^=( X&, const Y&) { return Z(); }
-
- // assignment
- class Assign {
- public:
- void operator=(const Assign& /*a*/) {}
- X operator[](const int& /*i*/) { return X(); }
- };
-
-
-
- namespace boost {
- namespace lambda {
-
- // you can do action groups
- template<class Act>
- struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
- typedef Z type;
- };
-
- // or specialize the exact action
- template<>
- struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
- typedef X type;
- };
-
- // if you want to make a distinction between differently cv-qualified
- // types, you need to specialize on a different level:
- template<>
- struct return_type_2<arithmetic_action<multiply_action>, XX, YY> {
- typedef YY type;
- };
- template<>
- struct return_type_2<arithmetic_action<multiply_action>, const XX, const YY> {
- typedef ZZ type;
- };
- template<>
- struct return_type_2<arithmetic_action<multiply_action>, volatile XX, volatile YY> {
- typedef XX type;
- };
- template<>
- struct return_type_2<arithmetic_action<multiply_action>, volatile const XX, const volatile YY> {
- typedef VV type;
- };
-
- // the mapping can be more complex:
- template<class A, class B>
- struct plain_return_type_2<arithmetic_action<plus_action>, my_vector<A>, my_vector<B> > {
- typedef typename
- return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
- typedef my_vector<res_type> type;
- };
-
- // bitwise binary:
- // you can do action groups
- template<class Act>
- struct plain_return_type_2<bitwise_action<Act>, X, Y> {
- typedef Z type;
- };
-
- // or specialize the exact action
- template<>
- struct plain_return_type_2<bitwise_action<leftshift_action>, X, Y> {
- typedef X type;
- };
-
- // comparison binary:
- // you can do action groups
- template<class Act>
- struct plain_return_type_2<relational_action<Act>, X, Y> {
- typedef Z type;
- };
-
- // or specialize the exact action
- template<>
- struct plain_return_type_2<relational_action<less_action>, X, Y> {
- typedef X type;
- };
-
- // logical binary:
- // you can do action groups
- template<class Act>
- struct plain_return_type_2<logical_action<Act>, X, Y> {
- typedef Z type;
- };
-
- // or specialize the exact action
- template<>
- struct plain_return_type_2<logical_action<and_action>, X, Y> {
- typedef X type;
- };
-
- // arithmetic assignment :
- // you can do action groups
- template<class Act>
- struct plain_return_type_2<arithmetic_assignment_action<Act>, X, Y> {
- typedef Z type;
- };
-
- // or specialize the exact action
- template<>
- struct plain_return_type_2<arithmetic_assignment_action<multiply_action>, X, Y> {
- typedef Y type;
- };
-
- // arithmetic assignment :
- // you can do action groups
- template<class Act>
- struct plain_return_type_2<bitwise_assignment_action<Act>, X, Y> {
- typedef Z type;
- };
-
- // or specialize the exact action
- template<>
- struct plain_return_type_2<bitwise_assignment_action<and_action>, X, Y> {
- typedef Y type;
- };
-
- // assignment
- template<>
- struct plain_return_type_2<other_action<assignment_action>, Assign, Assign> {
- typedef void type;
- };
- // subscript
- template<>
- struct plain_return_type_2<other_action<subscript_action>, Assign, int> {
- typedef X type;
- };
-
-
- } // end lambda
- } // end boost
-
-
-
- void test_binary_operators() {
-
- X x; Y y;
- (_1 + _2)(x, y);
- (_1 - _2)(x, y);
- (_1 * _2)(x, y);
- (_1 / _2)(x, y);
- (_1 % _2)(x, y);
-
-
- // make a distinction between differently cv-qualified operators
- XX xx; YY yy;
- const XX& cxx = xx;
- const YY& cyy = yy;
- volatile XX& vxx = xx;
- volatile YY& vyy = yy;
- const volatile XX& cvxx = xx;
- const volatile YY& cvyy = yy;
-
- ZZ dummy1 = (_1 * _2)(cxx, cyy);
- YY dummy2 = (_1 * _2)(xx, yy);
- XX dummy3 = (_1 * _2)(vxx, vyy);
- VV dummy4 = (_1 * _2)(cvxx, cvyy);
-
- suppress_unused_variable_warnings(dummy1);
- suppress_unused_variable_warnings(dummy2);
- suppress_unused_variable_warnings(dummy3);
- suppress_unused_variable_warnings(dummy4);
-
- my_vector<int> v1; my_vector<double> v2;
- my_vector<double> d = (_1 + _2)(v1, v2);
-
- suppress_unused_variable_warnings(d);
-
- // bitwise
-
- (_1 << _2)(x, y);
- (_1 >> _2)(x, y);
- (_1 | _2)(x, y);
- (_1 & _2)(x, y);
- (_1 ^ _2)(x, y);
-
- // comparison
-
- (_1 < _2)(x, y);
- (_1 > _2)(x, y);
- (_1 <= _2)(x, y);
- (_1 >= _2)(x, y);
- (_1 == _2)(x, y);
- (_1 != _2)(x, y);
-
- // logical
-
- (_1 || _2)(x, y);
- (_1 && _2)(x, y);
-
- // arithmetic assignment
- (_1 += _2)(x, y);
- (_1 -= _2)(x, y);
- (_1 *= _2)(x, y);
- (_1 /= _2)(x, y);
- (_1 %= _2)(x, y);
-
- // bitwise assignment
- (_1 <<= _2)(x, y);
- (_1 >>= _2)(x, y);
- (_1 |= _2)(x, y);
- (_1 &= _2)(x, y);
- (_1 ^= _2)(x, y);
-
- }
-
-
- int test_main(int, char *[]) {
- test_unary_operators();
- test_binary_operators();
- return 0;
- }