extending_rt_traits.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 385 行
CPP
385 行
// 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 <iostream>#include <functional>#include <algorithm>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/decrtemplate<class Act>struct plain_return_type_1<post_increment_decrement_action<Act>, A > { typedef B type;}; // pre incr/decrtemplate<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} // boostvoid 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 versionsYY 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 assignmentZ 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 assignmentZ 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(); }// assignmentclass Assign {public: void operator=(const Assign& a) {} X operator[](const int& i) { return X(); }};namespace boost {namespace lambda { // you can do action groupstemplate<class Act> struct plain_return_type_2<arithmetic_action<Act>, X, Y> { typedef Z type;}; // or specialize the exact actiontemplate<> 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 groupstemplate<class Act> struct plain_return_type_2<bitwise_action<Act>, X, Y> { typedef Z type;}; // or specialize the exact actiontemplate<> struct plain_return_type_2<bitwise_action<leftshift_action>, X, Y> { typedef X type;}; // comparison binary: // you can do action groupstemplate<class Act> struct plain_return_type_2<relational_action<Act>, X, Y> { typedef Z type;}; // or specialize the exact actiontemplate<> struct plain_return_type_2<relational_action<less_action>, X, Y> { typedef X type;}; // logical binary: // you can do action groupstemplate<class Act> struct plain_return_type_2<logical_action<Act>, X, Y> { typedef Z type;}; // or specialize the exact actiontemplate<> struct plain_return_type_2<logical_action<and_action>, X, Y> { typedef X type;}; // arithmetic assignment : // you can do action groupstemplate<class Act> struct plain_return_type_2<arithmetic_assignment_action<Act>, X, Y> { typedef Z type;}; // or specialize the exact actiontemplate<> struct plain_return_type_2<arithmetic_assignment_action<multiply_action>, X, Y> { typedef Y type;}; // arithmetic assignment : // you can do action groupstemplate<class Act> struct plain_return_type_2<bitwise_assignment_action<Act>, X, Y> { typedef Z type;}; // or specialize the exact actiontemplate<> struct plain_return_type_2<bitwise_assignment_action<and_action>, X, Y> { typedef Y type;}; // assignmenttemplate<> struct plain_return_type_2<other_action<assignment_action>, Assign, Assign> { typedef void type;}; // subscripttemplate<> struct plain_return_type_2<other_action<subscript_action>, Assign, int> { typedef X type;};} // end lambda} // end boostvoid 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); my_vector<int> v1; my_vector<double> v2; my_vector<double> d = (_1 + _2)(v1, v2); // 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;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?