///////////////////////////////////////////////////////////////////////////////
/// \file basic_regex.hpp
/// Contains the definition of the basic_regex\<\> class template and its
/// associated helper functions.
//
//  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_BASIC_REGEX_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005

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

#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/xpressive/xpressive_fwd.hpp>
#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/regex_domain.hpp>

// Doxygen can't handle proto :-(
#ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
# include <boost/xpressive/detail/static/grammar.hpp>
# include <boost/proto/extends.hpp>
#endif

#if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
# include <excpt.h>     // for _exception_code()
# include <malloc.h>    // for _resetstkoflw()
#endif

namespace boost { namespace xpressive
{

namespace detail
{
    inline void throw_on_stack_error(bool stack_error)
    {
        BOOST_XPR_ENSURE_(!stack_error, regex_constants::error_stack, "Regex stack space exhausted");
    }
}

///////////////////////////////////////////////////////////////////////////////
// basic_regex
//
/// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression.
template<typename BidiIter>
struct basic_regex
  : proto::extends<
        proto::expr<proto::tag::terminal, proto::term<detail::tracking_ptr<detail::regex_impl<BidiIter> > >, 0>
      , basic_regex<BidiIter>
      , detail::regex_domain
    >
{
private:
    typedef proto::expr<proto::tag::terminal, proto::term<detail::tracking_ptr<detail::regex_impl<BidiIter> > >, 0> pimpl_type;
    typedef proto::extends<pimpl_type, basic_regex<BidiIter>, detail::regex_domain> base_type;

public:
    typedef BidiIter iterator_type;
    typedef typename iterator_value<BidiIter>::type char_type;
    // For compatibility with std::basic_regex
    typedef typename iterator_value<BidiIter>::type value_type;
    typedef typename detail::string_type<char_type>::type string_type;
    typedef regex_constants::syntax_option_type flag_type;

    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ECMAScript         = regex_constants::ECMAScript);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, icase              = regex_constants::icase_);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, nosubs             = regex_constants::nosubs);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, optimize           = regex_constants::optimize);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, collate            = regex_constants::collate);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, single_line        = regex_constants::single_line);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_null       = regex_constants::not_dot_null);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_newline    = regex_constants::not_dot_newline);
    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ignore_white_space = regex_constants::ignore_white_space);

    /// \post regex_id()    == 0
    /// \post mark_count()  == 0
    basic_regex()
      : base_type()
    {
    }

    /// \param that The basic_regex object to copy.
    /// \post regex_id()    == that.regex_id()
    /// \post mark_count()  == that.mark_count()
    basic_regex(basic_regex<BidiIter> const &that)
      : base_type(that)
    {
    }

    /// \param that The basic_regex object to copy.
    /// \post regex_id()    == that.regex_id()
    /// \post mark_count()  == that.mark_count()
    /// \return *this
    basic_regex<BidiIter> &operator =(basic_regex<BidiIter> const &that)
    {
        proto::value(*this) = proto::value(that);
        return *this;
    }

    /// Construct from a static regular expression.
    ///
    /// \param  expr The static regular expression
    /// \pre    Expr is the type of a static regular expression.
    /// \post   regex_id()   != 0
    /// \post   mark_count() \>= 0
    template<typename Expr>
    basic_regex(Expr const &expr)
      : base_type()
    {
        BOOST_XPRESSIVE_CHECK_REGEX(Expr, char_type);
        this->compile_(expr, is_valid_regex<Expr, char_type>());
    }

    /// Construct from a static regular expression.
    ///
    /// \param  expr The static regular expression.
    /// \pre    Expr is the type of a static regular expression.
    /// \post   regex_id()   != 0
    /// \post   mark_count() \>= 0
    /// \throw  std::bad_alloc on out of memory
    /// \return *this
    template<typename Expr>
    basic_regex<BidiIter> &operator =(Expr const &expr)
    {
        BOOST_XPRESSIVE_CHECK_REGEX(Expr, char_type);
        this->compile_(expr, is_valid_regex<Expr, char_type>());
        return *this;
    }

    /// Returns the count of capturing sub-expressions in this regular expression
    ///
    std::size_t mark_count() const
    {
        return proto::value(*this) ? proto::value(*this)->mark_count_ : 0;
    }

    /// Returns a token which uniquely identifies this regular expression.
    ///
    regex_id_type regex_id() const
    {
        return proto::value(*this) ? proto::value(*this)->xpr_.get() : 0;
    }

    /// Swaps the contents of this basic_regex object with another.
    ///
    /// \param      that The other basic_regex object.
    /// \attention  This is a shallow swap that does not do reference tracking.
    ///             If you embed a basic_regex object by reference in another
    ///             regular expression and then swap its contents with another
    ///             basic_regex object, the change will not be visible to the
    ///             enclosing regular expression. It is done this way to ensure
    ///             that swap() cannot throw.
    /// \throw      nothrow
    void swap(basic_regex<BidiIter> &that) // throw()
    {
        proto::value(*this).swap(proto::value(that));
    }

    /// Factory method for building a regex object from a range of characters.
    /// Equivalent to regex_compiler\< BidiIter \>().compile(begin, end, flags);
    ///
    /// \param  begin The beginning of a range of characters representing the
    ///         regular expression to compile.
    /// \param  end The end of a range of characters representing the
    ///         regular expression to compile.
    /// \param  flags Optional bitmask that determines how the pat string is
    ///         interpreted. (See syntax_option_type.)
    /// \return A basic_regex object corresponding to the regular expression
    ///         represented by the character range.
    /// \pre    [begin,end) is a valid range.
    /// \pre    The range of characters specified by [begin,end) contains a
    ///         valid string-based representation of a regular expression.
    /// \throw  regex_error when the range of characters has invalid regular
    ///         expression syntax.
    template<typename InputIter>
    static basic_regex<BidiIter> compile(InputIter begin, InputIter end, flag_type flags = regex_constants::ECMAScript)
    {
        return regex_compiler<BidiIter>().compile(begin, end, flags);
    }

    /// \overload
    ///
    template<typename InputRange>
    static basic_regex<BidiIter> compile(InputRange const &pat, flag_type flags = regex_constants::ECMAScript)
    {
        return regex_compiler<BidiIter>().compile(pat, flags);
    }

    /// \overload
    ///
    static basic_regex<BidiIter> compile(char_type const *begin, flag_type flags = regex_constants::ECMAScript)
    {
        return regex_compiler<BidiIter>().compile(begin, flags);
    }

    /// \overload
    ///
    static basic_regex<BidiIter> compile(char_type const *begin, std::size_t len, flag_type flags)
    {
        return regex_compiler<BidiIter>().compile(begin, len, flags);
    }

private:
    friend struct detail::core_access<BidiIter>;

    // Avoid a common programming mistake. Construction from a string is
    // ambiguous. It could mean:
    //   sregex rx = sregex::compile(str); // compile the string into a regex
    // or
    //   sregex rx = as_xpr(str);          // treat the string as a literal
    // Since there is no easy way to disambiguate, it is disallowed. You must
    // say what you mean.

    /// INTERNAL ONLY
    basic_regex(char_type const *);
    /// INTERNAL ONLY
    basic_regex(string_type const &);

    /// INTERNAL ONLY
    bool match_(detail::match_state<BidiIter> &state) const
    {
        #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
        bool success = false, stack_error = false;
        __try
        {
            success = proto::value(*this)->xpr_->match(state);
        }
        __except(_exception_code() == 0xC00000FDUL)
        {
            stack_error = true;
            _resetstkoflw();
        }
        detail::throw_on_stack_error(stack_error);
        return success;
        #else
        return proto::value(*this)->xpr_->match(state);
        #endif
    }

    // Compiles valid static regexes into a state machine.
    /// INTERNAL ONLY
    template<typename Expr>
    void compile_(Expr const &expr, mpl::true_)
    {
        detail::static_compile(expr, proto::value(*this).get());
    }

    // No-op for invalid static regexes.
    /// INTERNAL ONLY
    template<typename Expr>
    void compile_(Expr const &, mpl::false_)
    {
    }
};

#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ECMAScript;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::icase;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::nosubs;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::optimize;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::collate;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::single_line;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_null;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_newline;
template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ignore_white_space;
#endif

///////////////////////////////////////////////////////////////////////////////
// swap
/// \brief      Swaps the contents of two basic_regex objects.
/// \param      left The first basic_regex object.
/// \param      right The second basic_regex object.
/// \attention  This is a shallow swap that does not do reference tracking.
///             If you embed a basic_regex object by reference in another
///             regular expression and then swap its contents with another
///             basic_regex object, the change will not be visible to the
///             enclosing regular expression. It is done this way to ensure
///             that swap() cannot throw.
/// \throw      nothrow
template<typename BidiIter>
inline void swap(basic_regex<BidiIter> &left, basic_regex<BidiIter> &right) // throw()
{
    left.swap(right);
}

}} // namespace boost::xpressive

#endif // BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005
