tarray.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 221 行
CPP
221 行
//[ TArray///////////////////////////////////////////////////////////////////////////////// Copyright 2008 Eric Niebler. 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)//// This example constructs a mini-library for linear algebra, using// expression templates to eliminate the need for temporaries when// adding arrays of numbers. It duplicates the TArray example from// PETE (http://www.codesourcery.com/pooma/download.html)#include <iostream>#include <boost/mpl/int.hpp>#include <boost/xpressive/proto/proto.hpp>#include <boost/xpressive/proto/context.hpp>using namespace boost;// This grammar describes which TArray expressions// are allowed; namely, int and array terminals// plus, minus, multiplies and divides of TArray expressions.struct TArrayGrammar : proto::or_< proto::terminal< int > , proto::terminal< int[3] > , proto::plus< TArrayGrammar, TArrayGrammar > , proto::minus< TArrayGrammar, TArrayGrammar > , proto::multiplies< TArrayGrammar, TArrayGrammar > , proto::divides< TArrayGrammar, TArrayGrammar > >{};template<typename Expr>struct TArrayExpr;// Tell proto that in the TArrayDomain, all// expressions should be wrapped in TArrayExpr<> and// must conform to the TArrayGrammarstruct TArrayDomain : proto::domain<proto::generator<TArrayExpr>, TArrayGrammar>{};// Here is an evaluation context that indexes into a TArray// expression, and combines the result.struct TArraySubscriptCtx : proto::callable_context< TArraySubscriptCtx const >{ typedef int result_type; TArraySubscriptCtx(std::ptrdiff_t i) : i_(i) {} // Index array terminals with our subscript. Everything // else will be handled by the default evaluation context. int operator ()(proto::tag::terminal, int const (&data)[3]) const { return data[this->i_]; } std::ptrdiff_t i_;};// Here is an evaluation context that prints a TArray expression.struct TArrayPrintCtx : proto::callable_context< TArrayPrintCtx const >{ typedef std::ostream &result_type; TArrayPrintCtx() {} std::ostream &operator ()(proto::tag::terminal, int i) const { return std::cout << i; } std::ostream &operator ()(proto::tag::terminal, int const (&arr)[3]) const { return std::cout << '{' << arr[0] << ", " << arr[1] << ", " << arr[2] << '}'; } template<typename L, typename R> std::ostream &operator ()(proto::tag::plus, L const &l, R const &r) const { return std::cout << '(' << l << " + " << r << ')'; } template<typename L, typename R> std::ostream &operator ()(proto::tag::minus, L const &l, R const &r) const { return std::cout << '(' << l << " - " << r << ')'; } template<typename L, typename R> std::ostream &operator ()(proto::tag::multiplies, L const &l, R const &r) const { return std::cout << l << " * " << r; } template<typename L, typename R> std::ostream &operator ()(proto::tag::divides, L const &l, R const &r) const { return std::cout << l << " / " << r; }};// Here is the domain-specific expression wrapper, which overrides// operator [] to evaluate the expression using the TArraySubscriptCtx.template<typename Expr>struct TArrayExpr : proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain>{ typedef proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain> base_type; TArrayExpr( Expr const & expr = Expr() ) : base_type( expr ) {} // Use the TArraySubscriptCtx to implement subscripting // of a TArray expression tree. int operator []( std::ptrdiff_t i ) const { TArraySubscriptCtx const ctx(i); return proto::eval(*this, ctx); } // Use the TArrayPrintCtx to display a TArray expression tree. friend std::ostream &operator <<(std::ostream &sout, TArrayExpr<Expr> const &expr) { TArrayPrintCtx const ctx; return proto::eval(expr, ctx); }};// Here is our TArray terminal, implemented in terms of TArrayExpr// It is basically just an array of 3 integers.struct TArray : TArrayExpr< proto::terminal< int[3] >::type >{ explicit TArray( int i = 0, int j = 0, int k = 0 ) { (*this)[0] = i; (*this)[1] = j; (*this)[2] = k; } // Here we override operator [] to give read/write access to // the elements of the array. (We could use the TArrayExpr // operator [] if we made the subscript context smarter about // returning non-const reference when appropriate.) int &operator [](std::ptrdiff_t i) { return proto::arg(*this)[i]; } int const &operator [](std::ptrdiff_t i) const { return proto::arg(*this)[i]; } // Here we define a operator = for TArray terminals that // takes a TArray expression. template< typename Expr > TArray &operator =(Expr const & expr) { // proto::as_expr<TArrayDomain>(expr) is the same as // expr unless expr is an integer, in which case it // is made into a TArrayExpr terminal first. return this->assign(proto::as_expr<TArrayDomain>(expr)); } template< typename Expr > TArray &printAssign(Expr const & expr) { *this = expr; std::cout << *this << " = " << expr << std::endl; return *this; }private: template< typename Expr > TArray &assign(Expr const & expr) { // expr[i] here uses TArraySubscriptCtx under the covers. (*this)[0] = expr[0]; (*this)[1] = expr[1]; (*this)[2] = expr[2]; return *this; }};int main(){ TArray a(3,1,2); TArray b; std::cout << a << std::endl; std::cout << b << std::endl; b[0] = 7; b[1] = 33; b[2] = -99; TArray c(a); std::cout << c << std::endl; a = 0; std::cout << a << std::endl; std::cout << b << std::endl; std::cout << c << std::endl; a = b + c; std::cout << a << std::endl; a.printAssign(b+c*(b + 3*c)); return 0;}//]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?