Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:50

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // sequence.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // MS compatible compilers support #pragma once
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 // sequence
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             // keep track of sequence width and purity
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         // Keep track of width and purity
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         // through the wonders of reference counting, all alternates_ can share an end_alternate
0105         if(!this->alt_end_xpr_)
0106         {
0107             this->alt_end_xpr_ = new alt_end_xpr_type;
0108         }
0109 
0110         // terminate each alternate with an alternate_end_matcher
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 }}} // namespace boost::xpressive::detail
0174 
0175 #endif