// class template regex -*- C++ -*-

// Copyright (C) 2007-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/**
 * @file tr1/regex
 * @author Stephen M. Webb  <stephen.webb@bregmasoft.ca>
 * This is a TR1 C++ Library header. 
 */

#ifndef _GLIBCXX_TR1_REGEX
#define _GLIBCXX_TR1_REGEX 1

#pragma GCC system_header

#include <algorithm>
#include <bitset>
#include <iterator>
#include <locale>
#include <stdexcept>
#include <string>
#include <vector>
#include <utility>
#include <sstream>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace tr1
{
/**
 * @defgroup tr1_regex Regular Expressions
 * A facility for performing regular expression pattern matching.
 */
 ///@{

/** @namespace std::regex_constants
 *  @brief ISO C++ 0x entities sub namespace for regex.
 */
namespace regex_constants
{
  /**
   * @name 5.1 Regular Expression Syntax Options
   */
  ///@{
  enum __syntax_option
    {
      _S_icase,
      _S_nosubs,
      _S_optimize,
      _S_collate,
      _S_ECMAScript,
      _S_basic,
      _S_extended,
      _S_awk,
      _S_grep,
      _S_egrep,
      _S_syntax_last
    };

  /**
   * @brief This is a bitmask type indicating how to interpret the regex.
   *
   * The @c syntax_option_type is implementation defined but it is valid to
   * perform bitwise operations on these values and expect the right thing to
   * happen.
   *
   * A valid value of type syntax_option_type shall have exactly one of the
   * elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep
   * %set.
   */
  typedef unsigned int syntax_option_type;

  /** 
   * Specifies that the matching of regular expressions against a character
   * sequence shall be performed without regard to case.
   */
  static const syntax_option_type icase      = 1 << _S_icase;

  /**
   * Specifies that when a regular expression is matched against a character
   * container sequence, no sub-expression matches are to be stored in the
   * supplied match_results structure.
   */
  static const syntax_option_type nosubs     = 1 << _S_nosubs;

  /**
   * Specifies that the regular expression engine should pay more attention to
   * the speed with which regular expressions are matched, and less to the
   * speed with which regular expression objects are constructed. Otherwise
   * it has no detectable effect on the program output.
   */
  static const syntax_option_type optimize   = 1 << _S_optimize;

  /**
   * Specifies that character ranges of the form [a-b] should be locale
   * sensitive.
   */
  static const syntax_option_type collate    = 1 << _S_collate;

  /**
   * Specifies that the grammar recognized by the regular expression engine is
   * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript
   * Language Specification, Standard Ecma-262, third edition, 1999], as
   * modified in tr1 section [7.13].  This grammar is similar to that defined
   * in the PERL scripting language but extended with elements found in the
   * POSIX regular expression grammar.
   */
  static const syntax_option_type ECMAScript = 1 << _S_ECMAScript;

  /**
   * Specifies that the grammar recognized by the regular expression engine is
   * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001,
   * Portable Operating System Interface (POSIX), Base Definitions and
   * Headers, Section 9, Regular Expressions [IEEE, Information Technology --
   * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
   */
  static const syntax_option_type basic      = 1 << _S_basic;

  /**
   * Specifies that the grammar recognized by the regular expression engine is
   * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001,
   * Portable Operating System Interface (POSIX), Base Definitions and Headers,
   * Section 9, Regular Expressions.
   */
  static const syntax_option_type extended   = 1 << _S_extended;

  /**
   * Specifies that the grammar recognized by the regular expression engine is
   * that used by POSIX utility awk in IEEE Std 1003.1-2001.  This option is
   * identical to syntax_option_type extended, except that C-style escape
   * sequences are supported.  These sequences are: 
   * \\\\, \\a, \\b, \\f, 
   * \\n, \\r, \\t , \\v, 
   * \\&apos;, &apos;, and \\ddd 
   * (where ddd is one, two, or three octal digits).  
   */
  static const syntax_option_type awk        = 1 << _S_awk;

  /**
   * Specifies that the grammar recognized by the regular expression engine is
   * that used by POSIX utility grep in IEEE Std 1003.1-2001.  This option is
   * identical to syntax_option_type basic, except that newlines are treated
   * as whitespace.
   */
  static const syntax_option_type grep       = 1 << _S_grep;

  /**
   * Specifies that the grammar recognized by the regular expression engine is
   * that used by POSIX utility grep when given the -E option in
   * IEEE Std 1003.1-2001.  This option is identical to syntax_option_type 
   * extended, except that newlines are treated as whitespace.
   */
  static const syntax_option_type egrep      = 1 << _S_egrep;

  ///@}

  /**
   * @name 5.2 Matching Rules
   *
   * Matching a regular expression against a sequence of characters [first,
   * last) proceeds according to the rules of the grammar specified for the
   * regular expression object, modified according to the effects listed
   * below for any bitmask elements set.
   *
   */
  ///@{

  enum __match_flag
    {
      _S_not_bol,
      _S_not_eol,
      _S_not_bow,
      _S_not_eow,
      _S_any,
      _S_not_null,
      _S_continuous,
      _S_prev_avail,
      _S_sed,
      _S_no_copy,
      _S_first_only,
      _S_match_flag_last
    };

  /**
   * @brief This is a bitmask type indicating regex matching rules.
   *
   * The @c match_flag_type is implementation defined but it is valid to
   * perform bitwise operations on these values and expect the right thing to
   * happen.
   */
  typedef std::bitset<_S_match_flag_last> match_flag_type;

  /**
   * The default matching rules.
   */
  static const match_flag_type match_default     = 0;

  /**
   * The first character in the sequence [first, last) is treated as though it
   * is not at the beginning of a line, so the character (^) in the regular
   * expression shall not match [first, first).
   */
  static const match_flag_type match_not_bol     = 1 << _S_not_bol;

  /**
   * The last character in the sequence [first, last) is treated as though it
   * is not at the end of a line, so the character ($) in the regular
   * expression shall not match [last, last).
   */
  static const match_flag_type match_not_eol     = 1 << _S_not_eol;
   
  /**
   * The expression \\b is not matched against the sub-sequence
   * [first,first).
   */
  static const match_flag_type match_not_bow     = 1 << _S_not_bow;
   
  /**
   * The expression \\b should not be matched against the sub-sequence
   * [last,last).
   */
  static const match_flag_type match_not_eow     = 1 << _S_not_eow;
   
  /**
   * If more than one match is possible then any match is an acceptable
   * result.
   */
  static const match_flag_type match_any         = 1 << _S_any;
   
  /**
   * The expression does not match an empty sequence.
   */
  static const match_flag_type match_not_null    = 1 << _S_not_null;
   
  /**
   * The expression only matches a sub-sequence that begins at first .
   */
  static const match_flag_type match_continuous  = 1 << _S_continuous;
   
  /**
   * --first is a valid iterator position.  When this flag is set then the
   * flags match_not_bol and match_not_bow are ignored by the regular
   * expression algorithms 7.11 and iterators 7.12.
   */
  static const match_flag_type match_prev_avail  = 1 << _S_prev_avail;

  /**
   * When a regular expression match is to be replaced by a new string, the
   * new string is constructed using the rules used by the ECMAScript replace
   * function in ECMA- 262 [Ecma International, ECMAScript Language
   * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11
   * String.prototype.replace. In addition, during search and replace
   * operations all non-overlapping occurrences of the regular expression
   * are located and replaced, and sections of the input that did not match
   * the expression are copied unchanged to the output string.
   * 
   * Format strings (from ECMA-262 [15.5.4.11]):
   * @li $$  The dollar-sign itself ($)
   * @li $&  The matched substring.
   * @li $`  The portion of @a string that precedes the matched substring.
   *         This would be match_results::prefix().
   * @li $'  The portion of @a string that follows the matched substring.
   *         This would be match_results::suffix().
   * @li $n  The nth capture, where n is in [1,9] and $n is not followed by a
   *         decimal digit.  If n <= match_results::size() and the nth capture
   *         is undefined, use the empty string instead.  If n >
   *         match_results::size(), the result is implementation-defined.
   * @li $nn The nnth capture, where nn is a two-digit decimal number on
   *         [01, 99].  If nn <= match_results::size() and the nth capture is
   *         undefined, use the empty string instead. If
   *         nn > match_results::size(), the result is implementation-defined.
   */
  static const match_flag_type format_default    = 0;

  /**
   * When a regular expression match is to be replaced by a new string, the
   * new string is constructed using the rules used by the POSIX sed utility
   * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable
   * Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
   */
  static const match_flag_type format_sed        = 1 << _S_sed;

  /**
   * During a search and replace operation, sections of the character
   * container sequence being searched that do not match the regular
   * expression shall not be copied to the output string.
   */
  static const match_flag_type format_no_copy    = 1 << _S_no_copy;

  /**
   * When specified during a search and replace operation, only the first
   * occurrence of the regular expression shall be replaced.
   */
  static const match_flag_type format_first_only = 1 << _S_first_only;

  ///@}

  /**
   * @name 5.3 Error Types
   */
  ///@{
 
  enum error_type
    {
      _S_error_collate,
      _S_error_ctype,
      _S_error_escape,
      _S_error_backref,
      _S_error_brack,
      _S_error_paren,
      _S_error_brace,
      _S_error_badbrace,
      _S_error_range,
      _S_error_space,
      _S_error_badrepeat,
      _S_error_complexity,
      _S_error_stack,
      _S_error_last
    };

  /** The expression contained an invalid collating element name. */
  static const error_type error_collate(_S_error_collate);

  /** The expression contained an invalid character class name. */
  static const error_type error_ctype(_S_error_ctype);

  /**
   * The expression contained an invalid escaped character, or a trailing
   * escape.
   */
  static const error_type error_escape(_S_error_escape);

  /** The expression contained an invalid back reference. */
  static const error_type error_backref(_S_error_backref);

  /** The expression contained mismatched [ and ]. */
  static const error_type error_brack(_S_error_brack);

  /** The expression contained mismatched ( and ). */
  static const error_type error_paren(_S_error_paren);

  /** The expression contained mismatched { and } */
  static const error_type error_brace(_S_error_brace);

  /** The expression contained an invalid range in a {} expression. */
  static const error_type error_badbrace(_S_error_badbrace);

  /**
   * The expression contained an invalid character range,
   * such as [b-a] in most encodings.
   */
  static const error_type error_range(_S_error_range);

  /**
   * There was insufficient memory to convert the expression into a
   * finite state machine.
   */
  static const error_type error_space(_S_error_space);

  /**
   * One of <em>*?+{</em> was not preceded by a valid regular expression.
   */
  static const error_type error_badrepeat(_S_error_badrepeat);

  /**
   * The complexity of an attempted match against a regular expression
   * exceeded a pre-set level.
   */
  static const error_type error_complexity(_S_error_complexity);

  /**
   * There was insufficient memory to determine whether the
   * regular expression could match the specified character sequence.
   */
  static const error_type error_stack(_S_error_stack);

  ///@}
}

  // [7.8] Class regex_error
  /**
   *  @brief A regular expression exception class.
   *  @ingroup exceptions
   *
   *  The regular expression library throws objects of this class on error.
   */
  class regex_error
  : public std::runtime_error
  {
  public:
    /**
     * @brief Constructs a regex_error object.
     *
     * @param ecode the regex error code.
     */
    explicit
    regex_error(regex_constants::error_type __ecode)
    : std::runtime_error("regex_error"), _M_code(__ecode)
    { }

    /**
     * @brief Gets the regex error code.
     *
     * @returns the regex error code.
     */
    regex_constants::error_type
    code() const
    { return _M_code; }

  protected:
    regex_constants::error_type _M_code;
  };

  // [7.7] Class regex_traits
  /**
   * @brief Describes aspects of a regular expression.
   *
   * A regular expression traits class that satisfies the requirements of tr1
   * section [7.2].
   *
   * The class %regex is parameterized around a set of related types and
   * functions used to complete the definition of its semantics.  This class
   * satisfies the requirements of such a traits class.
   */
  template<typename _Ch_type>
    struct regex_traits
    {
    public:
      typedef _Ch_type                     char_type;
      typedef std::basic_string<char_type> string_type;
      typedef std::locale                  locale_type;
      typedef std::ctype_base::mask        char_class_type;

    public:
      /**
       * @brief Constructs a default traits object.
       */
      regex_traits()
      { }
      
      /**
       * @brief Gives the length of a C-style string starting at @p __p.
       *
       * @param __p a pointer to the start of a character sequence.
       *
       * @returns the number of characters between @p *__p and the first
       * default-initialized value of type @p char_type.  In other words, uses
       * the C-string algorithm for determining the length of a sequence of
       * characters.
       */
      static std::size_t
      length(const char_type* __p)
      { return string_type::traits_type::length(__p); }

      /**
       * @brief Performs the identity translation.
       *
       * @param c A character to the locale-specific character set.
       *
       * @returns c.
       */
      char_type
      translate(char_type __c) const
      { return __c; }
      
      /**
       * @brief Translates a character into a case-insensitive equivalent.
       *
       * @param c A character to the locale-specific character set.
       *
       * @returns the locale-specific lower-case equivalent of c.
       * @throws std::bad_cast if the imbued locale does not support the ctype
       *         facet.
       */
      char_type
      translate_nocase(char_type __c) const
      {
	using std::ctype;
	using std::use_facet;
	return use_facet<ctype<char_type> >(_M_locale).tolower(__c);
      }
      
      /**
       * @brief Gets a sort key for a character sequence.
       *
       * @param first beginning of the character sequence.
       * @param last  one-past-the-end of the character sequence.
       *
       * Returns a sort key for the character sequence designated by the
       * iterator range [F1, F2) such that if the character sequence [G1, G2)
       * sorts before the character sequence [H1, H2) then
       * v.transform(G1, G2) < v.transform(H1, H2).
       *
       * What this really does is provide a more efficient way to compare a
       * string to multiple other strings in locales with fancy collation
       * rules and equivalence classes.
       *
       * @returns a locale-specific sort key equivalent to the input range.
       *
       * @throws std::bad_cast if the current locale does not have a collate
       *         facet.
       */
      template<typename _Fwd_iter>
        string_type
        transform(_Fwd_iter __first, _Fwd_iter __last) const
        {
	  using std::collate;
	  using std::use_facet;
	  const collate<_Ch_type>& __c(use_facet<
				       collate<_Ch_type> >(_M_locale));
	  string_type __s(__first, __last);
	  return __c.transform(__s.data(), __s.data() + __s.size());
	}

      /**
       * @brief Dunno.
       *
       * @param first beginning of the character sequence.
       * @param last  one-past-the-end of the character sequence.
       *
       * Effects: if typeid(use_facet<collate<_Ch_type> >) ==
       * typeid(collate_byname<_Ch_type>) and the form of the sort key
       * returned by collate_byname<_Ch_type>::transform(first, last) is known
       * and can be converted into a primary sort key then returns that key,
       * otherwise returns an empty string. WTF??
       *
       * @todo Implement this function.
       */
      template<typename _Fwd_iter>
        string_type
        transform_primary(_Fwd_iter __first, _Fwd_iter __last) const;

      /**
       * @brief Gets a collation element by name.
       *
       * @param first beginning of the collation element name.
       * @param last  one-past-the-end of the collation element name.
       * 
       * @returns a sequence of one or more characters that represents the
       * collating element consisting of the character sequence designated by
       * the iterator range [first, last). Returns an empty string if the
       * character sequence is not a valid collating element.
       *
       * @todo Implement this function.
       */
      template<typename _Fwd_iter>
        string_type
        lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const;

      /**
       * @brief Maps one or more characters to a named character
       *        classification.
       *
       * @param first beginning of the character sequence.
       * @param last  one-past-the-end of the character sequence.
       *
       * @returns an unspecified value that represents the character
       * classification named by the character sequence designated by the
       * iterator range [first, last). The value returned shall be independent
       * of the case of the characters in the character sequence. If the name
       * is not recognized then returns a value that compares equal to 0.
       *
       * At least the following names (or their wide-character equivalent) are
       * supported.
       * - d
       * - w
       * - s
       * - alnum
       * - alpha
       * - blank
       * - cntrl
       * - digit
       * - graph
       * - lower
       * - print
       * - punct
       * - space
       * - upper
       * - xdigit
       *
       * @todo Implement this function.
       */
      template<typename _Fwd_iter>
        char_class_type
        lookup_classname(_Fwd_iter __first, _Fwd_iter __last) const;

      /**
       * @brief Determines if @p c is a member of an identified class.
       *
       * @param c a character.
       * @param f a class type (as returned from lookup_classname).
       *
       * @returns true if the character @p c is a member of the classification
       * represented by @p f, false otherwise.
       *
       * @throws std::bad_cast if the current locale does not have a ctype
       *         facet.
       */
      bool
      isctype(_Ch_type __c, char_class_type __f) const;

      /**
       * @brief Converts a digit to an int.
       *
       * @param ch    a character representing a digit.
       * @param radix the radix if the numeric conversion (limited to 8, 10,
       *              or 16).
       * 
       * @returns the value represented by the digit ch in base radix if the
       * character ch is a valid digit in base radix; otherwise returns -1.
       */
      int
      value(_Ch_type __ch, int __radix) const;
      
      /**
       * @brief Imbues the regex_traits object with a copy of a new locale.
       *
       * @param loc A locale.
       *
       * @returns a copy of the previous locale in use by the regex_traits
       *          object.
       *
       * @note Calling imbue with a different locale than the one currently in
       *       use invalidates all cached data held by *this.
       */
      locale_type
      imbue(locale_type __loc)
      {
	std::swap(_M_locale, __loc);
	return __loc;
      }
      
      /**
       * @brief Gets a copy of the current locale in use by the regex_traits
       * object.
       */
      locale_type
      getloc() const
      { return _M_locale; }
      
    protected:
      locale_type _M_locale;
    };

  template<typename _Ch_type>
    bool regex_traits<_Ch_type>::
    isctype(_Ch_type __c, char_class_type __f) const
    {
      using std::ctype;
      using std::use_facet;
      const ctype<_Ch_type>& __ctype(use_facet<
				     ctype<_Ch_type> >(_M_locale));
      
      if (__ctype.is(__c, __f))
	return true;
#if 0
      // special case of underscore in [[:w:]]
      if (__c == __ctype.widen('_'))
	{
	  const char* const __wb[] = "w";
	  char_class_type __wt = this->lookup_classname(__wb,
							__wb + sizeof(__wb));
	  if (__f | __wt)
	    return true;
	}
    
      // special case of [[:space:]] in [[:blank:]]
      if (__c == __ctype.isspace(__c))
	{
	  const char* const __bb[] = "blank";
	  char_class_type __bt = this->lookup_classname(__bb,
							__bb + sizeof(__bb));
	  if (__f | __bt)
	    return true;
	}
#endif
      return false;
    }

  template<typename _Ch_type>
    int regex_traits<_Ch_type>::
    value(_Ch_type __ch, int __radix) const
    {
      std::basic_istringstream<_Ch_type> __is(string_type(1, __ch));
      int __v;
      if (__radix == 8)
	__is >> std::oct;
      else if (__radix == 16)
	__is >> std::hex;
      __is >> __v;
      return __is.fail() ? -1 : __v;
    }

  // [7.8] Class basic_regex
  /**
   * Objects of specializations of this class represent regular expressions
   * constructed from sequences of character type @p _Ch_type.
   *
   * Storage for the regular expression is allocated and deallocated as
   * necessary by the member functions of this class.
   */
  template<typename _Ch_type, typename _Rx_traits = regex_traits<_Ch_type> >
    class basic_regex
    {
    public:
      // types:
      typedef _Ch_type                              value_type;
      typedef regex_constants::syntax_option_type flag_type;
      typedef typename _Rx_traits::locale_type  locale_type;
      typedef typename _Rx_traits::string_type  string_type;

      /**
       * @name Constants
       * tr1 [7.8.1] std [28.8.1]
       */
      ///@{
      static const regex_constants::syntax_option_type icase
        = regex_constants::icase;
      static const regex_constants::syntax_option_type nosubs
        = regex_constants::nosubs;
      static const regex_constants::syntax_option_type optimize
        = regex_constants::optimize;
      static const regex_constants::syntax_option_type collate
        = regex_constants::collate;
      static const regex_constants::syntax_option_type ECMAScript
        = regex_constants::ECMAScript;
      static const regex_constants::syntax_option_type basic
        = regex_constants::basic;
      static const regex_constants::syntax_option_type extended
        = regex_constants::extended;
      static const regex_constants::syntax_option_type awk
        = regex_constants::awk;
      static const regex_constants::syntax_option_type grep
        = regex_constants::grep;
      static const regex_constants::syntax_option_type egrep
        = regex_constants::egrep;
      ///@}

      // [7.8.2] construct/copy/destroy
      /**
       * Constructs a basic regular expression that does not match any
       * character sequence.
       */
      basic_regex()
      : _M_flags(regex_constants::ECMAScript), _M_pattern(), _M_mark_count(0)
      { _M_compile(); }

      /**
       * @brief Constructs a basic regular expression from the sequence
       * [p, p + char_traits<_Ch_type>::length(p)) interpreted according to the
       * flags in @p f.
       *
       * @param p A pointer to the start of a C-style null-terminated string
       *          containing a regular expression.
       * @param f Flags indicating the syntax rules and options.
       *
       * @throws regex_error if @p p is not a valid regular expression.
       */
      explicit
      basic_regex(const _Ch_type* __p,
		  flag_type __f = regex_constants::ECMAScript)
      : _M_flags(__f), _M_pattern(__p), _M_mark_count(0)
      { _M_compile(); }

      /**
       * @brief Constructs a basic regular expression from the sequence
       * [p, p + len) interpreted according to the flags in @p f.
       *
       * @param p   A pointer to the start of a string containing a regular
       *            expression.
       * @param len The length of the string containing the regular expression.
       * @param f   Flags indicating the syntax rules and options.
       *
       * @throws regex_error if @p p is not a valid regular expression.
       */
      basic_regex(const _Ch_type* __p, std::size_t __len, flag_type __f)
      : _M_flags(__f) , _M_pattern(__p, __len), _M_mark_count(0)
      { _M_compile(); }

      /**
       * @brief Copy-constructs a basic regular expression.
       *
       * @param rhs A @p regex object.
     */
      basic_regex(const basic_regex& __rhs)
      : _M_flags(__rhs._M_flags), _M_pattern(__rhs._M_pattern),
	_M_mark_count(__rhs._M_mark_count)
      { _M_compile(); }

      /**
       * @brief Constructs a basic regular expression from the string
       * @p s interpreted according to the flags in @p f.
       *
       * @param s A string containing a regular expression.
       * @param f Flags indicating the syntax rules and options.
       *
       * @throws regex_error if @p s is not a valid regular expression.
       */
      template<typename _Ch_traits, typename _Ch_alloc>
        explicit
        basic_regex(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s,
		    flag_type __f = regex_constants::ECMAScript)
	: _M_flags(__f), _M_pattern(__s.begin(), __s.end()), _M_mark_count(0)
        { _M_compile(); }

      /**
       * @brief Constructs a basic regular expression from the range
       * [first, last) interpreted according to the flags in @p f.
       *
       * @param first The start of a range containing a valid regular
       *              expression.
       * @param last  The end of a range containing a valid regular
       *              expression.
       * @param f     The format flags of the regular expression.
       *
       * @throws regex_error if @p [first, last) is not a valid regular
       *         expression.
       */
      template<typename _InputIterator>
        basic_regex(_InputIterator __first, _InputIterator __last, 
		    flag_type __f = regex_constants::ECMAScript)
	: _M_flags(__f), _M_pattern(__first, __last), _M_mark_count(0)
        { _M_compile(); }

#ifdef _GLIBCXX_INCLUDE_AS_CXX11
      /**
       * @brief Constructs a basic regular expression from an initializer list.
       *
       * @param l  The initializer list.
       * @param f  The format flags of the regular expression.
       *
       * @throws regex_error if @p l is not a valid regular expression.
       */
      basic_regex(initializer_list<_Ch_type> __l,
		  flag_type __f = regex_constants::ECMAScript)
	: _M_flags(__f), _M_pattern(__l.begin(), __l.end()), _M_mark_count(0)
        { _M_compile(); }
#endif

      /**
       * @brief Destroys a basic regular expression.
       */
      ~basic_regex()
      { }
      
      /**
       * @brief Assigns one regular expression to another.
       */
      basic_regex&
      operator=(const basic_regex& __rhs)
      { return this->assign(__rhs); }

      /**
       * @brief Replaces a regular expression with a new one constructed from
       * a C-style null-terminated string.
       *
       * @param A pointer to the start of a null-terminated C-style string
       *        containing a regular expression.
       */
      basic_regex&
      operator=(const _Ch_type* __p)
      { return this->assign(__p, flags()); }
      
      /**
       * @brief Replaces a regular expression with a new one constructed from
       * a string.
       *
       * @param A pointer to a string containing a regular expression.
       */
      template<typename _Ch_typeraits, typename _Allocator>
        basic_regex&
        operator=(const basic_string<_Ch_type, _Ch_typeraits, _Allocator>& __s)
        { return this->assign(__s, flags()); }

      // [7.8.3] assign
      /**
       * @brief the real assignment operator.
       *
       * @param that Another regular expression object.
       */
      basic_regex&
      assign(const basic_regex& __that)
      {
	basic_regex __tmp(__that);
	this->swap(__tmp);
	return *this;
      }
      
      /**
       * @brief Assigns a new regular expression to a regex object from a
       * C-style null-terminated string containing a regular expression
       * pattern.
       *
       * @param p     A pointer to a C-style null-terminated string containing
       *              a regular expression pattern.
       * @param flags Syntax option flags.
       *
       * @throws regex_error if p does not contain a valid regular expression
       * pattern interpreted according to @p flags.  If regex_error is thrown,
       * *this remains unchanged.
       */
      basic_regex&
      assign(const _Ch_type* __p,
	     flag_type __flags = regex_constants::ECMAScript)
      { return this->assign(string_type(__p), __flags); }

      /**
       * @brief Assigns a new regular expression to a regex object from a
       * C-style string containing a regular expression pattern.
       *
       * @param p     A pointer to a C-style string containing a
       *              regular expression pattern.
       * @param len   The length of the regular expression pattern string.
       * @param flags Syntax option flags.
       *
       * @throws regex_error if p does not contain a valid regular expression
       * pattern interpreted according to @p flags.  If regex_error is thrown,
       * *this remains unchanged.
       */
      basic_regex&
      assign(const _Ch_type* __p, std::size_t __len, flag_type __flags)
      { return this->assign(string_type(__p, __len), __flags); }

      /**
       * @brief Assigns a new regular expression to a regex object from a 
       * string containing a regular expression pattern.
       *
       * @param s     A string containing a regular expression pattern.
       * @param flags Syntax option flags.
       *
       * @throws regex_error if p does not contain a valid regular expression
       * pattern interpreted according to @p flags.  If regex_error is thrown,
       * *this remains unchanged.
       */
      template<typename _Ch_typeraits, typename _Allocator>
        basic_regex&
        assign(const basic_string<_Ch_type, _Ch_typeraits, _Allocator>& __s,
	       flag_type __f = regex_constants::ECMAScript)
        { 
	  basic_regex __tmp(__s, __f);
	  this->swap(__tmp);
	  return *this;
	}

      /**
       * @brief Assigns a new regular expression to a regex object.
       *
       * @param first The start of a range containing a valid regular
       *              expression.
       * @param last  The end of a range containing a valid regular
       *              expression.
       * @param flags Syntax option flags.
       *
       * @throws regex_error if p does not contain a valid regular expression
       * pattern interpreted according to @p flags.  If regex_error is thrown,
       * the object remains unchanged.
       */
      template<typename _InputIterator>
        basic_regex&
        assign(_InputIterator __first, _InputIterator __last,
	       flag_type __flags = regex_constants::ECMAScript)
        { return this->assign(string_type(__first, __last), __flags); }

#ifdef _GLIBCXX_INCLUDE_AS_CXX11
      /**
       * @brief Assigns a new regular expression to a regex object.
       *
       * @param l     An initializer list representing a regular expression.
       * @param flags Syntax option flags.
       *
       * @throws regex_error if @p l does not contain a valid regular
       * expression pattern interpreted according to @p flags.  If regex_error
       * is thrown, the object remains unchanged.
       */
      basic_regex&
      assign(initializer_list<_Ch_type> __l,
	     flag_type __f = regex_constants::ECMAScript)
      { return this->assign(__l.begin(), __l.end(), __f); }
#endif

      // [7.8.4] const operations
      /**
       * @brief Gets the number of marked subexpressions within the regular
       * expression.
       */
      unsigned int
      mark_count() const
      { return _M_mark_count; }
      
      /**
       * @brief Gets the flags used to construct the regular expression
       * or in the last call to assign().
       */
      flag_type
      flags() const
      { return _M_flags; }
      
      // [7.8.5] locale
      /**
       * @brief Imbues the regular expression object with the given locale.
       *
       * @param loc A locale.
       */
      locale_type
      imbue(locale_type __loc)
      { return _M_traits.imbue(__loc); }
      
      /**
       * @brief Gets the locale currently imbued in the regular expression
       *        object.
       */
      locale_type
      getloc() const
      { return _M_traits.getloc(); }
      
      // [7.8.6] swap
      /**
       * @brief Swaps the contents of two regular expression objects.
       *
       * @param rhs Another regular expression object.
       */
      void
      swap(basic_regex& __rhs)
      {
	std::swap(_M_flags,      __rhs._M_flags);
	std::swap(_M_pattern,    __rhs._M_pattern);
	std::swap(_M_mark_count, __rhs._M_mark_count);
	std::swap(_M_traits,     __rhs._M_traits);
      }
      
    private:
      /**
       * @brief Compiles a regular expression pattern into a NFA.
       * @todo Implement this function.
       */
      void _M_compile();

    protected:
      flag_type    _M_flags;
      string_type  _M_pattern;
      unsigned int _M_mark_count;
      _Rx_traits   _M_traits;
    };
  
  /** @brief Standard regular expressions. */
  typedef basic_regex<char>    regex;
#ifdef _GLIBCXX_USE_WCHAR_T
  /** @brief Standard wide-character regular expressions. */
  typedef basic_regex<wchar_t> wregex;
#endif


  // [7.8.6] basic_regex swap
  /**
   * @brief Swaps the contents of two regular expression objects.
   * @param lhs First regular expression.
   * @param rhs Second regular expression.
   */
  template<typename _Ch_type, typename _Rx_traits>
    inline void
    swap(basic_regex<_Ch_type, _Rx_traits>& __lhs,
	 basic_regex<_Ch_type, _Rx_traits>& __rhs)
    { __lhs.swap(__rhs); }


  // [7.9] Class template sub_match
  /**
   * A sequence of characters matched by a particular marked sub-expression.
   *
   * An object of this class is essentially a pair of iterators marking a
   * matched subexpression within a regular expression pattern match. Such
   * objects can be converted to and compared with std::basic_string objects
   * of a similar base character type as the pattern matched by the regular
   * expression.
   *
   * The iterators that make up the pair are the usual half-open interval
   * referencing the actual original pattern matched.
   */
  template<typename _BiIter>
    class sub_match : public std::pair<_BiIter, _BiIter>
    {
    public:
      typedef typename iterator_traits<_BiIter>::value_type      value_type;
      typedef typename iterator_traits<_BiIter>::difference_type
                                                            difference_type;
      typedef _BiIter                                              iterator;

    public:
      bool matched;
      
      /**
       * Gets the length of the matching sequence.
       */
      difference_type
      length() const
      { return this->matched ? std::distance(this->first, this->second) : 0; }

      /**
       * @brief Gets the matching sequence as a string.
       *
       * @returns the matching sequence as a string.
       *
       * This is the implicit conversion operator.  It is identical to the
       * str() member function except that it will want to pop up in
       * unexpected places and cause a great deal of confusion and cursing
       * from the unwary.
       */
      operator basic_string<value_type>() const
      {
	return this->matched
	  ? std::basic_string<value_type>(this->first, this->second)
	  : std::basic_string<value_type>();
      }
      
      /**
       * @brief Gets the matching sequence as a string.
       *
       * @returns the matching sequence as a string.
       */
      basic_string<value_type>
      str() const
      {
	return this->matched
	  ? std::basic_string<value_type>(this->first, this->second)
	  : std::basic_string<value_type>();
      }
      
      /**
       * @brief Compares this and another matched sequence.
       *
       * @param s Another matched sequence to compare to this one.
       *
       * @retval <0 this matched sequence will collate before @p s.
       * @retval =0 this matched sequence is equivalent to @p s.
       * @retval <0 this matched sequence will collate after @p s.
       */
      int
      compare(const sub_match& __s) const
      { return this->str().compare(__s.str()); }

      /**
       * @brief Compares this sub_match to a string.
       *
       * @param s A string to compare to this sub_match.
       *
       * @retval <0 this matched sequence will collate before @p s.
       * @retval =0 this matched sequence is equivalent to @p s.
       * @retval <0 this matched sequence will collate after @p s.
       */
      int
      compare(const basic_string<value_type>& __s) const
      { return this->str().compare(__s); }
      
      /**
       * @brief Compares this sub_match to a C-style string.
       *
       * @param s A C-style string to compare to this sub_match.
       *
       * @retval <0 this matched sequence will collate before @p s.
       * @retval =0 this matched sequence is equivalent to @p s.
       * @retval <0 this matched sequence will collate after @p s.
       */
      int
      compare(const value_type* __s) const
      { return this->str().compare(__s); }
    };
  
  
  /** @brief Standard regex submatch over a C-style null-terminated string. */
  typedef sub_match<const char*>             csub_match;
  /** @brief Standard regex submatch over a standard string. */
  typedef sub_match<string::const_iterator>  ssub_match;
#ifdef _GLIBCXX_USE_WCHAR_T
  /** @brief Regex submatch over a C-style null-terminated wide string. */
  typedef sub_match<const wchar_t*>          wcsub_match;
  /** @brief Regex submatch over a standard wide string. */
  typedef sub_match<wstring::const_iterator> wssub_match;
#endif

  // [7.9.2] sub_match non-member operators
  
  /**
   * @brief Tests the equivalence of two regular expression submatches.
   * @param lhs First regular expression submatch.
   * @param rhs Second regular expression submatch.
   * @returns true if @a lhs  is equivalent to @a rhs, false otherwise.
   */
  template<typename _BiIter>
    inline bool
    operator==(const sub_match<_BiIter>& __lhs,
	       const sub_match<_BiIter>& __rhs)
    { return __lhs.compare(__rhs) == 0; }

  /**
   * @brief Tests the inequivalence of two regular expression submatches.
   * @param lhs First regular expression submatch.
   * @param rhs Second regular expression submatch.
   * @returns true if @a lhs  is not equivalent to @a rhs, false otherwise.
   */
  template<typename _BiIter>
    inline bool
    operator!=(const sub_match<_BiIter>& __lhs,
	       const sub_match<_BiIter>& __rhs)
    { return __lhs.compare(__rhs) != 0; }

  /**
   * @brief Tests the ordering of two regular expression submatches.
   * @param lhs First regular expression submatch.
   * @param rhs Second regular expression submatch.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _BiIter>
    inline bool
    operator<(const sub_match<_BiIter>& __lhs,
	      const sub_match<_BiIter>& __rhs)
    { return __lhs.compare(__rhs) < 0; }

  /**
   * @brief Tests the ordering of two regular expression submatches.
   * @param lhs First regular expression submatch.
   * @param rhs Second regular expression submatch.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _BiIter>
    inline bool
    operator<=(const sub_match<_BiIter>& __lhs,
	       const sub_match<_BiIter>& __rhs)
    { return __lhs.compare(__rhs) <= 0; }

  /**
   * @brief Tests the ordering of two regular expression submatches.
   * @param lhs First regular expression submatch.
   * @param rhs Second regular expression submatch.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _BiIter>
    inline bool
    operator>=(const sub_match<_BiIter>& __lhs,
	       const sub_match<_BiIter>& __rhs)
    { return __lhs.compare(__rhs) >= 0; }

  /**
   * @brief Tests the ordering of two regular expression submatches.
   * @param lhs First regular expression submatch.
   * @param rhs Second regular expression submatch.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _BiIter>
    inline bool
    operator>(const sub_match<_BiIter>& __lhs,
	      const sub_match<_BiIter>& __rhs)
    { return __lhs.compare(__rhs) > 0; }

  /**
   * @brief Tests the equivalence of a string and a regular expression
   *        submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs  is equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator==(const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs == __rhs.str(); }

  /**
   * @brief Tests the inequivalence of a string and a regular expression
   *        submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs  is not equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator!=(const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs)
    { return __lhs != __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator<(const basic_string<
	      typename iterator_traits<_Bi_iter>::value_type,
	      _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs)
     { return __lhs < __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator>(const basic_string<
	      typename iterator_traits<_Bi_iter>::value_type, 
	      _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs)
    { return __lhs > __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator>=(const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs)
    { return __lhs >= __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator<=(const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs)
    { return __lhs <= __rhs.str(); }

  /**
   * @brief Tests the equivalence of a regular expression submatch and a
   *        string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs is equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator==(const sub_match<_Bi_iter>& __lhs,
	       const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __rhs)
    { return __lhs.str() == __rhs; }

  /**
   * @brief Tests the inequivalence of a regular expression submatch and a
   *        string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs is not equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
    inline bool
    operator!=(const sub_match<_Bi_iter>& __lhs,
	       const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __rhs)
    { return __lhs.str() != __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc>
    inline bool
    operator<(const sub_match<_Bi_iter>& __lhs,
	      const basic_string<
	      typename iterator_traits<_Bi_iter>::value_type,
	      _Ch_traits, _Ch_alloc>& __rhs)
    { return __lhs.str() < __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc>
    inline bool
    operator>(const sub_match<_Bi_iter>& __lhs,
	      const basic_string<
	      typename iterator_traits<_Bi_iter>::value_type,
	      _Ch_traits, _Ch_alloc>& __rhs)
    { return __lhs.str() > __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc>
    inline bool
    operator>=(const sub_match<_Bi_iter>& __lhs,
	       const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __rhs)
    { return __lhs.str() >= __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc>
    inline bool
    operator<=(const sub_match<_Bi_iter>& __lhs,
	       const basic_string<
	       typename iterator_traits<_Bi_iter>::value_type,
	       _Ch_traits, _Ch_alloc>& __rhs)
    { return __lhs.str() <= __rhs; }

  /**
   * @brief Tests the equivalence of a C string and a regular expression
   *        submatch.
   * @param lhs A C string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs  is equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator==(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs == __rhs.str(); }

  /**
   * @brief Tests the inequivalence of an iterator value and a regular
   *        expression submatch.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs is not equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator!=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs != __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
	      const sub_match<_Bi_iter>& __rhs)
    { return __lhs < __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
	      const sub_match<_Bi_iter>& __rhs)
    { return __lhs > __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs >= __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs <= __rhs.str(); }

  /**
   * @brief Tests the equivalence of a regular expression submatch and a
   *        string.
   * @param lhs A regular expression submatch.
   * @param rhs A pointer to a string?
   * @returns true if @a lhs  is equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator==(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const* __rhs)
    { return __lhs.str() == __rhs; }

  /**
   * @brief Tests the inequivalence of a regular expression submatch and a
   *        string.
   * @param lhs A regular expression submatch.
   * @param rhs A pointer to a string.
   * @returns true if @a lhs is not equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator!=(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const* __rhs)
    { return __lhs.str() != __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<(const sub_match<_Bi_iter>& __lhs,
	      typename iterator_traits<_Bi_iter>::value_type const* __rhs)
    { return __lhs.str() < __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>(const sub_match<_Bi_iter>& __lhs,
	      typename iterator_traits<_Bi_iter>::value_type const* __rhs)
    { return __lhs.str() > __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>=(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const* __rhs)
    { return __lhs.str() >= __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A string.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<=(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const* __rhs)
    { return __lhs.str() <= __rhs; }

  /**
   * @brief Tests the equivalence of a string and a regular expression
   *        submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs is equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator==(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs == __rhs.str(); }

  /**
   * @brief Tests the inequivalence of a string and a regular expression
   *        submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs is not equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator!=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs != __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
	      const sub_match<_Bi_iter>& __rhs)
    { return __lhs < __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
	      const sub_match<_Bi_iter>& __rhs)
    { return __lhs > __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs >= __rhs.str(); }

  /**
   * @brief Tests the ordering of a string and a regular expression submatch.
   * @param lhs A string.
   * @param rhs A regular expression submatch.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
	       const sub_match<_Bi_iter>& __rhs)
    { return __lhs <= __rhs.str(); }

  /**
   * @brief Tests the equivalence of a regular expression submatch and a
   *        string.
   * @param lhs A regular expression submatch.
   * @param rhs A const string reference.
   * @returns true if @a lhs  is equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator==(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const& __rhs)
    { return __lhs.str() == __rhs; }

  /**
   * @brief Tests the inequivalence of a regular expression submatch and a
   *        string.
   * @param lhs A regular expression submatch.
   * @param rhs A const string reference.
   * @returns true if @a lhs is not equivalent to @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator!=(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const& __rhs)
    { return __lhs.str() != __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A const string reference.
   * @returns true if @a lhs precedes @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<(const sub_match<_Bi_iter>& __lhs,
	      typename iterator_traits<_Bi_iter>::value_type const& __rhs)
    { return __lhs.str() < __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A const string reference.
   * @returns true if @a lhs succeeds @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>(const sub_match<_Bi_iter>& __lhs,
	      typename iterator_traits<_Bi_iter>::value_type const& __rhs)
    { return __lhs.str() > __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A const string reference.
   * @returns true if @a lhs does not precede @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator>=(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const& __rhs)
    { return __lhs.str() >= __rhs; }

  /**
   * @brief Tests the ordering of a regular expression submatch and a string.
   * @param lhs A regular expression submatch.
   * @param rhs A const string reference.
   * @returns true if @a lhs does not succeed @a rhs, false otherwise.
   */
  template<typename _Bi_iter>
    inline bool
    operator<=(const sub_match<_Bi_iter>& __lhs,
	       typename iterator_traits<_Bi_iter>::value_type const& __rhs)
    { return __lhs.str() <= __rhs; }

  /**
   * @brief Inserts a matched string into an output stream.
   *
   * @param os The output stream.
   * @param m  A submatch string.
   *
   * @returns the output stream with the submatch string inserted.
   */
  template<typename _Ch_type, typename _Ch_traits, typename _Bi_iter>
    inline
    basic_ostream<_Ch_type, _Ch_traits>&
    operator<<(basic_ostream<_Ch_type, _Ch_traits>& __os,
	       const sub_match<_Bi_iter>& __m)
    { return __os << __m.str(); }

  // [7.10] Class template match_results
  /**
   * @brief The results of a match or search operation.
   *
   * A collection of character 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 template match_results.
   *
   * This class satisfies the Sequence requirements, with the exception that
   * only the operations defined for a const-qualified Sequence are supported.
   *
   * The sub_match object stored at index 0 represents sub-expression 0, i.e.
   * the whole match. In this case the sub_match member matched is always true.
   * The sub_match object stored at index n denotes what matched the marked
   * sub-expression n within the matched expression. If the sub-expression n
   * participated in a regular expression match then the sub_match member
   * matched evaluates to true, and members first and second denote the range
   * of characters [first, second) which formed that match. Otherwise matched
   * is false, and members first and second point to the end of the sequence
   * that was searched.
   *
   * @nosubgrouping
   */
  template<typename _Bi_iter,
	   typename _Allocator = allocator<sub_match<_Bi_iter> > >
    class match_results
    : private std::vector<std::tr1::sub_match<_Bi_iter>, _Allocator>
    {
    private:
      typedef std::vector<std::tr1::sub_match<_Bi_iter>, _Allocator>
                                                              _Base_type;

    public:
      /**
       * @name 10.? Public Types
       */
      ///@{
      typedef sub_match<_Bi_iter>                             value_type;
      typedef typename _Base_type::const_reference            const_reference;
      typedef const_reference                                 reference;
      typedef typename _Base_type::const_iterator             const_iterator;
      typedef const_iterator                                  iterator;
      typedef typename iterator_traits<_Bi_iter>::difference_type
                                                              difference_type;
      typedef typename _Allocator::size_type                  size_type;
      typedef _Allocator                                      allocator_type;
      typedef typename iterator_traits<_Bi_iter>::value_type  char_type;
      typedef basic_string<char_type>                         string_type;
      ///@}
  
    public:
      /**
       * @name 10.1 Construction, Copying, and Destruction
       */
      ///@{

      /**
       * @brief Constructs a default %match_results container.
       * @post size() returns 0 and str() returns an empty string.
       */
      explicit
      match_results(const _Allocator& __a = _Allocator())
      : _Base_type(__a), _M_matched(false)
      { }

      /**
       * @brief Copy constructs a %match_results.
       */
      match_results(const match_results& __rhs)
      : _Base_type(__rhs), _M_matched(__rhs._M_matched),
	_M_prefix(__rhs._M_prefix), _M_suffix(__rhs._M_suffix)
      { }

      /**
       * @brief Assigns rhs to *this.
       */
      match_results&
      operator=(const match_results& __rhs)
      {
	match_results __tmp(__rhs);
	this->swap(__tmp);
	return *this;
      }

      /**
       * @brief Destroys a %match_results object.
       */
      ~match_results()
      { }
      
      ///@}

      /**
       * @name 10.2 Size
       */
      ///@{

      /**
       * @brief Gets the number of matches and submatches.
       *
       * The number of matches for a given regular expression will be either 0
       * if there was no match or mark_count() + 1 if a match was successful.
       * Some matches may be empty.
       *
       * @returns the number of matches found.
       */
      size_type
      size() const
      { return _M_matched ? _Base_type::size() + 1 : 0; }
      
      //size_type
      //max_size() const;
      using _Base_type::max_size;

      /**
       * @brief Indicates if the %match_results contains no results.
       * @retval true The %match_results object is empty.
       * @retval false The %match_results object is not empty.
       */
      _GLIBCXX_NODISCARD bool
      empty() const
      { return size() == 0; }
      
      ///@}

      /**
       * @name 10.3 Element Access
       */
      ///@{

      /**
       * @brief Gets the length of the indicated submatch.
       * @param sub indicates the submatch.
       *
       * This function returns the length of the indicated submatch, or the
       * length of the entire match if @p sub is zero (the default).
       */
      difference_type
      length(size_type __sub = 0) const
      { return _M_matched ? this->str(__sub).length() : 0; }

      /**
       * @brief Gets the offset of the beginning of the indicated submatch.
       * @param sub indicates the submatch.
       *
       * This function returns the offset from the beginning of the target
       * sequence to the beginning of the submatch, unless the value of @p sub
       * is zero (the default), in which case this function returns the offset
       * from the beginning of the target sequence to the beginning of the
       * match.
       */
      difference_type
      position(size_type __sub = 0) const
      {
	return _M_matched ? std::distance(this->prefix().first,
					  (*this)[__sub].first) : 0;
      }

      /**
       * @brief Gets the match or submatch converted to a string type.
       * @param sub indicates the submatch.
       *
       * This function gets the submatch (or match, if @p sub is zero) extracted
       * from the target range and converted to the associated string type.
       */
      string_type
      str(size_type __sub = 0) const
      { return _M_matched ? (*this)[__sub].str() : string_type(); }
      
      /**
       * @brief Gets a %sub_match reference for the match or submatch.
       * @param sub indicates the submatch.
       *
       * This function gets a reference to the indicated submatch, or the entire
       * match if @p sub is zero.
       *
       * If @p sub >= size() then this function returns a %sub_match with a
       * special value indicating no submatch.
       */
      const_reference
      operator[](size_type __sub) const
      { return _Base_type::operator[](__sub); }

      /**
       * @brief Gets a %sub_match representing the match prefix.
       *
       * This function gets a reference to a %sub_match object representing the
       * part of the target range between the start of the target range and the
       * start of the match.
       */
      const_reference
      prefix() const
      { return _M_prefix; }

      /**
       * @brief Gets a %sub_match representing the match suffix.
       *
       * This function gets a reference to a %sub_match object representing the
       * part of the target range between the end of the match and the end of
       * the target range.
       */
      const_reference
      suffix() const
      { return _M_suffix; }

      /**
       * @brief Gets an iterator to the start of the %sub_match collection.
       */
      const_iterator
      begin() const
      { return _Base_type::begin(); }
      
#ifdef _GLIBCXX_INCLUDE_AS_CXX11
      /**
       * @brief Gets an iterator to the start of the %sub_match collection.
       */
      const_iterator
      cbegin() const
      { return _Base_type::begin(); }
#endif

      /**
       * @brief Gets an iterator to one-past-the-end of the collection.
       */
      const_iterator
      end() const
      { return _Base_type::end(); }
      
#ifdef _GLIBCXX_INCLUDE_AS_CXX11
      /**
       * @brief Gets an iterator to one-past-the-end of the collection.
       */
      const_iterator
      cend() const
      { return _Base_type::end(); }
#endif

      ///@}

      /**
       * @name 10.4 Formatting
       *
       * These functions perform formatted substitution of the matched
       * character sequences into their target.  The format specifiers
       * and escape sequences accepted by these functions are
       * determined by their @p flags parameter as documented above.
       */
       ///@{

      /**
       * @todo Implement this function.
       */
      template<typename _Out_iter>
        _Out_iter
        format(_Out_iter __out, const string_type& __fmt,
	       regex_constants::match_flag_type __flags
	       = regex_constants::format_default) const;

      /**
       * @todo Implement this function.
       */
      string_type
      format(const string_type& __fmt,
	     regex_constants::match_flag_type __flags
	     = regex_constants::format_default) const;

      ///@}

      /**
       * @name 10.5 Allocator
       */
      ///@{ 

      /**
       * @brief Gets a copy of the allocator.
       */
      //allocator_type
      //get_allocator() const;
      using _Base_type::get_allocator;
      
      ///@}

      /**
       * @name 10.6 Swap
       */
       ///@{ 

      /**
       * @brief Swaps the contents of two match_results.
       */
      void
      swap(match_results& __that)
      {
	_Base_type::swap(__that);
	std::swap(_M_matched, __that._M_matched);
	std::swap(_M_prefix,  __that._M_prefix);
	std::swap(_M_suffix,  __that._M_suffix);
      }
      ///@}
      
    private:
      bool       _M_matched;
      value_type _M_prefix;
      value_type _M_suffix;
    };
  
  typedef match_results<const char*>             cmatch;
  typedef match_results<string::const_iterator>  smatch;
#ifdef _GLIBCXX_USE_WCHAR_T
  typedef match_results<const wchar_t*>          wcmatch;
  typedef match_results<wstring::const_iterator> wsmatch;
#endif

  // match_results comparisons
  /**
   * @brief Compares two match_results for equality.
   * @returns true if the two objects refer to the same match,
   * false otherwise.
   * @todo Implement this function.
   */
  template<typename _Bi_iter, typename _Allocator>
    inline bool
    operator==(const match_results<_Bi_iter, _Allocator>& __m1,
	       const match_results<_Bi_iter, _Allocator>& __m2);

  /**
   * @brief Compares two match_results for inequality.
   * @returns true if the two objects do not refer to the same match,
   * false otherwise.
   */
  template<typename _Bi_iter, class _Allocator>
    inline bool
    operator!=(const match_results<_Bi_iter, _Allocator>& __m1,
	       const match_results<_Bi_iter, _Allocator>& __m2)
    { return !(__m1 == __m2); }

  // [7.10.6] match_results swap
  /**
   * @brief Swaps two match results.
   * @param lhs A match result.
   * @param rhs A match result.
   *
   * The contents of the two match_results objects are swapped.
   */
  template<typename _Bi_iter, typename _Allocator>
    inline void
    swap(match_results<_Bi_iter, _Allocator>& __lhs,
	 match_results<_Bi_iter, _Allocator>& __rhs)
    { __lhs.swap(__rhs); }

  // [7.11.2] Function template regex_match
  /**
   * @name Matching, Searching, and Replacing
   */
  ///@{

  /**
   * @brief Determines if there is a match between the regular expression @p e
   * and all of the character sequence [first, last).
   *
   * @param first Beginning of the character sequence to match.
   * @param last  One-past-the-end of the character sequence to match.
   * @param m     The match results.
   * @param re    The regular expression.
   * @param flags Controls how the regular expression is matched.
   *
   * @retval true  A match exists.
   * @retval false Otherwise.
   *
   * @throws an exception of type regex_error.
   *
   * @todo Implement this function.
   */
  template<typename _Bi_iter, typename _Allocator,
	   typename _Ch_type, typename _Rx_traits>
    bool
    regex_match(_Bi_iter __first, _Bi_iter __last,
		match_results<_Bi_iter, _Allocator>& __m,
		const basic_regex<_Ch_type, _Rx_traits>& __re,
		regex_constants::match_flag_type __flags
		= regex_constants::match_default);

  /**
   * @brief Indicates if there is a match between the regular expression @p e
   * and all of the character sequence [first, last).
   *
   * @param first Beginning of the character sequence to match.
   * @param last  One-past-the-end of the character sequence to match.
   * @param re    The regular expression.
   * @param flags Controls how the regular expression is matched.
   *
   * @retval true  A match exists.
   * @retval false Otherwise.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
    bool
    regex_match(_Bi_iter __first, _Bi_iter __last,
		const basic_regex<_Ch_type, _Rx_traits>& __re,
		regex_constants::match_flag_type __flags
		= regex_constants::match_default)
    { 
      match_results<_Bi_iter> __what;
      return regex_match(__first, __last, __what, __re, __flags);
    }

  /**
   * @brief Determines if there is a match between the regular expression @p e
   * and a C-style null-terminated string.
   *
   * @param s  The C-style null-terminated string to match.
   * @param m  The match results.
   * @param re The regular expression.
   * @param f  Controls how the regular expression is matched.
   *
   * @retval true  A match exists.
   * @retval false Otherwise.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_type, typename _Allocator, typename _Rx_traits>
    inline bool
    regex_match(const _Ch_type* __s,
		match_results<const _Ch_type*, _Allocator>& __m,
		const basic_regex<_Ch_type, _Rx_traits>& __re,
		regex_constants::match_flag_type __f
		= regex_constants::match_default)
    { return regex_match(__s, __s + _Rx_traits::length(__s), __m, __re, __f); }

  /**
   * @brief Determines if there is a match between the regular expression @p e
   * and a string.
   *
   * @param s     The string to match.
   * @param m     The match results.
   * @param re    The regular expression.
   * @param flags Controls how the regular expression is matched.
   *
   * @retval true  A match exists.
   * @retval false Otherwise.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_traits, typename _Ch_alloc,
	   typename _Allocator, typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s,
		match_results<typename basic_string<_Ch_type, 
		_Ch_traits, _Ch_alloc>::const_iterator, _Allocator>& __m,
		const basic_regex<_Ch_type, _Rx_traits>& __re,
		regex_constants::match_flag_type __flags
		= regex_constants::match_default)
    { return regex_match(__s.begin(), __s.end(), __m, __re, __flags); }

  /**
   * @brief Indicates if there is a match between the regular expression @p e
   * and a C-style null-terminated string.
   *
   * @param s  The C-style null-terminated string to match.
   * @param re The regular expression.
   * @param f  Controls how the regular expression is matched.
   *
   * @retval true  A match exists.
   * @retval false Otherwise.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_type, class _Rx_traits>
    inline bool
    regex_match(const _Ch_type* __s,
		const basic_regex<_Ch_type, _Rx_traits>& __re,
		regex_constants::match_flag_type __f
		= regex_constants::match_default)
    { return regex_match(__s, __s + _Rx_traits::length(__s), __re, __f); }

  /**
   * @brief Indicates if there is a match between the regular expression @p e
   * and a string.
   *
   * @param s     [IN] The string to match.
   * @param re    [IN] The regular expression.
   * @param flags [IN] Controls how the regular expression is matched.
   *
   * @retval true  A match exists.
   * @retval false Otherwise.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_traits, typename _Str_allocator,
	   typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_match(const basic_string<_Ch_type, _Ch_traits, _Str_allocator>& __s,
		const basic_regex<_Ch_type, _Rx_traits>& __re,
		regex_constants::match_flag_type __flags
		= regex_constants::match_default)
    { return regex_match(__s.begin(), __s.end(), __re, __flags); }

  // [7.11.3] Function template regex_search
  /**
   * Searches for a regular expression within a range.
   * @param first [IN]  The start of the string to search.
   * @param last  [IN]  One-past-the-end of the string to search.
   * @param m     [OUT] The match results.
   * @param re    [IN]  The regular expression to search for.
   * @param flags [IN]  Search policy flags.
   * @retval true  A match was found within the string.
   * @retval false No match was found within the string, the content of %m is
   *               undefined.
   *
   * @throws an exception of type regex_error.
   *
   * @todo Implement this function.
   */
  template<typename _Bi_iter, typename _Allocator,
	   typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_search(_Bi_iter __first, _Bi_iter __last,
		 match_results<_Bi_iter, _Allocator>& __m,
		 const basic_regex<_Ch_type, _Rx_traits>& __re,
		 regex_constants::match_flag_type __flags
		 = regex_constants::match_default);

  /**
   * Searches for a regular expression within a range.
   * @param first [IN]  The start of the string to search.
   * @param last  [IN]  One-past-the-end of the string to search.
   * @param re    [IN]  The regular expression to search for.
   * @param flags [IN]  Search policy flags.
   * @retval true  A match was found within the string.
   * @retval false No match was found within the string.
   * @doctodo
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_search(_Bi_iter __first, _Bi_iter __last,
		 const basic_regex<_Ch_type, _Rx_traits>& __re,
		 regex_constants::match_flag_type __flags
		 = regex_constants::match_default)
    {
      match_results<_Bi_iter> __what;
      return regex_search(__first, __last, __what, __re, __flags);
    }

  /**
   * @brief Searches for a regular expression within a C-string.
   * @param s [IN]  A C-string to search for the regex.
   * @param m [OUT] The set of regex matches.
   * @param e [IN]  The regex to search for in @p s.
   * @param f [IN]  The search flags.
   * @retval true  A match was found within the string.
   * @retval false No match was found within the string, the content of %m is
   *               undefined.
   * @doctodo
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_type, class _Allocator, class _Rx_traits>
    inline bool
    regex_search(const _Ch_type* __s,
		 match_results<const _Ch_type*, _Allocator>& __m,
		 const basic_regex<_Ch_type, _Rx_traits>& __e,
		 regex_constants::match_flag_type __f
		 = regex_constants::match_default)
    { return regex_search(__s, __s + _Rx_traits::length(__s), __m, __e, __f); }

  /**
   * @brief Searches for a regular expression within a C-string.
   * @param s [IN]  The C-string to search.
   * @param e [IN]  The regular expression to search for.
   * @param f [IN]  Search policy flags.
   * @retval true  A match was found within the string.
   * @retval false No match was found within the string.
   * @doctodo
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_search(const _Ch_type* __s,
		 const basic_regex<_Ch_type, _Rx_traits>& __e,
		 regex_constants::match_flag_type __f
		 = regex_constants::match_default)
    { return regex_search(__s, __s + _Rx_traits::length(__s), __e, __f); }

  /**
   * @brief Searches for a regular expression within a string.
   * @param s     [IN]  The string to search.
   * @param e     [IN]  The regular expression to search for.
   * @param flags [IN]  Search policy flags.
   * @retval true  A match was found within the string.
   * @retval false No match was found within the string.
   * @doctodo
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_traits, typename _String_allocator,
	   typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_search(const basic_string<_Ch_type, _Ch_traits,
		 _String_allocator>& __s,
		 const basic_regex<_Ch_type, _Rx_traits>& __e,
		 regex_constants::match_flag_type __flags
		 = regex_constants::match_default)
    { return regex_search(__s.begin(), __s.end(), __e, __flags); }

  /**
   * @brief Searches for a regular expression within a string.
   * @param s [IN]  A C++ string to search for the regex.
   * @param m [OUT] The set of regex matches.
   * @param e [IN]  The regex to search for in @p s.
   * @param f [IN]  The search flags.
   * @retval true  A match was found within the string.
   * @retval false No match was found within the string, the content of %m is
   *               undefined.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Ch_traits, typename _Ch_alloc,
	   typename _Allocator, typename _Ch_type,
	   typename _Rx_traits>
    inline bool
    regex_search(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s,
		 match_results<typename basic_string<_Ch_type,
		 _Ch_traits, _Ch_alloc>::const_iterator, _Allocator>& __m,
		 const basic_regex<_Ch_type, _Rx_traits>& __e,
		 regex_constants::match_flag_type __f
		 = regex_constants::match_default)
    { return regex_search(__s.begin(), __s.end(), __m, __e, __f); }

  // tr1 [7.11.4] std [28.11.4] Function template regex_replace
  /**
   * @doctodo
   * @param out
   * @param first
   * @param last
   * @param e
   * @param fmt
   * @param flags
   *
   * @returns out
   * @throws an exception of type regex_error.
   *
   * @todo Implement this function.
   */
  template<typename _Out_iter, typename _Bi_iter,
	   typename _Rx_traits, typename _Ch_type>
    inline _Out_iter
    regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
		  const basic_regex<_Ch_type, _Rx_traits>& __e,
		  const basic_string<_Ch_type>& __fmt,
		  regex_constants::match_flag_type __flags
		  = regex_constants::match_default);

  /**
   * @doctodo
   * @param s
   * @param e
   * @param fmt
   * @param flags
   *
   * @returns a copy of string @p s with replacements.
   *
   * @throws an exception of type regex_error.
   */
  template<typename _Rx_traits, typename _Ch_type>
    inline basic_string<_Ch_type>
    regex_replace(const basic_string<_Ch_type>& __s,
		  const basic_regex<_Ch_type, _Rx_traits>& __e,
		  const basic_string<_Ch_type>& __fmt,
		  regex_constants::match_flag_type __flags
		  = regex_constants::match_default)
    {
      std::string __result;
      regex_replace(std::back_inserter(__result),
		    __s.begin(), __s.end(), __e, __fmt, __flags);
      return __result;
    }

  ///@}

  // tr1 [7.12.1] std [28.12] Class template regex_iterator
  /**
   * An iterator adaptor that will provide repeated calls of regex_search over 
   * a range until no more matches remain.
   */
  template<typename _Bi_iter,
	   typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type,
	   typename _Rx_traits = regex_traits<_Ch_type> >
    class regex_iterator
    {
    public:
      typedef basic_regex<_Ch_type, _Rx_traits>  regex_type;
      typedef match_results<_Bi_iter>            value_type;
      typedef std::ptrdiff_t                     difference_type;
      typedef const value_type*                  pointer;
      typedef const value_type&                  reference;
      typedef std::forward_iterator_tag          iterator_category;

    public:
      /**
       * @brief Provides a singular iterator, useful for indicating
       * one-past-the-end of a range.
       * @todo Implement this function.
       * @doctodo
       */
      regex_iterator();
      
      /**
       * Constructs a %regex_iterator...
       * @param a  [IN] The start of a text range to search.
       * @param b  [IN] One-past-the-end of the text range to search.
       * @param re [IN] The regular expression to match.
       * @param m  [IN] Policy flags for match rules.
       * @todo Implement this function.
       * @doctodo
       */
      regex_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re,
		     regex_constants::match_flag_type __m
		     = regex_constants::match_default);

      /**
       * Copy constructs a %regex_iterator.
       * @todo Implement this function.
       * @doctodo
       */
      regex_iterator(const regex_iterator& __rhs);
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      regex_iterator&
      operator=(const regex_iterator& __rhs);
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      bool
      operator==(const regex_iterator& __rhs);
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      bool
      operator!=(const regex_iterator& __rhs);
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      const value_type&
      operator*();
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      const value_type*
      operator->();
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      regex_iterator&
      operator++();
      
      /**
       * @todo Implement this function.
       * @doctodo
       */
      regex_iterator
      operator++(int);
      
    private:
      // these members are shown for exposition only:
      _Bi_iter                         begin;
      _Bi_iter                         end;
      const regex_type*                pregex;
      regex_constants::match_flag_type flags;
      match_results<_Bi_iter>          match;
    };
  
  typedef regex_iterator<const char*>             cregex_iterator;
  typedef regex_iterator<string::const_iterator>  sregex_iterator;
#ifdef _GLIBCXX_USE_WCHAR_T
  typedef regex_iterator<const wchar_t*>          wcregex_iterator;
  typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
#endif

  // [7.12.2] Class template regex_token_iterator
  /**
   * Iterates over submatches in a range (or @a splits a text string).
   *
   * The purpose of this iterator is to enumerate all, or all specified,
   * matches of a regular expression within a text range.  The dereferenced
   * value of an iterator of this class is a std::tr1::sub_match object.
   */
  template<typename _Bi_iter,
	   typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type,
	   typename _Rx_traits = regex_traits<_Ch_type> >
    class regex_token_iterator
    {
    public:
      typedef basic_regex<_Ch_type, _Rx_traits> regex_type;
      typedef sub_match<_Bi_iter>               value_type;
      typedef std::ptrdiff_t                    difference_type;
      typedef const value_type*                 pointer;
      typedef const value_type&                 reference;
      typedef std::forward_iterator_tag         iterator_category;
      
    public:
      /**
       * @brief Default constructs a %regex_token_iterator.
       * @todo Implement this function.
       * 
       * A default-constructed %regex_token_iterator is a singular iterator
       * that will compare equal to the one-past-the-end value for any
       * iterator of the same type.
       */
      regex_token_iterator();
      
      /**
       * Constructs a %regex_token_iterator...
       * @param a          [IN] The start of the text to search.
       * @param b          [IN] One-past-the-end of the text to search.
       * @param re         [IN] The regular expression to search for.
       * @param submatch   [IN] Which submatch to return.  There are some
       *                        special values for this parameter:
       *                        - -1 each enumerated subexpression does NOT
       *                          match the regular expression (aka field
       *                          splitting)
       *                        - 0 the entire string matching the
       *                          subexpression is returned for each match
       *                          within the text.
       *                        - >0 enumerates only the indicated
       *                          subexpression from a match within the text.
       * @param m          [IN] Policy flags for match rules.
       *
       * @todo Implement this function.
       * @doctodo
       */
      regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re,
			   int __submatch = 0,
			   regex_constants::match_flag_type __m
			   = regex_constants::match_default);

      /**
       * Constructs a %regex_token_iterator...
       * @param a          [IN] The start of the text to search.
       * @param b          [IN] One-past-the-end of the text to search.
       * @param re         [IN] The regular expression to search for.
       * @param submatches [IN] A list of subexpressions to return for each
       *                        regular expression match within the text.
       * @param m          [IN] Policy flags for match rules.
       *
       * @todo Implement this function.
       * @doctodo
       */
      regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
			   const regex_type& __re,
			   const std::vector<int>& __submatches,
			   regex_constants::match_flag_type __m
			     = regex_constants::match_default);

      /**
       * Constructs a %regex_token_iterator...
       * @param a          [IN] The start of the text to search.
       * @param b          [IN] One-past-the-end of the text to search.
       * @param re         [IN] The regular expression to search for.
       * @param submatches [IN] A list of subexpressions to return for each
       *                        regular expression match within the text.
       * @param m          [IN] Policy flags for match rules.
       
       * @todo Implement this function.
       * @doctodo
       */
      template<std::size_t _Nm>
        regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
			     const regex_type& __re,
			     const int (&__submatches)[_Nm],
			     regex_constants::match_flag_type __m
			     = regex_constants::match_default);

      /**
       * @brief Copy constructs a %regex_token_iterator.
       * @param rhs [IN] A %regex_token_iterator to copy.
       * @todo Implement this function.
       */
      regex_token_iterator(const regex_token_iterator& __rhs);
      
      /**
       * @brief Assigns a %regex_token_iterator to another.
       * @param rhs [IN] A %regex_token_iterator to copy.
       * @todo Implement this function.
       */
      regex_token_iterator&
      operator=(const regex_token_iterator& __rhs);
      
      /**
       * @brief Compares a %regex_token_iterator to another for equality.
       * @todo Implement this function.
       */
      bool
      operator==(const regex_token_iterator& __rhs);
      
      /**
       * @brief Compares a %regex_token_iterator to another for inequality.
       * @todo Implement this function.
       */
      bool
      operator!=(const regex_token_iterator& __rhs);
      
      /**
       * @brief Dereferences a %regex_token_iterator.
       * @todo Implement this function.
       */
      const value_type&
      operator*();
      
      /**
       * @brief Selects a %regex_token_iterator member.
       * @todo Implement this function.
       */
      const value_type*
      operator->();
      
      /**
       * @brief Increments a %regex_token_iterator.
       * @todo Implement this function.
       */
      regex_token_iterator&
      operator++();
      
      /**
       * @brief Postincrements a %regex_token_iterator.
       * @todo Implement this function.
       */
      regex_token_iterator
      operator++(int);
      
    private: // data members for exposition only:
      typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> position_iterator;

      position_iterator __position;
      const value_type* __result;
      value_type        __suffix;
      std::size_t       __n;
      std::vector<int>  __subs;
    };

  /** @brief Token iterator for C-style NULL-terminated strings. */
  typedef regex_token_iterator<const char*>             cregex_token_iterator;
  /** @brief Token iterator for standard strings. */
  typedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;
#ifdef _GLIBCXX_USE_WCHAR_T
  /** @brief Token iterator for C-style NULL-terminated wide strings. */
  typedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;
  /** @brief Token iterator for standard wide-character strings. */
  typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#endif
  
  ///@}
}

_GLIBCXX_END_NAMESPACE_VERSION
}

#endif // _GLIBCXX_TR1_REGEX
