⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixed.cpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 CPP
字号:
//[ Mixed/////////////////////////////////////////////////////////////////////////////////  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 an example of using BOOST_PROTO_DEFINE_OPERATORS to proto-ify// expressions using std::vector<> and std::list, non-proto types. It is a port// of the Mixed example from PETE.// (http://www.codesourcery.com/pooma/download.html).#include <list>#include <cmath>#include <vector>#include <complex>#include <iostream>#include <stdexcept>#include <boost/xpressive/proto/proto.hpp>#include <boost/xpressive/proto/debug.hpp>#include <boost/xpressive/proto/context.hpp>#include <boost/xpressive/proto/transform.hpp>#include <boost/typeof/std/list.hpp>#include <boost/typeof/std/vector.hpp>#include <boost/typeof/std/complex.hpp>namespace proto = boost::proto;namespace mpl = boost::mpl;using namespace proto;template<typename Expr>struct MixedExpr;template<typename Iter>struct iterator_wrapper{    explicit iterator_wrapper(Iter iter)      : it(iter)    {}    Iter it;};struct begin : proto::callable{    template<class Sig>    struct result;    template<class This, class Cont>    struct result<This(Cont)>      : proto::result_of::as_expr<            iterator_wrapper<typename boost::remove_reference<Cont>::type::const_iterator>        >    {};    template<typename Cont>    typename result<begin(Cont const &)>::type    operator ()(Cont const &cont) const    {        iterator_wrapper<typename Cont::const_iterator> it(cont.begin());        return proto::as_expr(it);    }};// Here is a grammar that replaces vector and list terminals with their// begin iteratorsstruct Begin  : proto::or_<        when< proto::terminal< std::vector<_, _> >, begin(_arg) >      , when< proto::terminal< std::list<_, _> >, begin(_arg) >      , when< proto::terminal<_> >      , when< proto::nary_expr<_, proto::vararg<Begin> > >    >{};// Here is an evaluation context that dereferences iterator// terminals.struct DereferenceCtx{    // Unless this is an iterator terminal, use the    // default evaluation context    template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>    struct eval      : proto::default_eval<Expr, DereferenceCtx const>    {};    // Dereference iterator terminals.    template<typename Expr, typename Iter>    struct eval<Expr, iterator_wrapper<Iter> >    {        typedef typename std::iterator_traits<Iter>::reference result_type;        result_type operator ()(Expr &expr, DereferenceCtx const &) const        {            return *proto::arg(expr).it;        }    };};// Here is an evaluation context that increments iterator// terminals.struct IncrementCtx{    // Unless this is an iterator terminal, use the    // default evaluation context    template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>    struct eval      : proto::null_eval<Expr, IncrementCtx const>    {};    // advance iterator terminals.    template<typename Expr, typename Iter>    struct eval<Expr, iterator_wrapper<Iter> >    {        typedef void result_type;        result_type operator ()(Expr &expr, IncrementCtx const &) const        {            ++proto::arg(expr).it;        }    };};// A grammar which matches all the assignment operators,// so we can easily disable them.struct AssignOps  : proto::switch_<struct AssignOpsCases>{};// Here are the cases used by the switch_ above.struct AssignOpsCases{    template<typename Tag, int D = 0> struct case_  : proto::not_<_> {};    template<int D> struct case_< proto::tag::plus_assign, D >         : _ {};    template<int D> struct case_< proto::tag::minus_assign, D >        : _ {};    template<int D> struct case_< proto::tag::multiplies_assign, D >   : _ {};    template<int D> struct case_< proto::tag::divides_assign, D >      : _ {};    template<int D> struct case_< proto::tag::modulus_assign, D >      : _ {};    template<int D> struct case_< proto::tag::shift_left_assign, D >   : _ {};    template<int D> struct case_< proto::tag::shift_right_assign, D >  : _ {};    template<int D> struct case_< proto::tag::bitwise_and_assign, D >  : _ {};    template<int D> struct case_< proto::tag::bitwise_or_assign, D >   : _ {};    template<int D> struct case_< proto::tag::bitwise_xor_assign, D >  : _ {};};// A vector grammar is a terminal or some op that is not an// assignment op. (Assignment will be handled specially.)struct MixedGrammar  : proto::or_<        proto::terminal<_>      , proto::and_<            proto::nary_expr<_, proto::vararg<MixedGrammar> >          , proto::not_<AssignOps>        >    >{};// Expressions in the vector domain will be wrapped in VectorExpr<>// and must conform to the VectorGrammarstruct MixedDomain  : proto::domain<proto::generator<MixedExpr>, MixedGrammar>{};// Here is MixedExpr, a wrapper for expression types in the MixedDomain.template<typename Expr>struct MixedExpr  : proto::extends<Expr, MixedExpr<Expr>, MixedDomain>{    explicit MixedExpr(Expr const &expr)      : proto::extends<Expr, MixedExpr<Expr>, MixedDomain>(expr)    {}private:    // hide this:    using proto::extends<Expr, MixedExpr<Expr>, MixedDomain>::operator [];};// Define a trait type for detecting vector and list terminals, to// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.template<typename T>struct IsMixed  : mpl::false_{};template<typename T, typename A>struct IsMixed<std::list<T, A> >  : mpl::true_{};template<typename T, typename A>struct IsMixed<std::vector<T, A> >  : mpl::true_{};namespace MixedOps{    // This defines all the overloads to make expressions involving    // std::vector to build expression templates.    BOOST_PROTO_DEFINE_OPERATORS(IsMixed, MixedDomain)    struct assign_op    {        template<typename T, typename U>        void operator ()(T &t, U const &u) const        {            t = u;        }    };    struct plus_assign_op    {        template<typename T, typename U>        void operator ()(T &t, U const &u) const        {            t += u;        }    };    struct minus_assign_op    {        template<typename T, typename U>        void operator ()(T &t, U const &u) const        {            t -= u;        }    };    struct sin_    {        template<typename Sig>        struct result;        template<typename This, typename Arg>        struct result<This(Arg)>          : boost::remove_const<typename boost::remove_reference<Arg>::type>        {};        template<typename Arg>        Arg operator ()(Arg const &arg) const        {            return std::sin(arg);        }    };    template<typename A>    typename proto::result_of::make_expr<        proto::tag::function      , MixedDomain      , sin_ const      , A const &    >::type sin(A const &a)    {        return proto::make_expr<proto::tag::function, MixedDomain>(sin_(), boost::ref(a));    }    template<typename FwdIter, typename Expr, typename Op>    void evaluate(FwdIter begin, FwdIter end, Expr const &expr, Op op)    {        int i = 0;        IncrementCtx const inc = {};        DereferenceCtx const deref = {};        typename boost::result_of<Begin(Expr, int, int)>::type expr2 = Begin()(expr, i, i);        for(; begin != end; ++begin)        {            op(*begin, proto::eval(expr2, deref));            proto::eval(expr2, inc);        }    }    // Add-assign to a vector from some expression.    template<typename T, typename A, typename Expr>    std::vector<T, A> &assign(std::vector<T, A> &arr, Expr const &expr)    {        evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), assign_op());        return arr;    }    // Add-assign to a list from some expression.    template<typename T, typename A, typename Expr>    std::list<T, A> &assign(std::list<T, A> &arr, Expr const &expr)    {        evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), assign_op());        return arr;    }    // Add-assign to a vector from some expression.    template<typename T, typename A, typename Expr>    std::vector<T, A> &operator +=(std::vector<T, A> &arr, Expr const &expr)    {        evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), plus_assign_op());        return arr;    }    // Add-assign to a list from some expression.    template<typename T, typename A, typename Expr>    std::list<T, A> &operator +=(std::list<T, A> &arr, Expr const &expr)    {        evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), plus_assign_op());        return arr;    }    // Minus-assign to a vector from some expression.    template<typename T, typename A, typename Expr>    std::vector<T, A> &operator -=(std::vector<T, A> &arr, Expr const &expr)    {        evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), minus_assign_op());        return arr;    }    // Minus-assign to a list from some expression.    template<typename T, typename A, typename Expr>    std::list<T, A> &operator -=(std::list<T, A> &arr, Expr const &expr)    {        evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), minus_assign_op());        return arr;    }}int main(){    using namespace MixedOps;    int n = 10;    std::vector<int> a,b,c,d;    std::list<double> e;    std::list<std::complex<double> > f;    int i;    for(i = 0;i < n; ++i)    {        a.push_back(i);        b.push_back(2*i);        c.push_back(3*i);        d.push_back(i);        e.push_back(0.0);        f.push_back(std::complex<double>(1.0, 1.0));    }    MixedOps::assign(b, 2);    MixedOps::assign(d, a + b * c);    a += if_else(d < 30, b, c);    MixedOps::assign(e, c);    e += e - 4 / (c + 1);    f -= sin(0.1 * e * std::complex<double>(0.2, 1.2));    std::list<double>::const_iterator ei = e.begin();    std::list<std::complex<double> >::const_iterator fi = f.begin();    for (i = 0; i < n; ++i)    {        std::cout            << "a(" << i << ") = " << a[i]            << " b(" << i << ") = " << b[i]            << " c(" << i << ") = " << c[i]            << " d(" << i << ") = " << d[i]            << " e(" << i << ") = " << *ei++            << " f(" << i << ") = " << *fi++            << std::endl;    }}//]

⌨️ 快捷键说明

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