File indexing completed on 2025-01-18 09:53:50
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006
0009 #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <boost/assert.hpp>
0017 #include <boost/intrusive_ptr.hpp>
0018 #include <boost/xpressive/detail/utility/width.hpp>
0019 #include <boost/xpressive/detail/detail_fwd.hpp>
0020
0021 namespace boost { namespace xpressive { namespace detail
0022 {
0023
0024
0025
0026 template<typename BidiIter>
0027 struct sequence
0028 {
0029 sequence()
0030 : pure_(true)
0031 , width_(0)
0032 , quant_(quant_none)
0033 , head_()
0034 , tail_(0)
0035 , alt_end_xpr_()
0036 , alternates_(0)
0037 {
0038 }
0039
0040 template<typename Matcher>
0041 sequence(intrusive_ptr<dynamic_xpression<Matcher, BidiIter> > const &xpr)
0042 : pure_(Matcher::pure)
0043 , width_(xpr->Matcher::get_width())
0044 , quant_(static_cast<quant_enum>(Matcher::quant))
0045 , head_(xpr)
0046 , tail_(&xpr->next_)
0047 , alt_end_xpr_()
0048 , alternates_(0)
0049 {
0050 }
0051
0052 template<typename Traits>
0053 sequence(intrusive_ptr<dynamic_xpression<alternate_matcher<alternates_vector<BidiIter>, Traits>, BidiIter> > const &xpr)
0054 : pure_(true)
0055 , width_(0)
0056 , quant_(quant_none)
0057 , head_(xpr)
0058 , tail_(&xpr->next_)
0059 , alt_end_xpr_()
0060 , alternates_(&xpr->alternates_)
0061 {
0062 }
0063
0064 bool empty() const
0065 {
0066 return !this->head_;
0067 }
0068
0069 sequence<BidiIter> &operator +=(sequence<BidiIter> const &that)
0070 {
0071 if(this->empty())
0072 {
0073 *this = that;
0074 }
0075 else if(!that.empty())
0076 {
0077 *this->tail_ = that.head_;
0078 this->tail_ = that.tail_;
0079
0080 this->width_ += that.width_;
0081 this->pure_ = this->pure_ && that.pure_;
0082 this->set_quant_();
0083 }
0084 return *this;
0085 }
0086
0087 sequence<BidiIter> &operator |=(sequence<BidiIter> that)
0088 {
0089 BOOST_ASSERT(!this->empty());
0090 BOOST_ASSERT(0 != this->alternates_);
0091
0092
0093 if(this->alternates_->empty())
0094 {
0095 this->width_ = that.width_;
0096 this->pure_ = that.pure_;
0097 }
0098 else
0099 {
0100 this->width_ |= that.width_;
0101 this->pure_ = this->pure_ && that.pure_;
0102 }
0103
0104
0105 if(!this->alt_end_xpr_)
0106 {
0107 this->alt_end_xpr_ = new alt_end_xpr_type;
0108 }
0109
0110
0111 that += sequence(this->alt_end_xpr_);
0112 this->alternates_->push_back(that.head_);
0113 this->set_quant_();
0114 return *this;
0115 }
0116
0117 void repeat(quant_spec const &spec)
0118 {
0119 this->xpr().matchable()->repeat(spec, *this);
0120 }
0121
0122 shared_matchable<BidiIter> const &xpr() const
0123 {
0124 return this->head_;
0125 }
0126
0127 detail::width width() const
0128 {
0129 return this->width_;
0130 }
0131
0132 bool pure() const
0133 {
0134 return this->pure_;
0135 }
0136
0137 quant_enum quant() const
0138 {
0139 return this->quant_;
0140 }
0141
0142 private:
0143 typedef dynamic_xpression<alternate_end_matcher, BidiIter> alt_end_xpr_type;
0144
0145 void set_quant_()
0146 {
0147 this->quant_ = (!is_unknown(this->width_) && this->pure_)
0148 ? (!this->width_ ? quant_none : quant_fixed_width)
0149 : quant_variable_width;
0150 }
0151
0152 bool pure_;
0153 detail::width width_;
0154 quant_enum quant_;
0155 shared_matchable<BidiIter> head_;
0156 shared_matchable<BidiIter> *tail_;
0157 intrusive_ptr<alt_end_xpr_type> alt_end_xpr_;
0158 alternates_vector<BidiIter> *alternates_;
0159 };
0160
0161 template<typename BidiIter>
0162 inline sequence<BidiIter> operator +(sequence<BidiIter> left, sequence<BidiIter> const &right)
0163 {
0164 return left += right;
0165 }
0166
0167 template<typename BidiIter>
0168 inline sequence<BidiIter> operator |(sequence<BidiIter> left, sequence<BidiIter> const &right)
0169 {
0170 return left |= right;
0171 }
0172
0173 }}}
0174
0175 #endif