Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/xpressive/detail/dynamic/matchable.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: 4.5 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2// matchable.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_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
9#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_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 <utility>
17#include <boost/assert.hpp>
18#include <boost/shared_ptr.hpp>
19#include <boost/mpl/assert.hpp>
20#include <boost/type_traits/is_same.hpp>
21#include <boost/xpressive/detail/core/state.hpp>
22#include <boost/xpressive/detail/core/quant_style.hpp>
23#include <boost/xpressive/regex_error.hpp>
24
25namespace boost { namespace xpressive { namespace detail
26{
27
28template<typename BidiIter>
29struct matchable;
30
31///////////////////////////////////////////////////////////////////////////////
32// sequence
33//
34template<typename BidiIter>
35struct sequence
36  : std::pair
37    <
38        shared_ptr<matchable<BidiIter> const>
39      , shared_ptr<matchable<BidiIter> const> *
40    >
41{
42    typedef shared_ptr<matchable<BidiIter> const> matchable_ptr_t;
43    typedef std::pair<matchable_ptr_t, matchable_ptr_t *> base_t;
44
45    explicit sequence(matchable_ptr_t head = matchable_ptr_t(), matchable_ptr_t *tail_ptr = 0)
46      : base_t(head, tail_ptr)
47    {
48    }
49
50    bool is_empty() const
51    {
52        return !this->first;
53    }
54
55    sequence &operator +=(sequence that)
56    {
57        if(is_empty())
58        {
59            *this = that;
60        }
61        else if(!that.is_empty())
62        {
63            *this->second = that.first;
64            this->second = that.second;
65        }
66        return *this;
67    }
68};
69
70//////////////////////////////////////////////////////////////////////////
71// quant_spec
72//
73struct quant_spec
74{
75    unsigned int min_;
76    unsigned int max_;
77    bool greedy_;
78};
79
80///////////////////////////////////////////////////////////////////////////////
81// matchable
82//
83template<typename BidiIter>
84struct matchable
85  : xpression_base
86{
87    typedef typename iterator_value<BidiIter>::type char_type;
88
89    virtual ~matchable() {}
90
91    virtual bool match(state_type<BidiIter> &state) const = 0;
92
93    virtual std::size_t get_width(state_type<BidiIter> *state) const = 0;
94
95    virtual void link(xpression_linker<char_type> &) const {}
96
97    virtual void peek(xpression_peeker<char_type> &peeker) const
98    {
99        peeker.fail();
100    }
101
102    virtual sequence<BidiIter> quantify
103    (
104        quant_spec const & //spec
105      , std::size_t & //hidden_mark_count
106      , sequence<BidiIter> //seq
107      , alternates_factory<BidiIter> const &//factory
108    ) const
109    {
110        throw regex_error(regex_constants::error_badrepeat, "expression cannot be quantified");
111    }
112
113    virtual bool is_quantifiable() const
114    {
115        BOOST_ASSERT(false);
116        throw regex_error(regex_constants::error_internal, "internal error, sorry!");
117    }
118
119    ///////////////////////////////////////////////////////////////////////////////////////////////
120    // The following 4 functions (push_match, top_match, pop_match and skip_match) are
121    // used to implement looping and branching across the matchers. Call push_match to record
122    // a position. Then, another matcher further down the xpression chain has the
123    // option to call either top_match, pop_match or skip_match. top_match and pop_match will
124    // jump back to the place recorded by push_match, whereas skip_match will skip the jump and
125    // pass execution down the xpression chain. top_match will leave the xpression on top of the
126    // stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for
127    // statically bound xpressions and one for dynamically bound xpressions.
128    //
129
130    template<typename Top>
131    bool push_match(state_type<BidiIter> &state) const
132    {
133        BOOST_MPL_ASSERT((is_same<Top, matchable<BidiIter> >));
134        return this->match(state);
135    }
136
137    static bool top_match(state_type<BidiIter> &state, xpression_base const *top)
138    {
139        return static_cast<matchable<BidiIter> const *>(top)->match(state);
140    }
141
142    static bool pop_match(state_type<BidiIter> &state, xpression_base const *top)
143    {
144        return static_cast<matchable<BidiIter> const *>(top)->match(state);
145    }
146
147    bool skip_match(state_type<BidiIter> &state) const
148    {
149        return this->match(state);
150    }
151};
152
153}}} // namespace boost::xpressive::detail
154
155#endif
Note: See TracBrowser for help on using the repository browser.