///////////////////////////////////////////////////////////////////////////////
/// \file match_results.hpp
/// Contains the definition of the match_results type and associated helpers.
/// The match_results type holds the results of a regex_match() or
/// regex_search() operation.
//
//  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)
//
// Acknowledgements: Thanks to Markus Schoepflin for helping to track down
// a tricky formatting bug on HP Tru64, and to Steven Watanabe for suggesting
// the fix.

#ifndef BOOST_XPRESSIVE_MATCH_RESULTS_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_MATCH_RESULTS_HPP_EAN_10_04_2005

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

#include <map>
#include <string>
#include <vector>
#include <utility>
#include <iterator>
#include <typeinfo>
#include <algorithm>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/integer.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/optional.hpp>
#include <boost/range/end.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/type_traits/is_function.hpp>
#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
# include <boost/iterator/filter_iterator.hpp>
#endif
#include <boost/xpressive/regex_constants.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/core/regex_impl.hpp>
#include <boost/xpressive/detail/core/sub_match_vector.hpp>
#include <boost/xpressive/detail/utility/sequence_stack.hpp>
#include <boost/xpressive/detail/core/results_cache.hpp>
#include <boost/xpressive/detail/utility/literals.hpp>
#include <boost/xpressive/detail/utility/algorithm.hpp>
#include <boost/xpressive/detail/utility/counted_base.hpp>
// Doxygen can't handle proto :-(
#ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
# include <boost/proto/proto_fwd.hpp>
# include <boost/proto/traits.hpp>
# include <boost/proto/eval.hpp>
#endif

namespace boost { namespace xpressive { namespace detail
{

///////////////////////////////////////////////////////////////////////////////
// type_info_less
//
struct type_info_less
{
    bool operator()(std::type_info const *left, std::type_info const *right) const
    {
        return 0 != left->before(*right);
    }
};

///////////////////////////////////////////////////////////////////////////////
// ActionArgBinding
//
struct ActionArgBinding
  : proto::assign<proto::terminal<action_arg<proto::_, proto::_> >, proto::terminal<proto::_> >
{
};

///////////////////////////////////////////////////////////////////////////////
// results_extras
//
template<typename BidiIter>
struct results_extras
  : counted_base<results_extras<BidiIter> >
{
    sequence_stack<sub_match_impl<BidiIter> > sub_match_stack_;
    results_cache<BidiIter> results_cache_;
};

///////////////////////////////////////////////////////////////////////////////
// char_overflow_handler_
//
struct char_overflow_handler_
{
    void operator ()(numeric::range_check_result result) const // throw(regex_error)
    {
        if(numeric::cInRange != result)
        {
            BOOST_THROW_EXCEPTION(
                regex_error(
                    regex_constants::error_escape
                  , "character escape too large to fit in target character type"
                )
            );
        }
    }
};

///////////////////////////////////////////////////////////////////////////////
// transform_op enum
//
enum transform_op { None = 0, Upper = 1, Lower = 2 };
enum transform_scope { Next = 0, Rest = 1 };

///////////////////////////////////////////////////////////////////////////////
// case_converting_iterator
//
template<typename OutputIterator, typename Char>
struct case_converting_iterator
  : std::iterator<std::output_iterator_tag, Char, void, void, case_converting_iterator<OutputIterator, Char> >
{
    case_converting_iterator(OutputIterator const &out, traits<Char> const *tr)
      : out_(out)
      , traits_(tr)
      , next_(None)
      , rest_(None)
    {}

    OutputIterator base() const
    {
        return this->out_;
    }

    case_converting_iterator &operator ++()
    {
        ++this->out_;
        this->next_ = None;
        return *this;
    }

    case_converting_iterator operator ++(int)
    {
        case_converting_iterator tmp(*this);
        ++*this;
        return tmp;
    }

    case_converting_iterator &operator *()
    {
        return *this;
    }

    friend bool set_transform(case_converting_iterator &iter, transform_op trans, transform_scope scope)
    {
        BOOST_ASSERT(scope == Next || scope == Rest);
        if(scope == Next)
            iter.next_ = trans;
        else
            iter.rest_ = trans;
        return true;
    }

    case_converting_iterator &operator =(Char ch)
    {
        switch(this->next_ ? this->next_ : this->rest_)
        {
        case Lower:
            ch = this->traits_->tolower(ch);
            break;

        case Upper:
            ch = this->traits_->toupper(ch);
            break;

        default:;
        }

        *this->out_ = ch;
        return *this;
    }

private:
    OutputIterator out_;
    traits<Char> const *traits_;
    transform_op next_, rest_;
};

template<typename Iterator>
inline bool set_transform(Iterator &, transform_op, transform_scope)
{
    return false;
}

///////////////////////////////////////////////////////////////////////////////
// noop_output_iterator
//
template<typename Char>
struct noop_output_iterator
  : std::iterator<std::output_iterator_tag, Char, void, void, noop_output_iterator<Char> >
{
    noop_output_iterator &operator ++()
    {
        return *this;
    }

    noop_output_iterator &operator ++(int)
    {
        return *this;
    }

    noop_output_iterator &operator *()
    {
        return *this;
    }

    noop_output_iterator &operator =(Char const &)
    {
        return *this;
    }
};

struct any_type { any_type(...); };
typedef char no_type;
typedef char (&unary_type)[2];
typedef char (&binary_type)[3];
typedef char (&ternary_type)[4];

no_type check_is_formatter(unary_type, binary_type, ternary_type);

template<typename T>
unary_type check_is_formatter(T const &, binary_type, ternary_type);

template<typename T>
binary_type check_is_formatter(unary_type, T const &, ternary_type);

template<typename T, typename U>
binary_type check_is_formatter(T const &, U const &, ternary_type);

template<typename T>
ternary_type check_is_formatter(unary_type, binary_type, T const &);

template<typename T, typename U>
ternary_type check_is_formatter(T const &, binary_type, U const &);

template<typename T, typename U>
ternary_type check_is_formatter(unary_type, T const &, U const &);

template<typename T, typename U, typename V>
ternary_type check_is_formatter(T const &, U const &, V const &);

struct unary_binary_ternary
{
    typedef unary_type (*unary_fun)(any_type);
    typedef binary_type (*binary_fun)(any_type, any_type);
    typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);
    operator unary_fun();
    operator binary_fun();
    operator ternary_fun();
};

template<typename Formatter, bool IsFunction = is_function<Formatter>::value>
struct formatter_wrapper
  : Formatter
  , unary_binary_ternary
{
    formatter_wrapper();
};

template<typename Formatter>
struct formatter_wrapper<Formatter, true>
  : unary_binary_ternary
{
    operator Formatter *();
};

template<typename Formatter>
struct formatter_wrapper<Formatter *, false>
  : unary_binary_ternary
{
    operator Formatter *();
};

template<typename Formatter, typename What, typename Out, typename Void = void>
struct formatter_arity
{
    static formatter_wrapper<Formatter> &formatter;
    static What &what;
    static Out &out;
    BOOST_STATIC_CONSTANT(
        std::size_t
      , value = sizeof(
            check_is_formatter(
                formatter(what)
              , formatter(what, out)
              , formatter(what, out, regex_constants::format_default)
            )
        ) - 1
    );
    typedef mpl::size_t<value> type;
};

template<typename Formatter, typename What, typename Out>
struct formatter_arity<Formatter, What, Out, typename Formatter::proto_is_expr_>
  : mpl::size_t<4>
{};

template<typename T>
struct is_char_ptr
  : mpl::false_
{};

template<typename T>
struct is_char_ptr<T *>
  : mpl::not_<is_function<T> >
{};

#if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
// work around gcc-4.0.1 compiler bug wrt function references
template<typename T>
typename mpl::if_<is_function<T>, T *, T const &>::type
as_callable(T const &t)
{
    return t;
}
#endif

} // detail

///////////////////////////////////////////////////////////////////////////////
// match_results
/// \brief Class template match_results\<\> holds the results of a regex_match() or a
/// regex_search() as a collection of sub_match objects.
///
/// Class template match_results\<\> denotes a collection of sequences representing the result of
/// a regular expression match. Storage for the collection is allocated and freed as necessary by
/// the member functions of class match_results\<\>.
///
/// The class template match_results\<\> conforms to the requirements of a Sequence, as specified
/// in (lib.sequence.reqmts), except that only operations defined for const-qualified Sequences are
/// supported.
template<typename BidiIter>
struct match_results
{
private:
    /// INTERNAL ONLY
    ///
    struct dummy { int i_; };
    typedef int dummy::*bool_type;

public:
    typedef typename iterator_value<BidiIter>::type char_type;
    typedef typename detail::string_type<char_type>::type string_type;
    typedef std::size_t size_type;
    typedef sub_match<BidiIter> value_type;
    typedef typename iterator_difference<BidiIter>::type difference_type;
    typedef value_type const &reference;
    typedef value_type const &const_reference;

    typedef typename detail::sub_match_vector<BidiIter>::iterator iterator;
    typedef typename detail::sub_match_vector<BidiIter>::const_iterator const_iterator;
    typedef typename detail::nested_results<BidiIter> nested_results_type;

    /// \post regex_id() == 0
    /// \post size()     == 0
    /// \post empty()    == true
    /// \post str()      == string_type()
    match_results()
      : regex_id_(0)
      , sub_matches_()
      , base_()
      , prefix_()
      , suffix_()
      , nested_results_()
      , extras_ptr_()
      , traits_()
      , args_()
      , named_marks_()
    {
    }

    /// \param that The match_results object to copy
    /// \post regex_id()  == that.regex_id().
    /// \post size()      == that.size().
    /// \post empty()     == that.empty().
    /// \post str(n)      == that.str(n) for all positive integers n \< that.size().
    /// \post prefix()    == that.prefix().
    /// \post suffix()    == that.suffix().
    /// \post (*this)[n]  == that[n] for all positive integers n \< that.size().
    /// \post length(n)   == that.length(n) for all positive integers n \< that.size().
    /// \post position(n) == that.position(n) for all positive integers n \< that.size().
    match_results(match_results<BidiIter> const &that)
      : regex_id_(that.regex_id_)
      , sub_matches_()
      , base_()
      , prefix_()
      , suffix_()
      , nested_results_()
      , extras_ptr_()
      , traits_()
      , args_(that.args_)
      , named_marks_(that.named_marks_)
    {
        if(that)
        {
            extras_type &extras = this->get_extras_();
            std::size_t size = that.sub_matches_.size();
            detail::sub_match_impl<BidiIter> *sub_matches = extras.sub_match_stack_.push_sequence(size, detail::sub_match_impl<BidiIter>(*that.base_), detail::fill);
            detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, sub_matches, size, that.sub_matches_);

            this->base_ = that.base_;
            this->prefix_ = that.prefix_;
            this->suffix_ = that.suffix_;
            // BUGBUG this doesn't share the extras::sequence_stack
            this->nested_results_ = that.nested_results_;
            this->traits_ = that.traits_;
        }
    }

    ~match_results()
    {
    }

    /// \param that The match_results object to copy.
    /// \post regex_id()  == that.regex_id().
    /// \post size()      == that.size().
    /// \post empty()     == that.empty().
    /// \post str(n)      == that.str(n) for all positive integers n \< that.size().
    /// \post prefix()    == that.prefix().
    /// \post suffix()    == that.suffix().
    /// \post (*this)[n]  == that[n] for all positive integers n \< that.size().
    /// \post length(n)   == that.length(n) for all positive integers n \< that.size().
    /// \post position(n) == that.position(n) for all positive integers n \< that.size().
    match_results<BidiIter> &operator =(match_results<BidiIter> const &that)
    {
        match_results<BidiIter>(that).swap(*this);
        return *this;
    }

    /// Returns one plus the number of marked sub-expressions in the regular
    /// expression that was matched if *this represents the result of a
    /// successful match. Otherwise returns 0.
    size_type size() const
    {
        return this->sub_matches_.size();
    }

    /// Returns size() == 0.
    ///
    bool empty() const
    {
        return 0 == this->size();
    }

    /// Returns (*this)[sub].length().
    ///
    difference_type length(size_type sub = 0) const
    {
        return this->sub_matches_[ sub ].length();
    }

    /// If !(*this)[sub].matched then returns -1. Otherwise returns std::distance(base, (*this)[sub].first),
    /// where base is the start iterator of the sequence that was searched. [Note - unless this is part
    /// of a repeated search with a regex_iterator then base is the same as prefix().first - end note]
    difference_type position(size_type sub = 0) const
    {
        return this->sub_matches_[ sub ].matched ? std::distance(*this->base_, this->sub_matches_[ sub ].first) : -1;
    }

    /// Returns (*this)[sub].str().
    ///
    string_type str(size_type sub = 0) const
    {
        return this->sub_matches_[ sub ].str();
    }

    /// Returns a reference to the sub_match object representing the sequence that
    /// matched marked sub-expression sub. If sub == 0 then returns a reference to
    /// a sub_match object representing the sequence that matched the whole regular
    /// expression. If sub >= size() then returns a sub_match object representing an
    /// unmatched sub-expression.
    template<typename Sub>
    const_reference operator [](Sub const &sub) const
    {
        return this->at_(sub);
    }

    /// Returns a reference to the sub_match object representing the character sequence from
    /// the start of the string being matched/searched, to the start of the match found.
    ///
    /// \pre (*this)[0].matched is true
    const_reference prefix() const
    {
        return this->prefix_ ? *this->prefix_ : this->sub_matches_[this->sub_matches_.size()];
    }

    /// Returns a reference to the sub_match object representing the character sequence from
    /// the end of the match found to the end of the string being matched/searched.
    ///
    /// \pre (*this)[0].matched is true
    const_reference suffix() const
    {
        return this->suffix_ ? *this->suffix_ : this->sub_matches_[this->sub_matches_.size()];
    }

    /// Returns a starting iterator that enumerates over all the marked sub-expression matches
    /// stored in *this.
    ///
    const_iterator begin() const
    {
        return this->sub_matches_.begin();
    }

    /// Returns a terminating iterator that enumerates over all the marked sub-expression
    /// matches stored in *this.
    ///
    const_iterator end() const
    {
        return this->sub_matches_.end();
    }

    /// Returns a true value if (*this)[0].matched, else returns a false value.
    ///
    operator bool_type() const
    {
        return (!this->empty() && this->sub_matches_[ 0 ].matched) ? &dummy::i_ : 0;
    }

    /// Returns true if empty() || !(*this)[0].matched, else returns false.
    ///
    bool operator !() const
    {
        return this->empty() || !this->sub_matches_[ 0 ].matched;
    }

    /// Returns the id of the basic_regex object most recently used with this match_results object.
    ///
    regex_id_type regex_id() const
    {
        return this->regex_id_;
    }

    /// Returns a Sequence of nested match_results elements.
    ///
    nested_results_type const &nested_results() const
    {
        return this->nested_results_;
    }

    /// If \c Format models \c ForwardRange or is a null-terminated string, this function
    /// copies the character sequence in \c fmt to \c OutputIterator \c out. For each format
    /// specifier or escape sequence in \c fmt, replace that sequence with either the character(s) it
    /// represents, or the sequence within <tt>*this</tt> to which it refers. The bitmasks specified in flags
    /// determines what format specifiers or escape sequences are recognized. By default, this is the
    /// format used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.
    ///
    /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator, regex_constants::match_flag_type\></tt>,
    /// this function returns <tt>fmt(*this, out, flags)</tt>.
    ///
    /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator\></tt>, this function
    /// returns <tt>fmt(*this, out)</tt>.
    ///
    /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\> \></tt>, this function
    /// returns <tt>std::copy(x.begin(), x.end(), out)</tt>, where \c x is the result of
    /// calling <tt>fmt(*this)</tt>.
    template<typename Format, typename OutputIterator>
    OutputIterator format
    (
        OutputIterator out
      , Format const &fmt
      , regex_constants::match_flag_type flags = regex_constants::format_default
      , typename disable_if<detail::is_char_ptr<Format> >::type * = 0
    ) const
    {
        // Is this a formatter object, or a format string?
        typedef
            typename detail::formatter_arity<
                Format
              , match_results<BidiIter>
              , OutputIterator
            >::type
        arity;

        return this->format_(out, fmt, flags, arity());
    }

    /// \overload
    ///
    template<typename OutputIterator>
    OutputIterator format
    (
        OutputIterator out
      , char_type const *fmt
      , regex_constants::match_flag_type flags = regex_constants::format_default
    ) const
    {
        return this->format_(out, boost::as_literal(fmt), flags, mpl::size_t<0>());
    }

    /// If \c Format models \c ForwardRange or is a null-terminated string, this function
    /// returns a copy of the character sequence \c fmt. For each format specifier or escape sequence in \c fmt,
    /// replace that sequence with either the character(s) it represents, or the sequence within
    /// <tt>*this</tt> to which it refers. The bitmasks specified in \c flags determines what format specifiers
    /// or escape sequences are recognized. By default this is the format used by ECMA-262,
    /// ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.
    ///
    /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator, regex_constants::match_flag_type\></tt>,
    /// this function returns a \c string_type object \c x populated by calling <tt>fmt(*this, out, flags)</tt>,
    /// where \c out is a \c back_insert_iterator into \c x.
    ///
    /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator\></tt>, this function
    /// returns a \c string_type object \c x populated by calling <tt>fmt(*this, out)</tt>,
    /// where \c out is a \c back_insert_iterator into \c x.
    ///
    /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\> \></tt>, this function
    /// returns <tt>fmt(*this)</tt>.
    template<typename Format, typename OutputIterator>
    string_type format
    (
        Format const &fmt
      , regex_constants::match_flag_type flags = regex_constants::format_default
      , typename disable_if<detail::is_char_ptr<Format> >::type * = 0
    ) const
    {
        string_type result;
        this->format(std::back_inserter(result), fmt, flags);
        return result;
    }

    /// \overload
    ///
    string_type format
    (
        char_type const *fmt
      , regex_constants::match_flag_type flags = regex_constants::format_default
    ) const
    {
        string_type result;
        this->format(std::back_inserter(result), fmt, flags);
        return result;
    }

    /// Swaps the contents of two match_results objects. Guaranteed not to throw.
    /// \param that The match_results object to swap with.
    /// \post *this contains the sequence of matched sub-expressions that were in that,
    /// that contains the sequence of matched sub-expressions that were in *this.
    /// \throw nothrow
    void swap(match_results<BidiIter> &that) // throw()
    {
        using std::swap;
        swap(this->regex_id_, that.regex_id_);
        this->sub_matches_.swap(that.sub_matches_);
        swap(this->base_, that.base_);
        swap(this->prefix_, that.prefix_);
        swap(this->suffix_, that.suffix_);
        this->nested_results_.swap(that.nested_results_);
        this->extras_ptr_.swap(that.extras_ptr_);
        this->traits_.swap(that.traits_);
        this->args_.swap(that.args_);
    }

    /// TODO document me
    ///
    template<typename Arg>
    match_results<BidiIter> &let(Arg const &arg)
    {
        typedef typename proto::result_of::left<Arg>::type left_type;
        typedef typename proto::result_of::right<Arg>::type right_type;
        typedef typename proto::result_of::value<left_type>::type arg_left_type;
        typedef typename proto::result_of::value<right_type>::type arg_right_type;
        BOOST_MPL_ASSERT((proto::matches<Arg, detail::ActionArgBinding>));
        BOOST_MPL_ASSERT((is_same<typename arg_left_type::type, arg_right_type>));
        this->args_[&typeid(proto::value(proto::left(arg)))] = &proto::value(proto::right(arg));
        return *this;
    }

    /// INTERNAL ONLY
    ///
    match_results<BidiIter> const &operator ()(regex_id_type regex_id, size_type index = 0) const
    {
        // BUGBUG this is linear, make it O(1)
        static match_results<BidiIter> const s_null;

        regex_id_filter_predicate<BidiIter> pred(regex_id);
        typename nested_results_type::const_iterator
            begin = this->nested_results_.begin()
          , end = this->nested_results_.end()
          , cur = detail::find_nth_if(begin, end, index, pred);

        return (cur == end) ? s_null : *cur;
    }

    /// INTERNAL ONLY
    ///
    match_results<BidiIter> const &operator ()(basic_regex<BidiIter> const &rex, std::size_t index = 0) const
    {
        return (*this)(rex.regex_id(), index);
    }

private:

    friend struct detail::core_access<BidiIter>;
    typedef detail::results_extras<BidiIter> extras_type;

    /// INTERNAL ONLY
    ///
    void init_
    (
        regex_id_type regex_id
      , intrusive_ptr<detail::traits<char_type> const> const &tr
      , detail::sub_match_impl<BidiIter> *sub_matches
      , size_type size
      , std::vector<detail::named_mark<char_type> > const &named_marks
    )
    {
        this->traits_ = tr;
        this->regex_id_ = regex_id;
        this->named_marks_ = named_marks;
        detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, sub_matches, size);
    }

    /// INTERNAL ONLY
    ///
    extras_type &get_extras_()
    {
        if(!this->extras_ptr_)
        {
            this->extras_ptr_ = new extras_type;
        }

        return *this->extras_ptr_;
    }

    /// INTERNAL ONLY
    ///
    void set_prefix_suffix_(BidiIter begin, BidiIter end)
    {
        this->base_ = begin;
        this->prefix_ = sub_match<BidiIter>(begin, this->sub_matches_[ 0 ].first, begin != this->sub_matches_[ 0 ].first);
        this->suffix_ = sub_match<BidiIter>(this->sub_matches_[ 0 ].second, end, this->sub_matches_[ 0 ].second != end);

        typename nested_results_type::iterator ibegin = this->nested_results_.begin();
        typename nested_results_type::iterator iend = this->nested_results_.end();
        for( ; ibegin != iend; ++ibegin )
        {
            ibegin->set_prefix_suffix_(begin, end);
        }
    }

    /// INTERNAL ONLY
    ///
    void reset_()
    {
        detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, 0, 0);
    }

    /// INTERNAL ONLY
    ///
    void set_base_(BidiIter base)
    {
        this->base_ = base;

        typename nested_results_type::iterator ibegin = this->nested_results_.begin();
        typename nested_results_type::iterator iend = this->nested_results_.end();
        for( ; ibegin != iend; ++ibegin )
        {
            ibegin->set_base_(base);
        }
    }

    /// INTERNAL ONLY
    ///
    const_reference at_(size_type sub) const
    {
        return this->sub_matches_[ sub ];
    }

    /// INTERNAL ONLY
    ///
    const_reference at_(detail::basic_mark_tag const &mark) const
    {
        return this->sub_matches_[ detail::get_mark_number(mark) ];
    }

    /// INTERNAL ONLY
    ///
    const_reference at_(char_type const *name) const
    {
        for(std::size_t i = 0; i < this->named_marks_.size(); ++i)
        {
            if(this->named_marks_[i].name_ == name)
            {
                return this->sub_matches_[ this->named_marks_[i].mark_nbr_ ];
            }
        }
        BOOST_THROW_EXCEPTION(
            regex_error(regex_constants::error_badmark, "invalid named back-reference")
        );
        // Should never execute, but if it does, this returns
        // a "null" sub_match.
        return this->sub_matches_[this->sub_matches_.size()];
    }

    /// INTERNAL ONLY
    ///
    const_reference at_(string_type const &name) const
    {
        return (*this)[name.c_str()];
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename ForwardRange>
    OutputIterator format2_(OutputIterator out, ForwardRange const &result) const
    {
        return std::copy(boost::begin(result), boost::end(result), out);
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename Char>
    OutputIterator format2_(OutputIterator out, Char const *const &result) const
    {
        Char const *tmp = result;
        BOOST_ASSERT(0 != tmp);
        for(; 0 != *tmp; ++tmp, ++out)
        {
            *out = *tmp;
        }
        return out;
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename ForwardRange>
    OutputIterator format_
    (
        OutputIterator out
      , ForwardRange const &format
      , regex_constants::match_flag_type flags
      , mpl::size_t<0>
    ) const
    {
        typedef typename range_const_iterator<ForwardRange>::type iterator;
        iterator cur = boost::begin(format), end = boost::end(format);

        if(0 != (regex_constants::format_literal & flags))
        {
            return std::copy(cur, end, out);
        }
        else if(0 != (regex_constants::format_perl & flags))
        {
            return this->format_perl_(cur, end, out);
        }
        else if(0 != (regex_constants::format_sed & flags))
        {
            return this->format_sed_(cur, end, out);
        }
        else if(0 != (regex_constants::format_all & flags))
        {
            return this->format_all_(cur, end, out);
        }

        return this->format_ecma_262_(cur, end, out);
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename Callable1>
    OutputIterator format_
    (
        OutputIterator out
      , Callable1 const &format
      , regex_constants::match_flag_type
      , mpl::size_t<1>
    ) const
    {
        #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
        return this->format2_(out, detail::as_callable(format)(*this));
        #else
        return this->format2_(out, format(*this));
        #endif
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename Callable2>
    OutputIterator format_
    (
        OutputIterator out
      , Callable2 const &format
      , regex_constants::match_flag_type
      , mpl::size_t<2>
    ) const
    {
        #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
        return detail::as_callable(format)(*this, out);
        #else
        return format(*this, out);
        #endif
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename Callable3>
    OutputIterator format_
    (
        OutputIterator out
      , Callable3 const &format
      , regex_constants::match_flag_type flags
      , mpl::size_t<3>
    ) const
    {
        #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
        return detail::as_callable(format)(*this, out, flags);
        #else
        return format(*this, out, flags);
        #endif
    }

    /// INTERNAL ONLY
    ///
    template<typename OutputIterator, typename Expr>
    OutputIterator format_
    (
        OutputIterator out
      , Expr const &format
      , regex_constants::match_flag_type flags
      , mpl::size_t<4>
    ) const
    {
        detail::replacement_context<BidiIter> ctx(*this);
        return this->format2_(out, proto::eval(format, ctx));
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_ecma_262_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
    {
        while(cur != end)
        {
            switch(*cur)
            {
            case BOOST_XPR_CHAR_(char_type, '$'):
                out = this->format_backref_(++cur, end, out);
                break;

            default:
                *out++ = *cur++;
                break;
            }
        }

        return out;
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_sed_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
    {
        while(cur != end)
        {
            switch(*cur)
            {
            case BOOST_XPR_CHAR_(char_type, '&'):
                ++cur;
                out = std::copy(this->sub_matches_[ 0 ].first, this->sub_matches_[ 0 ].second, out);
                break;

            case BOOST_XPR_CHAR_(char_type, '\\'):
                out = this->format_escape_(++cur, end, out);
                break;

            default:
                *out++ = *cur++;
                break;
            }
        }

        return out;
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_perl_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
    {
        detail::case_converting_iterator<OutputIterator, char_type> iout(out, this->traits_.get());

        while(cur != end)
        {
            switch(*cur)
            {
            case BOOST_XPR_CHAR_(char_type, '$'):
                iout = this->format_backref_(++cur, end, iout);
                break;

            case BOOST_XPR_CHAR_(char_type, '\\'):
                if(++cur != end && BOOST_XPR_CHAR_(char_type, 'g') == *cur)
                {
                    iout = this->format_named_backref_(++cur, end, iout);
                }
                else
                {
                    iout = this->format_escape_(cur, end, iout);
                }
                break;

            default:
                *iout++ = *cur++;
                break;
            }
        }

        return iout.base();
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_all_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
    {
        detail::case_converting_iterator<OutputIterator, char_type> iout(out, this->traits_.get());
        iout = this->format_all_impl_(cur, end, iout);
        BOOST_XPR_ENSURE_(cur == end
          , regex_constants::error_paren, "unbalanced parentheses in format string");
        return iout.base();
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_all_impl_(ForwardIterator &cur, ForwardIterator end, OutputIterator out, bool metacolon = false) const
    {
        int max = 0, sub = 0;
        detail::noop_output_iterator<char_type> noop;

        while(cur != end)
        {
            switch(*cur)
            {
            case BOOST_XPR_CHAR_(char_type, '$'):
                out = this->format_backref_(++cur, end, out);
                break;

            case BOOST_XPR_CHAR_(char_type, '\\'):
                if(++cur != end && BOOST_XPR_CHAR_(char_type, 'g') == *cur)
                {
                    out = this->format_named_backref_(++cur, end, out);
                }
                else
                {
                    out = this->format_escape_(cur, end, out);
                }
                break;

            case BOOST_XPR_CHAR_(char_type, '('):
                out = this->format_all_impl_(++cur, end, out);
                BOOST_XPR_ENSURE_(BOOST_XPR_CHAR_(char_type, ')') == *(cur-1)
                  , regex_constants::error_paren, "unbalanced parentheses in format string");
                break;

            case BOOST_XPR_CHAR_(char_type, '?'):
                BOOST_XPR_ENSURE_(++cur != end
                  , regex_constants::error_subreg, "malformed conditional in format string");
                max = static_cast<int>(this->size() - 1);
                sub = detail::toi(cur, end, *this->traits_, 10, max);
                BOOST_XPR_ENSURE_(0 != sub, regex_constants::error_subreg, "invalid back-reference");
                if(this->sub_matches_[ sub ].matched)
                {
                    out = this->format_all_impl_(cur, end, out, true);
                    if(BOOST_XPR_CHAR_(char_type, ':') == *(cur-1))
                        this->format_all_impl_(cur, end, noop);
                }
                else
                {
                    this->format_all_impl_(cur, end, noop, true);
                    if(BOOST_XPR_CHAR_(char_type, ':') == *(cur-1))
                        out = this->format_all_impl_(cur, end, out);
                }
                return out;

            case BOOST_XPR_CHAR_(char_type, ':'):
                if(metacolon)
                {
            case BOOST_XPR_CHAR_(char_type, ')'):
                    ++cur;
                    return out;
                }
                // else fall-through

            default:
                *out++ = *cur++;
                break;
            }
        }

        return out;
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_backref_
    (
        ForwardIterator &cur
      , ForwardIterator end
      , OutputIterator out
    ) const
    {
        if(cur == end)
        {
            *out++ = BOOST_XPR_CHAR_(char_type, '$');
        }
        else if(BOOST_XPR_CHAR_(char_type, '$') == *cur)
        {
            *out++ = *cur++;
        }
        else if(BOOST_XPR_CHAR_(char_type, '&') == *cur) // whole match
        {
            ++cur;
            out = std::copy(this->sub_matches_[ 0 ].first, this->sub_matches_[ 0 ].second, out);
        }
        else if(BOOST_XPR_CHAR_(char_type, '`') == *cur) // prefix
        {
            ++cur;
            out = std::copy(this->prefix().first, this->prefix().second, out);
        }
        else if(BOOST_XPR_CHAR_(char_type, '\'') == *cur) // suffix
        {
            ++cur;
            out = std::copy(this->suffix().first, this->suffix().second, out);
        }
        else if(-1 != this->traits_->value(*cur, 10)) // a sub-match
        {
            int max = static_cast<int>(this->size() - 1);
            int sub = detail::toi(cur, end, *this->traits_, 10, max);
            BOOST_XPR_ENSURE_(0 != sub, regex_constants::error_subreg, "invalid back-reference");
            if(this->sub_matches_[ sub ].matched)
                out = std::copy(this->sub_matches_[ sub ].first, this->sub_matches_[ sub ].second, out);
        }
        else
        {
            *out++ = BOOST_XPR_CHAR_(char_type, '$');
            *out++ = *cur++;
        }

        return out;
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_escape_
    (
        ForwardIterator &cur
      , ForwardIterator end
      , OutputIterator out
    ) const
    {
        using namespace regex_constants;
        ForwardIterator tmp;
        // define an unsigned type the same size as char_type
        typedef typename boost::uint_t<CHAR_BIT * sizeof(char_type)>::least uchar_t;
        BOOST_MPL_ASSERT_RELATION(sizeof(uchar_t), ==, sizeof(char_type));
        typedef numeric::conversion_traits<uchar_t, int> converstion_traits;
        numeric::converter<int, uchar_t, converstion_traits, detail::char_overflow_handler_> converter;

        if(cur == end)
        {
            *out++ = BOOST_XPR_CHAR_(char_type, '\\');
            return out;
        }

        char_type ch = *cur++;
        switch(ch)
        {
        case BOOST_XPR_CHAR_(char_type, 'a'):
            *out++ = BOOST_XPR_CHAR_(char_type, '\a');
            break;

        case BOOST_XPR_CHAR_(char_type, 'e'):
            *out++ = converter(27);
            break;

        case BOOST_XPR_CHAR_(char_type, 'f'):
            *out++ = BOOST_XPR_CHAR_(char_type, '\f');
            break;

        case BOOST_XPR_CHAR_(char_type, 'n'):
            *out++ = BOOST_XPR_CHAR_(char_type, '\n');
            break;

        case BOOST_XPR_CHAR_(char_type, 'r'):
            *out++ = BOOST_XPR_CHAR_(char_type, '\r');
            break;

        case BOOST_XPR_CHAR_(char_type, 't'):
            *out++ = BOOST_XPR_CHAR_(char_type, '\t');
            break;

        case BOOST_XPR_CHAR_(char_type, 'v'):
            *out++ = BOOST_XPR_CHAR_(char_type, '\v');
            break;

        case BOOST_XPR_CHAR_(char_type, 'x'):
            BOOST_XPR_ENSURE_(cur != end, error_escape, "unexpected end of format found");
            if(BOOST_XPR_CHAR_(char_type, '{') == *cur)
            {
                BOOST_XPR_ENSURE_(++cur != end, error_escape, "unexpected end of format found");
                tmp = cur;
                *out++ = converter(detail::toi(cur, end, *this->traits_, 16, 0xffff));
                BOOST_XPR_ENSURE_(4 == std::distance(tmp, cur) && cur != end && BOOST_XPR_CHAR_(char_type, '}') == *cur++
                  , error_escape, "invalid hex escape : must be \\x { HexDigit HexDigit HexDigit HexDigit }");
            }
            else
            {
                tmp = cur;
                *out++ = converter(detail::toi(cur, end, *this->traits_, 16, 0xff));
                BOOST_XPR_ENSURE_(2 == std::distance(tmp, cur), error_escape
                  , "invalid hex escape : must be \\x HexDigit HexDigit");
            }
            break;

        case BOOST_XPR_CHAR_(char_type, 'c'):
            BOOST_XPR_ENSURE_(cur != end, error_escape, "unexpected end of format found");
            BOOST_XPR_ENSURE_
            (
                this->traits_->in_range(BOOST_XPR_CHAR_(char_type, 'a'), BOOST_XPR_CHAR_(char_type, 'z'), *cur)
             || this->traits_->in_range(BOOST_XPR_CHAR_(char_type, 'A'), BOOST_XPR_CHAR_(char_type, 'Z'), *cur)
              , error_escape
              , "invalid escape control letter; must be one of a-z or A-Z"
            );
            // Convert to character according to ECMA-262, section 15.10.2.10:
            *out++ = converter(*cur % 32);
            ++cur;
            break;

        case BOOST_XPR_CHAR_(char_type, 'l'):
            if(!set_transform(out, detail::Lower, detail::Next))
            {
                *out++ = BOOST_XPR_CHAR_(char_type, 'l');
            }
            break;

        case BOOST_XPR_CHAR_(char_type, 'L'):
            if(!set_transform(out, detail::Lower, detail::Rest))
            {
                *out++ = BOOST_XPR_CHAR_(char_type, 'L');
            }
            break;

        case BOOST_XPR_CHAR_(char_type, 'u'):
            if(!set_transform(out, detail::Upper, detail::Next))
            {
                *out++ = BOOST_XPR_CHAR_(char_type, 'u');
            }
            break;

        case BOOST_XPR_CHAR_(char_type, 'U'):
            if(!set_transform(out, detail::Upper, detail::Rest))
            {
                *out++ = BOOST_XPR_CHAR_(char_type, 'U');
            }
            break;

        case BOOST_XPR_CHAR_(char_type, 'E'):
            if(!set_transform(out, detail::None, detail::Rest))
            {
                *out++ = BOOST_XPR_CHAR_(char_type, 'E');
            }
            break;

        default:
            // BUGBUG what about backreferences like \12 ?
            if(0 < this->traits_->value(ch, 10))
            {
                int sub = this->traits_->value(ch, 10);
                if(this->sub_matches_[ sub ].matched)
                    out = std::copy(this->sub_matches_[ sub ].first, this->sub_matches_[ sub ].second, out);
            }
            else
            {
                *out++ = ch;
            }
            break;
        }

        return out;
    }

    /// INTERNAL ONLY
    ///
    template<typename ForwardIterator, typename OutputIterator>
    OutputIterator format_named_backref_
    (
        ForwardIterator &cur
      , ForwardIterator end
      , OutputIterator out
    ) const
    {
        using namespace regex_constants;
        BOOST_XPR_ENSURE_(cur != end && BOOST_XPR_CHAR_(char_type, '<') == *cur++
            , error_badmark, "invalid named back-reference");
        ForwardIterator begin = cur;
        for(; cur != end && BOOST_XPR_CHAR_(char_type, '>') != *cur; ++cur)
        {}
        BOOST_XPR_ENSURE_(cur != begin && cur != end && BOOST_XPR_CHAR_(char_type, '>') == *cur
            , error_badmark, "invalid named back-reference");

        string_type name(begin, cur++);
        for(std::size_t i = 0; i < this->named_marks_.size(); ++i)
        {
            if(this->named_marks_[i].name_ == name)
            {
                std::size_t sub = this->named_marks_[i].mark_nbr_;
                return std::copy(this->sub_matches_[ sub ].first, this->sub_matches_[ sub ].second, out);
            }
        }

        BOOST_THROW_EXCEPTION(regex_error(error_badmark, "invalid named back-reference"));
        // Should never get here
        return out;
    }

    regex_id_type regex_id_;
    detail::sub_match_vector<BidiIter> sub_matches_;
    boost::optional<BidiIter> base_;
    boost::optional<sub_match<BidiIter> > prefix_;
    boost::optional<sub_match<BidiIter> > suffix_;
    nested_results_type nested_results_;
    intrusive_ptr<extras_type> extras_ptr_;
    intrusive_ptr<detail::traits<char_type> const> traits_;
    detail::action_args_type args_;
    std::vector<detail::named_mark<char_type> > named_marks_;
};

///////////////////////////////////////////////////////////////////////////////
// regex_id_filter_predicate
//
template<typename BidiIter>
struct regex_id_filter_predicate
  : std::unary_function<match_results<BidiIter>, bool>
{
    regex_id_filter_predicate(regex_id_type regex_id)
      : regex_id_(regex_id)
    {
    }

    bool operator ()(match_results<BidiIter> const &res) const
    {
        return this->regex_id_ == res.regex_id();
    }

private:

    regex_id_type regex_id_;
};

}} // namespace boost::xpressive

#ifdef BOOST_HAS_CONCEPTS
// Better living through concepts. :-P
namespace std
{
    template<typename Iter_, typename Char_>
    concept_map OutputIterator<
        boost::xpressive::detail::case_converting_iterator<Iter_, Char_>
      , Char_
    >
    {};

    template<typename Char_>
    concept_map OutputIterator<
        boost::xpressive::detail::noop_output_iterator<Char_>
      , Char_
    >
    {};
}
#endif

#endif
