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

📄 closure.hpp

📁 著名的Parser库Spirit在VC6上的Port
💻 HPP
📖 第 1 页 / 共 2 页
字号:

                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 + -