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