📄 sample10.cpp
字号:
/*=============================================================================
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/phoenix/operators.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/composite.hpp>
#include <boost/spirit/phoenix/special_ops.hpp>
#include <boost/spirit/phoenix/statements.hpp>
#include <boost/spirit/phoenix/functions.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 {
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, a
// parent index and a tuple, get the Nth local variable type. The
// parent index is an integer specifying which parent scope to
// access; 0==current scope, 1==parent scope, 2==parent's parent
// scope etc.
//
// This is a metaprogram with partial specializations. There is a
// general case, a special case for local_tuples and a terminating
// special case for local_tuples.
//
// General case: If TupleT is not really a local_tuple, we just return nil_t.
//
// local_tuples case:
// Parent index is 0: We get the Nth local variable.
// Otherwise: We subclass from local_tuples<N, Parent-1, TupleArgsT>
//
///////////////////////////////////////////////////////////////////////////////
template <int N, int Parent, typename TupleT>
struct local_var_result {
typedef nil_t type;
};
//////////////////////////////////
template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
struct local_var_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
: public local_var_result<N, Parent-1, TupleArgsT> {};
//////////////////////////////////
template <int N, typename TupleArgsT, typename TupleLocsT>
struct local_var_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
typedef typename tuple_element<N, TupleLocsT>::type& type;
static type get(local_tuple<TupleArgsT, TupleLocsT> const& tuple)
{ return tuple.locs[tuple_index<N>()]; }
};
///////////////////////////////////////////////////////////////////////////////
//
// 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. Parent specifies the Nth parent scope.
// 0==current scope, 1==parent scope, 2==parent's parent scope etc.
// The member function parent<N>() may be called to provide access
// to outer scopes.
//
// Note that the member function eval expects a local_tuple
// argument. Otherwise there will be acompile-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: lvar1..locN.
//
///////////////////////////////////////////////////////////////////////////////
template <int N, int Parent = 0>
struct local_var {
typedef local_var<N, Parent> self_t;
template <typename TupleT>
struct result {
typedef typename local_var_result<N, Parent, TupleT>::type type;
};
template <typename TupleT>
typename actor_result<self_t, TupleT>::type
eval(TupleT const& tuple) const
{
return local_var_result<N, Parent, TupleT>::get(tuple);
}
template <int PIndex>
actor<local_var<N, Parent+PIndex> >
parent() const
{
return local_var<N, Parent+PIndex>();
}
};
//////////////////////////////////
namespace locals {
actor<local_var<0> > const result = local_var<0>();
actor<local_var<1> > const lvar1 = local_var<1>();
actor<local_var<2> > const lvar2 = local_var<2>();
actor<local_var<3> > const lvar3 = local_var<3>();
actor<local_var<4> > const lvar4 = local_var<4>();
}
///////////////////////////////////////////////////////////////////////////////
template <int N, int Parent, typename TupleT>
struct local_func_result {
typedef nil_t type;
};
//////////////////////////////////
template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
struct local_func_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
: public local_func_result<N, Parent-1, TupleArgsT> {};
//////////////////////////////////
template <int N, typename TupleArgsT, typename TupleLocsT>
struct local_func_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
typedef typename actor_result<
typename tuple_element<N, TupleLocsT>::type,
local_tuple<TupleArgsT, TupleLocsT>
>::type type;
template <typename ArgsT>
static type eval(local_tuple<ArgsT, TupleLocsT> const& tuple)
{ return tuple.locs[tuple_index<N>()].eval(tuple); }
};
template <
int N, int Parent,
typename A0 = nil_t,
typename A1 = nil_t,
typename A2 = nil_t,
typename A3 = nil_t,
typename A4 = nil_t
>
struct local_function_actor;
//////////////////////////////////
template <int N, int Parent>
struct local_function_base {
template <typename TupleT>
struct result {
typedef typename local_func_result<N, Parent, TupleT>::type type;
};
};
//////////////////////////////////
template <int N, int Parent>
struct local_function_actor<N, Parent, nil_t, nil_t, nil_t, nil_t, nil_t>
: public local_function_base<N, Parent> {
template <typename TupleArgsT, typename TupleLocsT>
typename local_func_result<
N, Parent, local_tuple<TupleArgsT, TupleLocsT> >::type
eval(local_tuple<TupleArgsT, TupleLocsT> const& args) const
{
typedef local_tuple<TupleArgsT, TupleLocsT> local_tuple_t;
typedef tuple<> tuple_t;
tuple_t local_args;
local_tuple<tuple_t, TupleLocsT> local_context(local_args, args.locs);
return local_func_result<
N, Parent, local_tuple_t>
::eval(local_context);
}
};
//////////////////////////////////
template <int N, int Parent,
typename A0>
struct local_function_actor<N, Parent, A0, nil_t, nil_t, nil_t, nil_t>
: public local_function_base<N, Parent> {
local_function_actor(
A0 const& _0)
: a0(_0) {}
template <typename TupleArgsT, typename TupleLocsT>
typename local_func_result<
N, Parent, local_tuple<TupleArgsT, TupleLocsT> >::type
eval(local_tuple<TupleArgsT, TupleLocsT> const& args) const
{
typedef local_tuple<TupleArgsT, TupleLocsT> local_tuple_t;
typename actor_result<A0, local_tuple_t>::type r0 = a0.eval(args);
typedef tuple<
typename actor_result<A0, local_tuple_t>::type
> tuple_t;
tuple_t local_args(r0);
local_tuple<tuple_t, TupleLocsT> local_context(local_args, args.locs);
return local_func_result<
N, Parent, local_tuple_t>
::eval(local_context);
}
A0 a0; // actors
};
namespace impl {
template <
int N, int Parent,
typename T0 = nil_t,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -