///////////////////////////////////////////////////////////////////////////////
// matchable.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_MATCHABLE_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/xpressive/detail/core/quant_style.hpp>
#include <boost/xpressive/detail/utility/counted_base.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/dynamic/sequence.hpp>
#include <boost/xpressive/regex_error.hpp>

namespace boost { namespace xpressive { namespace detail
{

//////////////////////////////////////////////////////////////////////////
// quant_spec
struct quant_spec
{
    unsigned int min_;
    unsigned int max_;
    bool greedy_;
    std::size_t *hidden_mark_count_;
};

///////////////////////////////////////////////////////////////////////////////
// matchable
template<typename BidiIter>
struct matchable
{
    typedef BidiIter iterator_type;
    typedef typename iterator_value<iterator_type>::type char_type;
    virtual ~matchable() {}
    virtual bool match(match_state<BidiIter> &state) const = 0;
};

///////////////////////////////////////////////////////////////////////////////
// matchable_ex
template<typename BidiIter>
struct matchable_ex
  : matchable<BidiIter>
  , counted_base<matchable_ex<BidiIter> >
{
    typedef BidiIter iterator_type;
    typedef typename iterator_value<iterator_type>::type char_type;

    virtual void link(xpression_linker<char_type> &) const
    {
    }

    virtual void peek(xpression_peeker<char_type> &peeker) const
    {
        peeker.fail();
    }

    virtual void repeat(quant_spec const &, sequence<BidiIter> &) const
    {
        BOOST_THROW_EXCEPTION(
            regex_error(regex_constants::error_badrepeat, "expression cannot be quantified")
        );
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // The following 4 functions (push_match, top_match, pop_match and skip_match) are
    // used to implement looping and branching across the matchers. Call push_match to record
    // a position. Then, another matcher further down the xpression chain has the
    // option to call either top_match, pop_match or skip_match. top_match and pop_match will
    // jump back to the place recorded by push_match, whereas skip_match will skip the jump and
    // pass execution down the xpression chain. top_match will leave the xpression on top of the
    // stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for
    // statically bound xpressions and one for dynamically bound xpressions.
    //

    template<typename Top>
    bool push_match(match_state<BidiIter> &state) const
    {
        BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
        return this->match(state);
    }

    static bool top_match(match_state<BidiIter> &state, void const *top)
    {
        return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
    }

    static bool pop_match(match_state<BidiIter> &state, void const *top)
    {
        return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
    }

    bool skip_match(match_state<BidiIter> &state) const
    {
        return this->match(state);
    }
};

///////////////////////////////////////////////////////////////////////////////
// shared_matchable
template<typename BidiIter>
struct shared_matchable
{
    typedef BidiIter iterator_type;
    typedef typename iterator_value<BidiIter>::type char_type;
    typedef intrusive_ptr<matchable_ex<BidiIter> const> matchable_ptr;

    BOOST_STATIC_CONSTANT(std::size_t, width = unknown_width::value);
    BOOST_STATIC_CONSTANT(bool, pure = false);

    shared_matchable(matchable_ptr const &xpr = matchable_ptr())
      : xpr_(xpr)
    {
    }

    bool operator !() const
    {
        return !this->xpr_;
    }

    friend bool operator ==(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
    {
        return left.xpr_ == right.xpr_;
    }

    friend bool operator !=(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
    {
        return left.xpr_ != right.xpr_;
    }

    matchable_ptr const &matchable() const
    {
        return this->xpr_;
    }

    bool match(match_state<BidiIter> &state) const
    {
        return this->xpr_->match(state);
    }

    void link(xpression_linker<char_type> &linker) const
    {
        this->xpr_->link(linker);
    }

    void peek(xpression_peeker<char_type> &peeker) const
    {
        this->xpr_->peek(peeker);
    }

    // BUGBUG yuk!
    template<typename Top>
    bool push_match(match_state<BidiIter> &state) const
    {
        BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
        return this->match(state);
    }

private:
    matchable_ptr xpr_;
};

}}} // namespace boost::xpressive::detail

#endif
