///////////////////////////////////////////////////////////////////////////////
// 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
