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 + -
显示快捷键?