~ai.tron/armagetronad/0.4-winlibs-updated

« back to all changes in this revision

Viewing changes to boost/includes/boost/xpressive/detail/dynamic/sequence.hpp

  • Committer: Manuel Moos
  • Date: 2013-08-10 16:21:05 UTC
  • mfrom: (118.1.64 winlibs-refactor)
  • Revision ID: z-man@users.sf.net-20130810162105-e6v55tas5si5gb3e
Updating boost to 1.53

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// sequence.hpp
 
3
//
 
4
//  Copyright 2008 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_SEQUENCE_HPP_EAN_04_10_2006
 
9
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006
 
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/assert.hpp>
 
17
#include <boost/intrusive_ptr.hpp>
 
18
#include <boost/xpressive/detail/utility/width.hpp>
 
19
#include <boost/xpressive/detail/detail_fwd.hpp>
 
20
 
 
21
namespace boost { namespace xpressive { namespace detail
 
22
{
 
23
 
 
24
///////////////////////////////////////////////////////////////////////////////
 
25
// sequence
 
26
template<typename BidiIter>
 
27
struct sequence
 
28
{
 
29
    sequence()
 
30
      : pure_(true)
 
31
      , width_(0)
 
32
      , quant_(quant_none)
 
33
      , head_()
 
34
      , tail_(0)
 
35
      , alt_end_xpr_()
 
36
      , alternates_(0)
 
37
    {
 
38
    }
 
39
 
 
40
    template<typename Matcher>
 
41
    sequence(intrusive_ptr<dynamic_xpression<Matcher, BidiIter> > const &xpr)
 
42
      : pure_(Matcher::pure)
 
43
      , width_(xpr->Matcher::get_width())
 
44
      , quant_(static_cast<quant_enum>(Matcher::quant))
 
45
      , head_(xpr)
 
46
      , tail_(&xpr->next_)
 
47
      , alt_end_xpr_()
 
48
      , alternates_(0)
 
49
    {
 
50
    }
 
51
 
 
52
    template<typename Traits>
 
53
    sequence(intrusive_ptr<dynamic_xpression<alternate_matcher<alternates_vector<BidiIter>, Traits>, BidiIter> > const &xpr)
 
54
      : pure_(true)
 
55
      , width_(0)
 
56
      , quant_(quant_none)
 
57
      , head_(xpr)
 
58
      , tail_(&xpr->next_)
 
59
      , alt_end_xpr_()
 
60
      , alternates_(&xpr->alternates_)
 
61
    {
 
62
    }
 
63
 
 
64
    bool empty() const
 
65
    {
 
66
        return !this->head_;
 
67
    }
 
68
 
 
69
    sequence<BidiIter> &operator +=(sequence<BidiIter> const &that)
 
70
    {
 
71
        if(this->empty())
 
72
        {
 
73
            *this = that;
 
74
        }
 
75
        else if(!that.empty())
 
76
        {
 
77
            *this->tail_ = that.head_;
 
78
            this->tail_ = that.tail_;
 
79
            // keep track of sequence width and purity
 
80
            this->width_ += that.width_;
 
81
            this->pure_ = this->pure_ && that.pure_;
 
82
            this->set_quant_();
 
83
        }
 
84
        return *this;
 
85
    }
 
86
 
 
87
    sequence<BidiIter> &operator |=(sequence<BidiIter> that)
 
88
    {
 
89
        BOOST_ASSERT(!this->empty());
 
90
        BOOST_ASSERT(0 != this->alternates_);
 
91
 
 
92
        // Keep track of width and purity
 
93
        if(this->alternates_->empty())
 
94
        {
 
95
            this->width_ = that.width_;
 
96
            this->pure_ = that.pure_;
 
97
        }
 
98
        else
 
99
        {
 
100
            this->width_ |= that.width_;
 
101
            this->pure_ = this->pure_ && that.pure_;
 
102
        }
 
103
 
 
104
        // through the wonders of reference counting, all alternates_ can share an end_alternate
 
105
        if(!this->alt_end_xpr_)
 
106
        {
 
107
            this->alt_end_xpr_ = new alt_end_xpr_type;
 
108
        }
 
109
 
 
110
        // terminate each alternate with an alternate_end_matcher
 
111
        that += sequence(this->alt_end_xpr_);
 
112
        this->alternates_->push_back(that.head_);
 
113
        this->set_quant_();
 
114
        return *this;
 
115
    }
 
116
 
 
117
    void repeat(quant_spec const &spec)
 
118
    {
 
119
        this->xpr().matchable()->repeat(spec, *this);
 
120
    }
 
121
 
 
122
    shared_matchable<BidiIter> const &xpr() const
 
123
    {
 
124
        return this->head_;
 
125
    }
 
126
 
 
127
    detail::width width() const
 
128
    {
 
129
        return this->width_;
 
130
    }
 
131
 
 
132
    bool pure() const
 
133
    {
 
134
        return this->pure_;
 
135
    }
 
136
 
 
137
    quant_enum quant() const
 
138
    {
 
139
        return this->quant_;
 
140
    }
 
141
 
 
142
private:
 
143
    typedef dynamic_xpression<alternate_end_matcher, BidiIter> alt_end_xpr_type;
 
144
 
 
145
    void set_quant_()
 
146
    {
 
147
        this->quant_ = (!is_unknown(this->width_) && this->pure_)
 
148
          ? (!this->width_ ? quant_none : quant_fixed_width)
 
149
          : quant_variable_width;
 
150
    }
 
151
 
 
152
    bool pure_;
 
153
    detail::width width_;
 
154
    quant_enum quant_;
 
155
    shared_matchable<BidiIter> head_;
 
156
    shared_matchable<BidiIter> *tail_;
 
157
    intrusive_ptr<alt_end_xpr_type> alt_end_xpr_;
 
158
    alternates_vector<BidiIter> *alternates_;
 
159
};
 
160
 
 
161
template<typename BidiIter>
 
162
inline sequence<BidiIter> operator +(sequence<BidiIter> left, sequence<BidiIter> const &right)
 
163
{
 
164
    return left += right;
 
165
}
 
166
 
 
167
template<typename BidiIter>
 
168
inline sequence<BidiIter> operator |(sequence<BidiIter> left, sequence<BidiIter> const &right)
 
169
{
 
170
    return left |= right;
 
171
}
 
172
 
 
173
}}} // namespace boost::xpressive::detail
 
174
 
 
175
#endif