📄 closure.hpp
字号:
local(TupleT*& ptr_) : ptr(ptr_) {}
local& operator=(type const& val)
{
get() = val;
return *this;
}
operator type&() const { return boost::tuples::get<N>(*ptr); }
type& get() const
{
assert(ptr);
return boost::tuples::get<N>(*ptr);
}
private:
TupleT*& ptr;
};
///////////////////////////////////////////////////////////////////////////////
//
// closure_member
//
// Variables in a closure (see below) are referred to using closure
// member objects. One may think of a closure as a struct with named
// member variables. Closure members essentially names variables in a
// closure. While members of a struct are accessed using the dot
// notation (e.g. my_struct.mem), variables in a closure are accessed
// via locals (see above, e.g. my_closure(mem), where mem is a closure
// member).
//
// closure_member objects are template classes parameterized by an
// integer that specifies the Nth (zero based) index of the closure
// variable. For instance, closure_member<0> specifies the first closure
// variable, closure_member<1> specifies the second and so forth. For
// example:
//
// closure_member<0> id;
//
// links the name 'id' to the first closure variable (at index 0).
// There are some predefined closure_members m0..m9 available below.
//
///////////////////////////////////////////////////////////////////////////////
template <int N>
struct closure_member {};
closure_member<0> const m0 = closure_member<0>();
closure_member<1> const m1 = closure_member<1>();
closure_member<2> const m2 = closure_member<2>();
closure_member<3> const m3 = closure_member<3>();
closure_member<4> const m4 = closure_member<4>();
closure_member<5> const m5 = closure_member<5>();
closure_member<6> const m6 = closure_member<6>();
closure_member<7> const m7 = closure_member<7>();
closure_member<8> const m8 = closure_member<8>();
closure_member<9> const m9 = closure_member<9>();
///////////////////////////////////////////////////////////////////////////////
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// local_type class { Implementation utilities }
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename TupleT, int N>
struct local_type {
typedef typename
impl::IF<boost::is_same<T, boost::tuples::null_type >::value,
boost::tuples::null_type,
local<TupleT, N> >::RET type;
typedef typename
impl::IF<boost::is_same<T, boost::tuples::null_type >::value,
selector2,
selector1>::RET dispatcher;
static type init_helper(TupleT*& ptr, selector1)
{
return type(ptr);
}
static type init_helper(TupleT*& ptr, selector2)
{
return boost::tuples::null_type();
}
static type init(TupleT*& ptr)
{ return init_helper(ptr, dispatcher()); }
};
} //end namespace impl
///////////////////////////////////////////////////////////////////////////////
//
// closure class
//
// closure provides an environment for local variables to reside. When a
// parser is enclosed in a closure, the closure's local variables are
// created prior to entering the parse function and destructed after
// exiting the parse function.
//
// A closure has a maximum capacity of 10 variables, which should be
// sufficient in most cases (if not, multiple closures can be cascaded).
// Each of these closure variables may be accessed at run time while the
// parsing traversal proceeds. A closure can hold heterogeneous types.
// Here are some examples:
//
// closure<int> c1; // closure with a single variable.
// closure<int, string> c2; // closure with two variables.
// closure<int, my_class> c3; // closure with my_class.
// closure<vector<int> > c4; // closure with a vector of ints.
//
// Any type, class, or struct may be placed in a closure. The only
// restriction is that variables in a closure must have a default
// constructor.
//
// After a closure has been created, it may now be attached to a parser
// using the construct:
//
// c[p]
//
// where c is a closure and p is a parser. This creates a closure_parser
// object (see above). The closure_parser class handles the actual
// creation of stack variables prior to parsing and the consequent
// destruction of the created stack variables after parsing.
//
// Individual closure variables may be accessed using the construct:
//
// c(mem)
//
// where c is a closure and mem is a closure_member (see closure member
// class above). This returns a reference_wrapper (see action.hpp) to a
// local object (see local class above) in the closure that serves as a
// proxy to the actual local variable. Take note that this is merely a
// proxy: the actual local variable has not been created yet at this
// point; in fact, this proxy may point to different instances of the
// local variable at different times. This reference wrapped local object
// may be used as a semantic action.
//
// Trivial example:
//
// closure<char> c; // closure with single char member
// closure_member<0> ch; // closure member referring the char
//
// rule<> r = c[ anychar[c(ch)] ];
//
// When rule r is invoked, the parsed char is stored in the closure
// variable referred to by ch (i.e. the sole (0th) closure member).
//
///////////////////////////////////////////////////////////////////////////////
template <
typename T0, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9
>
class base_closure {
public:
typedef boost::tuples::
tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_t;
typedef impl::local_type<T0, tuple_t, 0> LT0;
typedef impl::local_type<T1, tuple_t, 1> LT1;
typedef impl::local_type<T2, tuple_t, 2> LT2;
typedef impl::local_type<T3, tuple_t, 3> LT3;
typedef impl::local_type<T4, tuple_t, 4> LT4;
typedef impl::local_type<T5, tuple_t, 5> LT5;
typedef impl::local_type<T6, tuple_t, 6> LT6;
typedef impl::local_type<T7, tuple_t, 7> LT7;
typedef impl::local_type<T8, tuple_t, 8> LT8;
typedef impl::local_type<T9, tuple_t, 9> LT9;
typedef typename LT0::type L0; typedef typename LT1::type L1;
typedef typename LT2::type L2; typedef typename LT3::type L3;
typedef typename LT4::type L4; typedef typename LT5::type L5;
typedef typename LT6::type L6; typedef typename LT7::type L7;
typedef typename LT8::type L8; typedef typename LT9::type L9;
typedef boost::tuples::
tuple<L0, L1, L2, L3, L4, L5, L6, L7, L8, L9> local_t;
base_closure();
// IntelV5.0.1 fails to generate correct code, if the following functions
// are not defined inline
template <int N>
reference_wrapper<local<tuple_t, N> >
operator()(closure_member<N>)
{
return reference_wrapper<local<tuple_t, N> >(
boost::tuples::get<N>(locals));
}
template <int N>
typename boost::tuples::element<N, tuple_t>::type const &
get(closure_member<N>) const
{return boost::tuples::get<N>(*ptr); }
template <int N>
typename boost::tuples::element<N, tuple_t>::type &
get(closure_member<N>)
{ return boost::tuples::get<N>(*ptr); }
template <int N>
void
set(closure_member<N>, typename boost::tuples::element<N, tuple_t>::type val) const
{boost::tuples::get<N>(*ptr) = val; }
protected:
mutable tuple_t* ptr;
local_t locals;
};
///////////////////////////////////////////////////////////////////////////////
//
// closure class
//
// This class is splitted into a base_closure and this class to avoid the
// derivation of the closure_parser generating functions to attr_rule<>'s.
//
///////////////////////////////////////////////////////////////////////////////
template <
typename T0, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9
>
class closure :
public base_closure<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>
{
public:
typedef base_closure<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> base_closure_t;
typedef base_closure_t::tuple_t tuple_t;
closure();
// Generate a closure_parser, which automatically wraps a closure around an
// embedded parser and instantiates the closure member tuple on the hardware
// stack for every corresponding parsing context. The closure_parser returns
// the value of the closure_member<0> of the closure as the return value of the
// parsing process.
template <typename S>
closure_parser<tuple_t, S>
operator[](parser<S> const& subject) const
{
// Borland 5.5 reports an internal compiler
// error if this is not defined here.
return closure_parser<tuple_t, S>(ptr, subject.derived());
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace Spirit
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -