Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/xpressive/detail/dynamic/sequence.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/xpressive/detail/dynamic/sequence.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,175 @@ +/////////////////////////////////////////////////////////////////////////////// +// sequence.hpp +// +// Copyright 2008 Eric Niebler. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006 +#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006 + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include <boost/assert.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/xpressive/detail/utility/width.hpp> +#include <boost/xpressive/detail/detail_fwd.hpp> + +namespace boost { namespace xpressive { namespace detail +{ + +/////////////////////////////////////////////////////////////////////////////// +// sequence +template<typename BidiIter> +struct sequence +{ + sequence() + : pure_(true) + , width_(0) + , quant_(quant_none) + , head_() + , tail_(0) + , alt_end_xpr_() + , alternates_(0) + { + } + + template<typename Matcher> + sequence(intrusive_ptr<dynamic_xpression<Matcher, BidiIter> > const &xpr) + : pure_(Matcher::pure) + , width_(xpr->Matcher::get_width()) + , quant_(static_cast<quant_enum>(Matcher::quant)) + , head_(xpr) + , tail_(&xpr->next_) + , alt_end_xpr_() + , alternates_(0) + { + } + + template<typename Traits> + sequence(intrusive_ptr<dynamic_xpression<alternate_matcher<alternates_vector<BidiIter>, Traits>, BidiIter> > const &xpr) + : pure_(true) + , width_(0) + , quant_(quant_none) + , head_(xpr) + , tail_(&xpr->next_) + , alt_end_xpr_() + , alternates_(&xpr->alternates_) + { + } + + bool empty() const + { + return !this->head_; + } + + sequence<BidiIter> &operator +=(sequence<BidiIter> const &that) + { + if(this->empty()) + { + *this = that; + } + else if(!that.empty()) + { + *this->tail_ = that.head_; + this->tail_ = that.tail_; + // keep track of sequence width and purity + this->width_ += that.width_; + this->pure_ = this->pure_ && that.pure_; + this->set_quant_(); + } + return *this; + } + + sequence<BidiIter> &operator |=(sequence<BidiIter> that) + { + BOOST_ASSERT(!this->empty()); + BOOST_ASSERT(0 != this->alternates_); + + // Keep track of width and purity + if(this->alternates_->empty()) + { + this->width_ = that.width_; + this->pure_ = that.pure_; + } + else + { + this->width_ |= that.width_; + this->pure_ = this->pure_ && that.pure_; + } + + // through the wonders of reference counting, all alternates_ can share an end_alternate + if(!this->alt_end_xpr_) + { + this->alt_end_xpr_ = new alt_end_xpr_type; + } + + // terminate each alternate with an alternate_end_matcher + that += sequence(this->alt_end_xpr_); + this->alternates_->push_back(that.head_); + this->set_quant_(); + return *this; + } + + void repeat(quant_spec const &spec) + { + this->xpr().matchable()->repeat(spec, *this); + } + + shared_matchable<BidiIter> const &xpr() const + { + return this->head_; + } + + detail::width width() const + { + return this->width_; + } + + bool pure() const + { + return this->pure_; + } + + quant_enum quant() const + { + return this->quant_; + } + +private: + typedef dynamic_xpression<alternate_end_matcher, BidiIter> alt_end_xpr_type; + + void set_quant_() + { + this->quant_ = (!is_unknown(this->width_) && this->pure_) + ? (!this->width_ ? quant_none : quant_fixed_width) + : quant_variable_width; + } + + bool pure_; + detail::width width_; + quant_enum quant_; + shared_matchable<BidiIter> head_; + shared_matchable<BidiIter> *tail_; + intrusive_ptr<alt_end_xpr_type> alt_end_xpr_; + alternates_vector<BidiIter> *alternates_; +}; + +template<typename BidiIter> +inline sequence<BidiIter> operator +(sequence<BidiIter> left, sequence<BidiIter> const &right) +{ + return left += right; +} + +template<typename BidiIter> +inline sequence<BidiIter> operator |(sequence<BidiIter> left, sequence<BidiIter> const &right) +{ + return left |= right; +} + +}}} // namespace boost::xpressive::detail + +#endif