📄 sample10.cpp
字号:
typename T1 = nil_t,
typename T2 = nil_t,
typename T3 = nil_t,
typename T4 = nil_t
>
struct make_local_function_actor {
typedef local_function_actor<
N, Parent,
typename as_actor<T0>::type,
typename as_actor<T1>::type,
typename as_actor<T2>::type,
typename as_actor<T3>::type,
typename as_actor<T4>::type
> composite_type;
typedef actor<composite_type> type;
};
}
template <int N, int Parent = 0>
struct local_function {
actor<local_function_actor<N, Parent> >
operator()() const
{
return local_function_actor<N, Parent>();
}
template <typename T0>
typename impl::make_local_function_actor<N, Parent, T0>::type
operator()(T0 const& _0) const
{
return impl::make_local_function_actor<N, Parent, T0>::composite_type(_0);
}
template <int PIndex>
local_function<N, Parent+PIndex>
parent() const
{
return local_function<N, Parent+PIndex>();
}
};
//////////////////////////////////
namespace locals {
local_function<1> const lfun1 = local_function<1>();
local_function<2> const lfun2 = local_function<2>();
local_function<3> const lfun3 = local_function<3>();
local_function<4> const lfun4 = local_function<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, T4> tuple_t;
return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3, _4));
}
///////////////////////////////////////////////////////////////////////////////
}
//////////////////////////////////
using namespace std;
using namespace phoenix;
using namespace phoenix::locals;
//////////////////////////////////
int
main()
{
int _10 = 10;
#ifndef __BORLANDC__
context<nil_t>
(
1000, // lvar1: local int variable
cout << arg1 << '\n', // lfun2: local function w/ 1 argument (arg1)
lvar1 * 2, // lfun3: local function that accesses local variable lvar1
lfun2(2 * arg1) // lfun4: local function that calls local function lfun2
)
[
lfun2(arg1 + 2000),
lfun2(val(5000) * 2),
lfun2(lvar1 + lfun3()),
lfun4(val(55)),
cout << lvar1 << '\n',
cout << lfun3() << '\n',
cout << val("bye bye\n")
]
(_10);
#else // Borland does not like local variables w/ local functions
// we can have local variables (see sample 7..9) *OR*
// local functions (this: sample 10) but not both
// Sigh... Borland :-{
context<nil_t>
(
12345,
cout << arg1 << '\n'
)
[
lfun2(arg1 + 687),
lfun2(val(9999) * 2),
cout << val("bye bye\n")
]
(_10);
#endif
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -