vec3.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 175 行

CPP
175
字号
//[ Vec3/////////////////////////////////////////////////////////////////////////////////  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 is a simple example using proto::extends to extend a terminal type with// additional behaviors, and using custom contexts and proto::eval for// evaluating expressions. It is a port of the Vec3 example// from PETE (http://www.codesourcery.com/pooma/download.html).#include <iostream>#include <functional>#include <boost/assert.hpp>#include <boost/mpl/int.hpp>#include <boost/proto/core.hpp>#include <boost/proto/context.hpp>#include <boost/proto/proto_typeof.hpp>#include <boost/proto/transform.hpp>namespace mpl = boost::mpl;namespace proto = boost::proto;using proto::_;// Here is an evaluation context that indexes into a Vec3// expression, and combines the result.struct Vec3SubscriptCtx  : proto::callable_context< Vec3SubscriptCtx const >{    typedef int result_type;    Vec3SubscriptCtx(int 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 (&arr)[3]) const    {        return arr[this->i_];    }    int i_;};// Here is an evaluation context that counts the number// of Vec3 terminals in an expression.struct CountLeavesCtx  : proto::callable_context< CountLeavesCtx, proto::null_context >{    CountLeavesCtx()      : count(0)      {}      typedef void result_type;      void operator ()(proto::tag::terminal, int const(&)[3])      {          ++this->count;      }      int count;};struct iplus : std::plus<int>, proto::callable {};// Here is a transform that does the same thing as the above context.// It demonstrates the use of the std::plus<> function object// with the fold transform. With minor modifications, this// transform could be used to calculate the leaf count at compile// time, rather than at runtime.struct CountLeaves  : proto::or_<        // match a Vec3 terminal, return 1        proto::when<proto::terminal<int[3]>, mpl::int_<1>() >        // match a terminal, return int() (which is 0)      , proto::when<proto::terminal<_>, int() >        // fold everything else, using std::plus<> to add        // the leaf count of each child to the accumulated state.      , proto::otherwise< proto::fold<_, int(), iplus(CountLeaves, proto::_state) > >    >{};// Here is the Vec3 struct, which is a vector of 3 integers.struct Vec3  : proto::extends<proto::terminal<int[3]>::type, Vec3>{    explicit Vec3(int i=0, int j=0, int k=0)    {        (*this)[0] = i;        (*this)[1] = j;        (*this)[2] = k;    }    int &operator [](int i)    {        return proto::value(*this)[i];    }    int const &operator [](int i) const    {        return proto::value(*this)[i];    }    // Here we define a operator = for Vec3 terminals that    // takes a Vec3 expression.    template< typename Expr >    Vec3 &operator =(Expr const & expr)    {        typedef Vec3SubscriptCtx const CVec3SubscriptCtx;        (*this)[0] = proto::eval(proto::as_expr(expr), CVec3SubscriptCtx(0));        (*this)[1] = proto::eval(proto::as_expr(expr), CVec3SubscriptCtx(1));        (*this)[2] = proto::eval(proto::as_expr(expr), CVec3SubscriptCtx(2));        return *this;    }    void print() const    {        std::cout << '{' << (*this)[0]                  << ", " << (*this)[1]                  << ", " << (*this)[2]                  << '}' << std::endl;    }};// The count_leaves() function uses the CountLeaves transform and// to count the number of leaves in an expression.template<typename Expr>int count_leaves(Expr const &expr){    // Count the number of Vec3 terminals using the    // CountLeavesCtx evaluation context.    CountLeavesCtx ctx;    proto::eval(expr, ctx);    // This is another way to count the leaves using a transform.    int i = 0;    BOOST_ASSERT( CountLeaves()(expr, i, i) == ctx.count );    return ctx.count;}int main(){    Vec3 a, b, c;    c = 4;    b[0] = -1;    b[1] = -2;    b[2] = -3;    a = b + c;    a.print();    Vec3 d;    BOOST_PROTO_AUTO(expr1, b + c);    d = expr1;    d.print();    int num = count_leaves(expr1);    std::cout << num << std::endl;    BOOST_PROTO_AUTO(expr2, b + 3 * c);    num = count_leaves(expr2);    std::cout << num << std::endl;    BOOST_PROTO_AUTO(expr3, b + c * d);    num = count_leaves(expr3);    std::cout << num << std::endl;    return 0;}//]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?