sample8.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 285 行
CPP
285 行
/*============================================================================= Phoenix V1.2.1 Copyright (c) 2001-2003 Joel de Guzman Use, modification and distribution is subject to 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)==============================================================================*/#include <vector>#include <algorithm>#include <iostream>#define PHOENIX_LIMIT 5#include <boost/spirit/include/phoenix1_operators.hpp>#include <boost/spirit/include/phoenix1_primitives.hpp>#include <boost/spirit/include/phoenix1_composite.hpp>#include <boost/spirit/include/phoenix1_special_ops.hpp>#include <boost/spirit/include/phoenix1_statements.hpp>namespace phoenix {/////////////////////////////////////////////////////////////////////////////////// local_tuple//// This *is a* tuple like the one we see in TupleT in any actor// base class' eval member function. local_tuple should look and// feel the same as a tupled-args, that's why it is derived from// TupleArgsT. It has an added member, locs which is another tuple// where the local variables will be stored. locs is mutable to// allow read-write access to our locals regardless of// local_tuple's constness (The eval member function accepts it as// a const argument)./////////////////////////////////////////////////////////////////////////////////template <typename TupleArgsT, typename TupleLocsT>struct local_tuple : public TupleArgsT { typedef TupleLocsT local_vars_t; local_tuple(TupleArgsT const& args, TupleLocsT const& locs_) : TupleArgsT(args), locs(locs_) {} mutable TupleLocsT locs;};/////////////////////////////////////////////////////////////////////////////////// local_var_result//// This is a return type computer. Given a constant integer N and a// tuple, get the Nth local variable type. If TupleT is not really// a local_tuple, we just return nil_t. Otherwise we get the Nth// local variable type./////////////////////////////////////////////////////////////////////////////////template <int N, typename TupleT>struct local_var_result { typedef nil_t type;};//////////////////////////////////template <int N, typename TupleArgsT, typename TupleLocsT>struct local_var_result<N, local_tuple<TupleArgsT, TupleLocsT> > { typedef typename tuple_element<N, TupleLocsT>::type& type;};/////////////////////////////////////////////////////////////////////////////////// local_var//// This class looks so curiously like the argument class. local_var// provides access to the Nth local variable packed in the tuple// duo local_tuple above. Note that the member function eval// expects a local_tuple argument. Otherwise the expression// 'tuple.locs' will fail (compile-time error). local_var// primitives only work within the context of a context_composite// (see below).//// Provided are some predefined local_var actors for 0..N local// variable access: loc1..locN./////////////////////////////////////////////////////////////////////////////////template <int N>struct local_var { template <typename TupleT> struct result { typedef typename local_var_result<N, TupleT>::type type; }; template <typename TupleT> typename local_var_result<N, TupleT>::type eval(TupleT const& tuple) const { return tuple.locs[tuple_index<N>()]; }};//////////////////////////////////namespace locals { actor<local_var<0> > const result = local_var<0>(); actor<local_var<1> > const loc1 = local_var<1>(); actor<local_var<2> > const loc2 = local_var<2>(); actor<local_var<3> > const loc3 = local_var<3>(); actor<local_var<4> > const loc4 = local_var<4>();}/////////////////////////////////////////////////////////////////////////////////// context_composite//// This class encapsulates an actor and some local variable// initializers packed in a tuple.//// context_composite is just like a proxy and delegates the actual// evaluation to the actor. The actor does the actual work. In the// eval member function, before invoking the embedded actor's eval// member function, we first stuff an instance of our locals and// bundle both 'args' and 'locals' in a local_tuple. This// local_tuple instance is created in the stack initializing it// with our locals member. We then pass this local_tuple instance// as an argument to the actor's eval member function./////////////////////////////////////////////////////////////////////////////////template <typename ActorT, typename LocsT>struct context_composite { typedef context_composite<ActorT, LocsT> self_t; template <typename TupleT> struct result { typedef typename tuple_element<0, LocsT>::type type; }; context_composite(ActorT const& actor_, LocsT const& locals_) : actor(actor_), locals(locals_) {} template <typename TupleT> typename tuple_element<0, LocsT>::type eval(TupleT const& args) const { local_tuple<TupleT, LocsT> local_context(args, locals); actor.eval(local_context); return local_context.locs[tuple_index<0>()]; } ActorT actor; LocsT locals;};/////////////////////////////////////////////////////////////////////////////////// context_gen//// At construction time, this class is given some local var-// initializers packed in a tuple. We just store this for later.// The operator[] of this class creates the actual context_composite// given an actor. This is responsible for the construct// context<types>[actor]./////////////////////////////////////////////////////////////////////////////////template <typename LocsT>struct context_gen { context_gen(LocsT const& locals_) : locals(locals_) {} template <typename ActorT> actor<context_composite<typename as_actor<ActorT>::type, LocsT> > operator[](ActorT const& actor) { return context_composite<typename as_actor<ActorT>::type, LocsT> (as_actor<ActorT>::convert(actor), locals); } LocsT locals;};/////////////////////////////////////////////////////////////////////////////////// Front end generator functions. These generators are overloaded for// 1..N local variables. context<T0,... TN>(i0,...iN) generate context_gen// objects (see above)./////////////////////////////////////////////////////////////////////////////////template <typename T0>inline context_gen<tuple<T0> >context(){ typedef tuple<T0> tuple_t; return context_gen<tuple_t>(tuple_t(T0()));}//////////////////////////////////template <typename T0, typename T1>inline context_gen<tuple<T0, T1> >context( T1 const& _1 = T1()){ typedef tuple<T0, T1> tuple_t; return context_gen<tuple_t>(tuple_t(T0(), _1));}//////////////////////////////////template <typename T0, typename T1, typename T2>inline context_gen<tuple<T0, T1, T2> >context( T1 const& _1 = T1(), T2 const& _2 = T2()){ typedef tuple<T0, T1, T2> tuple_t; return context_gen<tuple_t>(tuple_t(T0(), _1, _2));}//////////////////////////////////template <typename T0, typename T1, typename T2, typename T3>inline context_gen<tuple<T0, T1, T2, T3> >context( T1 const& _1 = T1(), T2 const& _2 = T2(), T3 const& _3 = T3()){ typedef tuple<T0, T1, T2, T3> tuple_t; return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3));}//////////////////////////////////template <typename T0, typename T1, typename T2, typename T3, typename T4>inline context_gen<tuple<T0, T1, T2, T3, T4> >context( T1 const& _1 = T1(), T2 const& _2 = T2(), T3 const& _3 = T3(), T4 const& _4 = T4()){ typedef tuple<T0, T1, T2, T3> tuple_t; return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3, _4));}///////////////////////////////////////////////////////////////////////////////}//////////////////////////////////using namespace std;using namespace phoenix;using namespace phoenix::locals;//////////////////////////////////intmain(){ int init[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; vector<int> c(init, init + 10); typedef vector<int>::iterator iterator; // find the first element > 5, print each element // as we traverse the container c. Print the result // if one is found. find_if(c.begin(), c.end(), context<bool>() [ cout << arg1, result = arg1 > 5, if_(!result) [ cout << val(", ") ] .else_ [ cout << val(" found result == ") << arg1 ] ] ); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?