Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/xpressive/detail/static/static.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 8.5 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2// static.hpp
3//
4//  Copyright 2004 Eric Niebler. Distributed under the Boost
5//  Software License, Version 1.0. (See accompanying file
6//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005
9#define BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005
10
11// MS compatible compilers support #pragma once
12#if defined(_MSC_VER) && (_MSC_VER >= 1020)
13# pragma once
14#endif
15
16#include <boost/mpl/assert.hpp>
17#include <boost/xpressive/detail/detail_fwd.hpp>
18#include <boost/xpressive/detail/core/state.hpp>
19#include <boost/xpressive/detail/core/linker.hpp>
20#include <boost/xpressive/detail/core/peeker.hpp>
21
22// Random thoughts:
23// - must support indirect repeat counts {$n,$m}
24// - add ws to eat whitespace (make *ws illegal)
25// - a{n,m}    -> repeat<n,m>(a)
26// - a{$n,$m}  -> repeat(n,m)(a)
27// - add nil to match nothing
28// - instead of s1, s2, etc., how about s[1], s[2], etc.? Needlessly verbose?
29
30namespace boost { namespace xpressive { namespace detail
31{
32
33#ifdef BOOST_XPR_DEBUG_STACK
34///////////////////////////////////////////////////////////////////////////////
35// top_type
36//
37template<typename Top>
38struct top_type
39{
40    typedef Top type;
41};
42
43///////////////////////////////////////////////////////////////////////////////
44// top_type
45//
46template<typename Top, typename Next>
47struct top_type<stacked_xpression<Top, Next> >
48{
49    typedef Next type;
50};
51#endif
52
53///////////////////////////////////////////////////////////////////////////////
54// stacked_xpression
55//
56template<typename Top, typename Next>
57struct stacked_xpression
58  : Next
59{
60    // match
61    //  delegates to Next
62    template<typename BidiIter>
63    bool match(state_type<BidiIter> &state) const
64    {
65        return static_cast<Next const *>(this)->
66            BOOST_NESTED_TEMPLATE push_match<Top>(state);
67    }
68
69    // top_match
70    //   jump back to the xpression on top of the xpression stack,
71    //   and keep the xpression on the stack.
72    template<typename BidiIter>
73    static bool top_match(state_type<BidiIter> &state, xpression_base const *top)
74    {
75        BOOST_XPR_DEBUG_STACK_ASSERT(typeid(*top) == typeid(typename top_type<Top>::type));
76        return static_cast<Top const *>(top)->
77            BOOST_NESTED_TEMPLATE push_match<Top>(state);
78    }
79
80    // pop_match
81    //   jump back to the xpression on top of the xpression stack,
82    //   pop the xpression off the stack.
83    template<typename BidiIter>
84    static bool pop_match(state_type<BidiIter> &state, xpression_base const *top)
85    {
86        BOOST_XPR_DEBUG_STACK_ASSERT(typeid(*top) == typeid(typename top_type<Top>::type));
87        return static_cast<Top const *>(top)->match(state);
88    }
89
90    // skip_match
91    //   pop the xpression off the top of the stack and ignore it; call
92    //   match on next.
93    template<typename BidiIter>
94    bool skip_match(state_type<BidiIter> &state) const
95    {
96        // could be static_xpression::skip_impl or stacked_xpression::skip_impl
97        // depending on if there is 1 or more than 1 xpression on the
98        // xpression stack
99        return Top::skip_impl(*static_cast<Next const *>(this), state);
100    }
101
102//protected:
103
104    // skip_impl
105    //   implementation of skip_match.
106    template<typename That, typename BidiIter>
107    static bool skip_impl(That const &that, state_type<BidiIter> &state)
108    {
109        return that.BOOST_NESTED_TEMPLATE push_match<Top>(state);
110    }
111};
112
113///////////////////////////////////////////////////////////////////////////////
114// stacked_xpression_cast
115//
116template<typename Top, typename Next>
117inline stacked_xpression<Top, Next> const &stacked_xpression_cast(Next const &next)
118{
119    // NOTE: this is a little white lie. The "next" object doesn't really have
120    // the type to which we're casting it. It is harmless, though. We are only using
121    // the cast to decorate the next object with type information. It is done
122    // this way to save stack space.
123    BOOST_MPL_ASSERT_RELATION(sizeof(stacked_xpression<Top, Next>), ==, sizeof(Next));
124    return *static_cast<stacked_xpression<Top, Next> const *>(&next);
125}
126
127///////////////////////////////////////////////////////////////////////////////
128// static_xpression
129//
130template<typename Matcher, typename Next>
131struct static_xpression
132  : Matcher
133{
134    Next next_;
135
136    static_xpression(Matcher const &matcher = Matcher(), Next const &next = Next())
137      : Matcher(matcher)
138      , next_(next)
139    {
140    }
141
142    // match
143    //  delegates to the Matcher
144    template<typename BidiIter>
145    bool match(state_type<BidiIter> &state) const
146    {
147        return this->Matcher::match(state, this->next_);
148    }
149
150    // push_match
151    //   call match on this, but also push "Top" onto the xpression
152    //   stack so we know what we are jumping back to later.
153    template<typename Top, typename BidiIter>
154    bool push_match(state_type<BidiIter> &state) const
155    {
156        return this->Matcher::match(state, stacked_xpression_cast<Top>(this->next_));
157    }
158
159    // skip_impl
160    //   implementation of skip_match, called from stacked_xpression::skip_match
161    template<typename That, typename BidiIter>
162    static bool skip_impl(That const &that, state_type<BidiIter> &state)
163    {
164        return that.match(state);
165    }
166
167    // for linking a compiled regular xpression
168    template<typename Char>
169    void link(xpression_linker<Char> &linker) const
170    {
171        linker.link(*static_cast<Matcher const *>(this), &this->next_);
172        this->next_.link(linker);
173    }
174
175    // for building a lead-follow
176    template<typename Char>
177    void peek(xpression_peeker<Char> &peeker) const
178    {
179        this->peek_next_(peeker.peek(*static_cast<Matcher const *>(this)), peeker);
180    }
181
182    // for getting xpression width
183    template<typename BidiIter>
184    std::size_t get_width(state_type<BidiIter> *state) const
185    {
186        // BUGBUG this gets called from the simple_repeat_matcher::match(), so this is slow.
187        // or will the compiler be able to optimize this all away?
188        std::size_t this_width = this->Matcher::get_width(state);
189        if(this_width == unknown_width())
190            return unknown_width();
191        std::size_t that_width = this->next_.get_width(state);
192        if(that_width == unknown_width())
193            return unknown_width();
194        return this_width + that_width;
195    }
196
197private: // hide this
198
199    static_xpression &operator =(static_xpression const &);
200
201    template<typename Char>
202    void peek_next_(mpl::true_, xpression_peeker<Char> &peeker) const
203    {
204        this->next_.peek(peeker);
205    }
206
207    template<typename Char>
208    static void peek_next_(mpl::false_, xpression_peeker<Char> &)
209    {
210        // no-op
211    }
212
213    using Matcher::width;
214    using Matcher::pure;
215};
216
217// syntactic sugar so this xpression can be treated the same as
218// (a smart pointer to) a dynamic xpression from templates
219template<typename Matcher, typename Next>
220inline static_xpression<Matcher, Next> const *
221get_pointer(static_xpression<Matcher, Next> const &xpr)
222{
223    return &xpr;
224}
225
226///////////////////////////////////////////////////////////////////////////////
227// make_static_xpression
228//
229template<typename Matcher>
230inline static_xpression<Matcher> const
231make_static_xpression(Matcher const &matcher)
232{
233    return static_xpression<Matcher>(matcher);
234}
235
236template<typename Matcher, typename Next>
237inline static_xpression<Matcher, Next> const
238make_static_xpression(Matcher const &matcher, Next const &next)
239{
240    return static_xpression<Matcher, Next>(matcher, next);
241}
242
243///////////////////////////////////////////////////////////////////////////////
244// no_next
245//
246struct no_next
247  : xpression_base
248{
249    template<typename Char>
250    void link(xpression_linker<Char> &) const
251    {
252    }
253
254    template<typename Char>
255    void peek(xpression_peeker<Char> &peeker) const
256    {
257        peeker.fail();
258    }
259
260    template<typename BidiIter>
261    static std::size_t get_width(state_type<BidiIter> *)
262    {
263        return 0;
264    }
265};
266
267///////////////////////////////////////////////////////////////////////////////
268// alternates_list
269//
270template<typename Alternates>
271struct alternates_list
272  : Alternates
273{
274    alternates_list(Alternates const &alternates)
275      : Alternates(alternates)
276    {
277    }
278private:
279    alternates_list &operator =(alternates_list const &);
280};
281
282///////////////////////////////////////////////////////////////////////////////
283// get_mark_number
284//
285inline int get_mark_number(mark_tag const &mark)
286{
287    return proto::arg(mark).mark_number_;
288}
289
290}}} // namespace boost::xpressive::detail
291
292#endif
Note: See TracBrowser for help on using the repository browser.