public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] Whole regex refactoring and current status
@ 2013-08-05 17:05 Tim Shen
       [not found] ` <52001184.5020707@oracle.com>
  2013-08-08 10:01 ` Rainer Orth
  0 siblings, 2 replies; 22+ messages in thread
From: Tim Shen @ 2013-08-05 17:05 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1582 bytes --]

As metioned in this[1] email, I here propose a refactored version of
regex, and show the status:

Modules:
1) Automaton module(regex_automaton.h, regex_automaton.tcc), now
consists of an NFA implementation; In the future, the NFA should be
able to be optimized to a DFA.

2) Regex compiler module(regex_compiler.h, regex_compiler.tcc), which
take a string and then emit a NFA. Now it provides a regex token
scanner and parser(NFA generator). It's not fully implemented, and
will be main task in the near future. It should includes various regex
flavors(ECMAScript, basic, extended, awk, grep and egrep), but they
are not supported. Since the ECMAScript style is the default one, I'll
start my work here.

3) Executor(or matcher) module, which is constructed with a NFA and a
string, then match and group it. We have a DFS and BFS(Thompson
matcher) approach now; the BFS approach can effectively prevent the
matching from being exponential, but cannot handle back-references.
The current strategy is checking whether there're back-referneces in
the pattern; If there are, a DFS matcher will be generated, else the
BFS one. Matching options are not supported now. It shouldn't be a
great deal since the executors are there.

This patch eliminate _SpecializedCursor and _SpecializedResults.
Instead, I use _BiIter and match_results, the actual data structure,
directly. It should enabled the easy and obvious approch to implement
back-reference.

'make bootstrap && make -k check' tested under x86_64.

Thanks!

[1] http://gcc.gnu.org/ml/libstdc++/2013-07/msg00140.html


-- 
Tim Shen

[-- Attachment #2: changelog --]
[-- Type: application/octet-stream, Size: 672 bytes --]

2013-08-05  Tim Shen  <timshen91@gmail.com>

	* include/Makefile.am: Adjust to new files.
	* include/Makefile.in: Regenerate.
	* include/bits/regex.h: Adjust to new interfaces.
	* include/bits/regex_automaton.h: New.
	* include/bits/regex_automaton.tcc: New.
	* include/bits/regex_compiler.h: Adjust to new files.
	* include/bits/regex_compiler.tcc: New.
	* include/bits/regex_constants.h: Tail spaces.
	* include/bits/regex_error.h: Likewise.
	* include/bits/regex_executor.h: New.
	* include/bits/regex_executor.tcc: New.
	* include/std/regex: Adjust to new files.
	* testsuite/28_regex/algorithms/regex_match/extended/
	string_dispatch_01.cc: Adjust to new interfaces.

[-- Attachment #3: regex.patch --]
[-- Type: application/octet-stream, Size: 157204 bytes --]

Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 201492)
+++ include/Makefile.am	(working copy)
@@ -126,14 +126,14 @@
 	${bits_srcdir}/random.tcc \
 	${bits_srcdir}/range_access.h \
 	${bits_srcdir}/regex.h \
-	${bits_srcdir}/regex_compiler.h \
 	${bits_srcdir}/regex_constants.h \
-	${bits_srcdir}/regex_cursor.h \
 	${bits_srcdir}/regex_error.h \
-	${bits_srcdir}/regex_grep_matcher.h \
-	${bits_srcdir}/regex_grep_matcher.tcc \
-	${bits_srcdir}/regex_nfa.h \
-	${bits_srcdir}/regex_nfa.tcc \
+	${bits_srcdir}/regex_automaton.h \
+	${bits_srcdir}/regex_automaton.tcc \
+	${bits_srcdir}/regex_compiler.h \
+	${bits_srcdir}/regex_compiler.tcc \
+	${bits_srcdir}/regex_executor.h \
+	${bits_srcdir}/regex_executor.tcc \
 	${bits_srcdir}/stream_iterator.h \
 	${bits_srcdir}/streambuf_iterator.h \
 	${bits_srcdir}/shared_ptr.h \
Index: include/Makefile.in
===================================================================
--- include/Makefile.in	(revision 201492)
+++ include/Makefile.in	(working copy)
@@ -388,14 +388,14 @@
 	${bits_srcdir}/random.tcc \
 	${bits_srcdir}/range_access.h \
 	${bits_srcdir}/regex.h \
-	${bits_srcdir}/regex_compiler.h \
 	${bits_srcdir}/regex_constants.h \
-	${bits_srcdir}/regex_cursor.h \
 	${bits_srcdir}/regex_error.h \
-	${bits_srcdir}/regex_grep_matcher.h \
-	${bits_srcdir}/regex_grep_matcher.tcc \
-	${bits_srcdir}/regex_nfa.h \
-	${bits_srcdir}/regex_nfa.tcc \
+	${bits_srcdir}/regex_automaton.h \
+	${bits_srcdir}/regex_automaton.tcc \
+	${bits_srcdir}/regex_compiler.h \
+	${bits_srcdir}/regex_compiler.tcc \
+	${bits_srcdir}/regex_executor.h \
+	${bits_srcdir}/regex_executor.tcc \
 	${bits_srcdir}/stream_iterator.h \
 	${bits_srcdir}/streambuf_iterator.h \
 	${bits_srcdir}/shared_ptr.h \
Index: include/bits/regex.h
===================================================================
--- include/bits/regex.h	(revision 201492)
+++ include/bits/regex.h	(working copy)
@@ -40,7 +40,7 @@
   /**
    * @brief Class regex_traits. Describes aspects of a regular expression.
    *
-   * A regular expression traits class that satisfies the requirements of 
+   * A regular expression traits class that satisfies the requirements of
    * section [28.7].
    *
    * The class %regex is parameterized around a set of related types and
@@ -61,7 +61,8 @@
           _BaseType _M_base;
           unsigned char _M_extended;
           static constexpr unsigned char _S_under = 1 << 0;
-          // FIXME: _S_blank should be removed in the future, when locale's complete.
+          // FIXME: _S_blank should be removed in the future,
+          // when locale's complete.
           static constexpr unsigned char _S_blank = 1 << 1;
           static constexpr unsigned char _S_valid_mask = 0x3;
 
@@ -128,7 +129,7 @@
        * @brief Constructs a default traits object.
        */
       regex_traits() { }
-      
+
       /**
        * @brief Gives the length of a C-style string starting at @p __p.
        *
@@ -153,7 +154,7 @@
       char_type
       translate(char_type __c) const
       { return __c; }
-      
+
       /**
        * @brief Translates a character into a case-insensitive equivalent.
        *
@@ -165,12 +166,12 @@
        */
       char_type
       translate_nocase(char_type __c) const
-      { 
+      {
 	typedef std::ctype<char_type> __ctype_type;
 	const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-	return __fctyp.tolower(__c); 
+	return __fctyp.tolower(__c);
       }
-      
+
       /**
        * @brief Gets a sort key for a character sequence.
        *
@@ -209,7 +210,7 @@
        *
        * 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) 
+       * 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.
        *
@@ -239,7 +240,7 @@
        *
        * @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
@@ -312,13 +313,13 @@
        * @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.
        *
@@ -336,7 +337,7 @@
 	std::swap(_M_locale, __loc);
 	return __loc;
       }
-      
+
       /**
        * @brief Gets a copy of the current locale in use by the regex_traits
        * object.
@@ -344,7 +345,7 @@
       locale_type
       getloc() const
       { return _M_locale; }
-      
+
     protected:
       locale_type _M_locale;
     };
@@ -579,7 +580,8 @@
           if (__s == __it->first)
             {
               if (__icase
-                  && ((__it->second & (ctype_base::lower | ctype_base::upper)) != 0))
+                  && ((__it->second
+                       & (ctype_base::lower | ctype_base::upper)) != 0))
                 return ctype_base::alpha;
               return __it->second;
             }
@@ -594,7 +596,7 @@
     {
       typedef std::ctype<char_type> __ctype_type;
       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-      
+
       return __fctyp.is(__f._M_base, __c)
         // [[:w:]]
         || ((__f._M_extended & _RegexMask::_S_under)
@@ -662,9 +664,7 @@
        * character sequence.
        */
       basic_regex()
-      : _M_flags(ECMAScript),
-        _M_automaton(__detail::__compile<const _Ch_type*, _Rx_traits>(0, 0,
-                     _M_traits, _M_flags))
+      : _M_flags(ECMAScript), _M_automaton(nullptr)
       { }
 
       /**
@@ -680,9 +680,7 @@
        */
       explicit
       basic_regex(const _Ch_type* __p, flag_type __f = ECMAScript)
-      : _M_flags(__f),
-        _M_automaton(__detail::__compile(__p, __p + _Rx_traits::length(__p),
-        				_M_traits, _M_flags))
+      : basic_regex(__p, __p + _Rx_traits::length(__p), __f)
       { }
 
       /**
@@ -697,9 +695,9 @@
        *
        * @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_automaton(__detail::__compile(__p, __p + __len, _M_traits, _M_flags))
+      basic_regex(const _Ch_type* __p,
+                  std::size_t __len, flag_type __f = ECMAScript)
+      : basic_regex(__p, __p + __len, __f)
       { }
 
       /**
@@ -707,10 +705,7 @@
        *
        * @param __rhs A @p regex object.
        */
-      basic_regex(const basic_regex& __rhs)
-      : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
-        _M_automaton(__rhs._M_automaton)
-      { }
+      basic_regex(const basic_regex& __rhs) = default;
 
       /**
        * @brief Move-constructs a basic regular expression.
@@ -733,12 +728,10 @@
        */
       template<typename _Ch_traits, typename _Ch_alloc>
         explicit
-        basic_regex(const std::basic_string<_Ch_type, _Ch_traits, 
+        basic_regex(const std::basic_string<_Ch_type, _Ch_traits,
 					    _Ch_alloc>& __s,
 		    flag_type __f = ECMAScript)
-	: _M_flags(__f),
-	  _M_automaton(__detail::__compile(__s.begin(), __s.end(),
-	  				  _M_traits, _M_flags))
+	: basic_regex(__s.begin(), __s.end(), __f)
         { }
 
       /**
@@ -755,10 +748,11 @@
        *         expression.
        */
       template<typename _InputIterator>
-        basic_regex(_InputIterator __first, _InputIterator __last, 
+        basic_regex(_InputIterator __first, _InputIterator __last,
 		    flag_type __f = ECMAScript)
 	: _M_flags(__f),
-	  _M_automaton(__detail::__compile(__first, __last, _M_traits, _M_flags))
+          _M_automaton(__detail::_Compiler<_InputIterator, _Ch_type, _Rx_traits>
+                       (__first, __last, _M_traits, _M_flags)._M_get_nfa())
         { }
 
       /**
@@ -771,9 +765,7 @@
        */
       basic_regex(initializer_list<_Ch_type> __l,
 		  flag_type __f = ECMAScript)
-      : _M_flags(__f),
-        _M_automaton(__detail::__compile(__l.begin(), __l.end(),
-        				_M_traits, _M_flags))
+      : basic_regex(__l.begin(), __l.end(), __f)
       { }
 
       /**
@@ -781,7 +773,7 @@
        */
       ~basic_regex()
       { }
-      
+
       /**
        * @brief Assigns one regular expression to another.
        */
@@ -806,7 +798,7 @@
       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.
@@ -831,7 +823,7 @@
 	this->swap(__tmp);
 	return *this;
       }
-      
+
       /**
        * @brief The move-assignment operator.
        *
@@ -880,7 +872,7 @@
       { return this->assign(string_type(__p, __len), __flags); }
 
       /**
-       * @brief Assigns a new regular expression to a regex object from a 
+       * @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.
@@ -894,7 +886,7 @@
         basic_regex&
         assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
 	       flag_type __flags = ECMAScript)
-        { 
+        {
 	  basic_regex __tmp(__s, __flags);
 	  this->swap(__tmp);
 	  return *this;
@@ -942,7 +934,7 @@
       unsigned int
       mark_count() const
       { return _M_automaton->_M_sub_count() - 1; }
-      
+
       /**
        * @brief Gets the flags used to construct the regular expression
        * or in the last call to assign().
@@ -950,7 +942,7 @@
       flag_type
       flags() const
       { return _M_flags; }
-      
+
       // [7.8.5] locale
       /**
        * @brief Imbues the regular expression object with the given locale.
@@ -960,7 +952,7 @@
       locale_type
       imbue(locale_type __loc)
       { return _M_traits.imbue(__loc); }
-      
+
       /**
        * @brief Gets the locale currently imbued in the regular expression
        *        object.
@@ -968,7 +960,7 @@
       locale_type
       getloc() const
       { return _M_traits.getloc(); }
-      
+
       // [7.8.6] swap
       /**
        * @brief Swaps the contents of two regular expression objects.
@@ -988,17 +980,40 @@
       _M_dot(std::ostream& __ostr)
       { _M_automaton->_M_dot(__ostr); }
 #endif
-      
-      const __detail::_AutomatonPtr&
-      _M_get_automaton() const
-      { return _M_automaton; }
 
     protected:
-      flag_type              _M_flags;
-      _Rx_traits             _M_traits;
-      __detail::_AutomatonPtr _M_automaton;
+      typedef std::shared_ptr<__detail::_Automaton<_Ch_type, _Rx_traits>>
+        _AutomatonPtr;
+
+      template<typename _BiIter, typename _Alloc,
+        typename _CharT, typename _TraitsT>
+        friend std::unique_ptr<
+          __detail::_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+        __detail::__get_executor(_BiIter,
+                                 _BiIter,
+                                 match_results<_BiIter, _Alloc>&,
+                                 const basic_regex<_CharT, _TraitsT>&,
+                                 regex_constants::match_flag_type);
+
+      template<typename _B, typename _A, typename _C, typename _R>
+        friend bool
+        regex_match(_B, _B,
+                    match_results<_B, _A>&,
+                    const basic_regex<_C, _R>&,
+                    regex_constants::match_flag_type);
+
+      template<typename _B, typename _A, typename _C, typename _R>
+        friend bool
+        regex_search(_B, _B,
+                     match_results<_B, _A>&,
+                     const basic_regex<_C, _R>&,
+                     regex_constants::match_flag_type);
+
+      flag_type     _M_flags;
+      _Rx_traits    _M_traits;
+      _AutomatonPtr _M_automaton;
     };
-  
+
   /** @brief Standard regular expressions. */
   typedef basic_regex<char>    regex;
 
@@ -1046,7 +1061,7 @@
       typedef std::basic_string<value_type>             string_type;
 
       bool matched;
-      
+
       constexpr sub_match() : matched() { }
 
       /**
@@ -1072,7 +1087,7 @@
 	  ? string_type(this->first, this->second)
 	  : string_type();
       }
-      
+
       /**
        * @brief Gets the matching sequence as a string.
        *
@@ -1085,7 +1100,7 @@
 	  ? string_type(this->first, this->second)
 	  : string_type();
       }
-      
+
       /**
        * @brief Compares this and another matched sequence.
        *
@@ -1111,7 +1126,7 @@
       int
       compare(const string_type& __s) const
       { return this->str().compare(__s); }
-      
+
       /**
        * @brief Compares this sub_match to a C-style string.
        *
@@ -1125,8 +1140,8 @@
       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;
 
@@ -1142,7 +1157,7 @@
 #endif
 
   // [7.9.2] sub_match non-member operators
-  
+
   /**
    * @brief Tests the equivalence of two regular expression submatches.
    * @param __lhs First regular expression submatch.
@@ -1760,7 +1775,7 @@
 
       typedef std::basic_string<char_type>                 string_type;
       //@}
-  
+
     public:
       /**
        * @name 28.10.1 Construction, Copying, and Destruction
@@ -1815,7 +1830,7 @@
        */
       ~match_results()
       { }
-      
+
       //@}
 
       // 28.10.2, state:
@@ -1846,7 +1861,7 @@
       	size_type __size = _Base_type::size();
       	return (__size && _Base_type::operator[](0).matched) ? __size - 2 : 0;
       }
-      
+
       size_type
       max_size() const
       { return _Base_type::max_size(); }
@@ -1859,7 +1874,7 @@
       bool
       empty() const
       { return size() == 0; }
-      
+
       //@}
 
       /**
@@ -1911,7 +1926,7 @@
       string_type
       str(size_type __sub = 0) const
       { return (*this)[__sub].str(); }
-      
+
       /**
        * @brief Gets a %sub_match reference for the match or submatch.
        * @param __sub indicates the submatch.
@@ -1925,7 +1940,7 @@
        */
       const_reference
       operator[](size_type __sub) const
-      { 
+      {
       	_GLIBCXX_DEBUG_ASSERT( ready() );
       	return __sub < size()
 	       ?  _Base_type::operator[](__sub)
@@ -1972,7 +1987,7 @@
       const_iterator
       begin() const
       { return _Base_type::begin(); }
-      
+
       /**
        * @brief Gets an iterator to the start of the %sub_match collection.
        */
@@ -1986,7 +2001,7 @@
       const_iterator
       end() const
       { return !empty() ? _Base_type::end() - 2 : _Base_type::end(); }
-      
+
       /**
        * @brief Gets an iterator to one-past-the-end of the collection.
        */
@@ -2047,21 +2062,22 @@
        */
       string_type
       format(const char_type* __fmt,
-	     match_flag_type __flags = regex_constants::format_default) const
+             match_flag_type __flags = regex_constants::format_default) const
       {
         string_type __result;
         format(std::back_inserter(__result),
+               __fmt,
                __fmt + char_traits<char_type>::length(__fmt),
                __flags);
         return __result;
       }
 
-      //@} 
+      //@}
 
       /**
        * @name 10.5 Allocator
        */
-      //@{ 
+      //@{
 
       /**
        * @brief Gets a copy of the allocator.
@@ -2069,13 +2085,13 @@
       allocator_type
       get_allocator() const
       { return _Base_type::get_allocator(); }
-      
-      //@} 
 
+      //@}
+
       /**
        * @name 10.6 Swap
        */
-       //@{ 
+       //@{
 
       /**
        * @brief Swaps the contents of two match_results.
@@ -2083,12 +2099,33 @@
       void
       swap(match_results& __that)
       { _Base_type::swap(__that); }
-      //@} 
-      
+      //@}
+
     private:
-      friend class __detail::_SpecializedResults<_Bi_iter, _Alloc>;
+      template<typename, typename, typename, typename>
+        friend class __detail::_Executor;
+
+      template<typename, typename, typename, typename>
+        friend class __detail::_DFSExecutor;
+
+      template<typename, typename, typename, typename>
+        friend class __detail::_BFSExecutor;
+
+      template<typename _B, typename _A, typename _Ch_type, typename _Rx_traits>
+        friend bool
+        regex_match(_B, _B, match_results<_B, _A>&,
+                    const basic_regex<_Ch_type,
+                    _Rx_traits>&,
+                    regex_constants::match_flag_type);
+
+      template<typename _B, typename _A, typename _Ch_type, typename _Rx_traits>
+        friend bool
+        regex_search(_B, _B, match_results<_B, _A>&,
+                     const basic_regex<_Ch_type,
+                     _Rx_traits>&,
+                     regex_constants::match_flag_type);
     };
-  
+
   typedef match_results<const char*>             cmatch;
   typedef match_results<string::const_iterator>  smatch;
 #ifdef _GLIBCXX_USE_WCHAR_T
@@ -2179,11 +2216,22 @@
                 regex_constants::match_flag_type         __flags
                                = regex_constants::match_default)
     {
-      __detail::_AutomatonPtr __a = __re._M_get_automaton();
-      __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
-      __detail::_SpecializedCursor<_Bi_iter> __cs(__s, __e);
-      __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
-      return __a->_M_get_matcher(__cs, __r, __a, __flags)->_M_match();
+      if (__re._M_automaton == nullptr)
+        return false;
+      if (__detail::__get_executor(__s, __e, __m, __re, __flags)->_M_match())
+        {
+          for (auto __it : __m)
+            if (!__it.matched)
+              __it.first = __it.second = __e;
+          __m.at(__m.size()).matched = false;
+          __m.at(__m.size()).first = __s;
+          __m.at(__m.size()).second = __s;
+          __m.at(__m.size()+1).matched = false;
+          __m.at(__m.size()+1).first = __e;
+          __m.at(__m.size()+1).second = __e;
+          return true;
+        }
+      return false;
     }
 
   /**
@@ -2206,7 +2254,7 @@
 		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);
     }
@@ -2252,7 +2300,7 @@
 	   typename _Alloc, 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, 
+		match_results<typename basic_string<_Ch_type,
 		_Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m,
 		const basic_regex<_Ch_type, _Rx_traits>& __re,
 		regex_constants::match_flag_type __flags
@@ -2327,29 +2375,25 @@
                  regex_constants::match_flag_type __flags
                  = regex_constants::match_default)
     {
-      __detail::_AutomatonPtr __a = __re._M_get_automaton();
-      __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
-      __detail::_SpecializedCursor<_Bi_iter> __cs(__first, __last);
-      __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
+      if (__re._M_automaton == nullptr)
+        return false;
       for (auto __cur = __first; __cur != __last; ++__cur) // Any KMP-like algo?
-        {
-          __detail::_SpecializedCursor<_Bi_iter> __curs(__cur, __last);
-          auto __matcher = __a->_M_get_matcher(__curs, __r, __a, __flags);
-          if (__matcher->_M_search_from_first())
-            {
-              __r._M_set_range(__m.size(),
-                               __detail::_SpecializedCursor<_Bi_iter>
-                                 {__first, __m[0].first});
-              __r._M_set_range(__m.size()+1,
-                               __detail::_SpecializedCursor<_Bi_iter>
-                                 {__m[0].second, __last});
-              __r._M_set_matched(__m.size(),
-                                 __m.prefix().first != __m.prefix().second);
-              __r._M_set_matched(__m.size()+1,
-                                 __m.suffix().first != __m.suffix().second);
-              return true;
-            }
-        }
+        if (__detail::__get_executor(__cur, __last, __m, __re, __flags)
+              ->_M_search_from_first())
+          {
+            for (auto __it : __m)
+              if (!__it.matched)
+                __it.first = __it.second = __last;
+            __m.at(__m.size()).first = __first;
+            __m.at(__m.size()).second = __m[0].first;
+            __m.at(__m.size()+1).first = __m[0].second;
+            __m.at(__m.size()+1).second = __last;
+            __m.at(__m.size()).matched =
+              (__m.prefix().first != __m.prefix().second);
+            __m.at(__m.size()+1).matched =
+              (__m.suffix().first != __m.suffix().second);
+            return true;
+          }
       return false;
     }
 
@@ -2513,7 +2557,7 @@
 
   // std [28.12] Class template regex_iterator
   /**
-   * An iterator adaptor that will provide repeated calls of regex_search over 
+   * An iterator adaptor that will provide repeated calls of regex_search over
    * a range until no more matches remain.
    */
   template<typename _Bi_iter,
@@ -2536,7 +2580,7 @@
       regex_iterator()
       : _M_match()
       { }
-      
+
       /**
        * Constructs a %regex_iterator...
        * @param __a  [IN] The start of a text range to search.
@@ -2554,46 +2598,46 @@
        * Copy constructs a %regex_iterator.
        */
       regex_iterator(const regex_iterator& __rhs) = default;
-      
+
       /**
        * @brief Assigns one %regex_iterator to another.
        */
       regex_iterator&
       operator=(const regex_iterator& __rhs) = default;
-      
+
       /**
        * @brief Tests the equivalence of two regex iterators.
        */
       bool
       operator==(const regex_iterator& __rhs) const;
-      
+
       /**
        * @brief Tests the inequivalence of two regex iterators.
        */
       bool
       operator!=(const regex_iterator& __rhs) const
       { return !(*this == __rhs); }
-      
+
       /**
        * @brief Dereferences a %regex_iterator.
        */
       const value_type&
       operator*() const
       { return _M_match; }
-      
+
       /**
        * @brief Selects a %regex_iterator member.
        */
       const value_type*
       operator->() const
       { return &_M_match; }
-      
+
       /**
        * @brief Increments a %regex_iterator.
        */
       regex_iterator&
       operator++();
-      
+
       /**
        * @brief Postincrements a %regex_iterator.
        */
@@ -2604,7 +2648,7 @@
         ++(*this);
         return __tmp;
       }
-      
+
     private:
       _Bi_iter                         _M_begin;
       _Bi_iter                         _M_end;
@@ -2665,7 +2709,7 @@
         }
       return *this;
     }
-  
+
   typedef regex_iterator<const char*>             cregex_iterator;
   typedef regex_iterator<string::const_iterator>  sregex_iterator;
 #ifdef _GLIBCXX_USE_WCHAR_T
@@ -2693,11 +2737,11 @@
       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.
-       * 
+       *
        * 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.
@@ -2705,7 +2749,7 @@
       regex_token_iterator()
       : _M_position(), _M_result(nullptr), _M_suffix(), _M_n(0), _M_subs()
       { }
-      
+
       /**
        * Constructs a %regex_token_iterator...
        * @param __a          [IN] The start of the text to search.
@@ -2987,7 +3031,7 @@
   /** @brief Token iterator for standard wide-character strings. */
   typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #endif
-  
+
   //@} // group regex
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
Index: include/bits/regex_automaton.h
===================================================================
--- include/bits/regex_automaton.h	(revision 0)
+++ include/bits/regex_automaton.h	(working copy)
@@ -0,0 +1,274 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_automaton.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @defgroup regex-detail Base and Implementation Classes
+   *  @ingroup regex
+   *  @{
+   */
+
+  typedef int _StateIdT;
+  typedef std::set<_StateIdT> _StateSet;
+  static const _StateIdT _S_invalid_state_id  = -1;
+
+  template<typename _CharT>
+    using _Matcher = std::function<bool (_CharT)>;
+
+  /// Operation codes that define the type of transitions within the base NFA
+  /// that represents the regular expression.
+  enum _Opcode
+  {
+      _S_opcode_unknown       =   0,
+      _S_opcode_alternative   =   1,
+      _S_opcode_subexpr_begin =   4,
+      _S_opcode_subexpr_end   =   5,
+      _S_opcode_match         = 100,
+      _S_opcode_accept        = 255
+  };
+
+  template<typename _CharT, typename _TraitsT>
+    class _State
+    {
+    public:
+      typedef int                        _OpcodeT;
+      typedef _Matcher<_CharT>           _MatcherT;
+
+      _OpcodeT     _M_opcode;    // type of outgoing transition
+      _StateIdT    _M_next;      // outgoing transition
+      _StateIdT    _M_alt;       // for _S_opcode_alternative
+      unsigned int _M_subexpr;   // for _S_opcode_subexpr_*
+      _MatcherT    _M_matches;   // for _S_opcode_match
+
+      explicit _State(_OpcodeT __opcode)
+      : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
+      { }
+
+      _State(const _MatcherT& __m)
+      : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id),
+        _M_matches(__m)
+      { }
+
+      _State(_OpcodeT __opcode, unsigned __index)
+      : _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__index)
+      { }
+
+      _State(_StateIdT __next, _StateIdT __alt)
+      : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
+      { }
+
+#ifdef _GLIBCXX_DEBUG
+      std::ostream&
+      _M_print(std::ostream& ostr) const;
+
+      // Prints graphviz dot commands for state.
+      std::ostream&
+      _M_dot(std::ostream& __ostr, _StateIdT __id) const;
+#endif
+    };
+
+  /// Base class for, um, automata.  Could be an NFA or a DFA.  Your choice.
+  template<typename _CharT, typename _TraitsT>
+    class _Automaton
+    {
+    public:
+      typedef unsigned int _SizeT;
+
+    public:
+      virtual _SizeT
+      _M_sub_count() const = 0;
+
+#ifdef _GLIBCXX_DEBUG
+      virtual std::ostream&
+      _M_dot(std::ostream& __ostr) const = 0;
+#endif
+    };
+
+  template<typename _CharT, typename _TraitsT>
+    class _NFA
+    : public _Automaton<_CharT, _TraitsT>,
+      public std::vector<_State<_CharT, _TraitsT>>
+    {
+    public:
+      typedef _State<_CharT, _TraitsT>            _StateT;
+      typedef const _Matcher<_CharT>&             _MatcherT;
+      typedef unsigned int                        _SizeT;
+      typedef regex_constants::syntax_option_type _FlagT;
+
+      _NFA(_FlagT __f)
+      : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
+      _M_has_backref(false)
+      { }
+
+      _FlagT
+      _M_options() const
+      { return _M_flags; }
+
+      _StateIdT
+      _M_start() const
+      { return _M_start_state; }
+
+      const _StateSet&
+      _M_final_states() const
+      { return _M_accepting_states; }
+
+      _SizeT
+      _M_sub_count() const
+      { return _M_subexpr_count; }
+
+      _StateIdT
+      _M_insert_accept()
+      {
+        this->push_back(_StateT(_S_opcode_accept));
+        _M_accepting_states.insert(this->size()-1);
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_alt(_StateIdT __next, _StateIdT __alt)
+      {
+        this->push_back(_StateT(__next, __alt));
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_matcher(_MatcherT __m)
+      {
+        this->push_back(_StateT(__m));
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_subexpr_begin()
+      {
+        auto __id = _M_subexpr_count++;
+        _M_paren_stack.push(__id);
+        this->push_back(_StateT(_S_opcode_subexpr_begin, __id));
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_subexpr_end()
+      {
+        this->push_back(_StateT(_S_opcode_subexpr_end, _M_paren_stack.top()));
+        _M_paren_stack.pop();
+        return this->size()-1;
+      }
+
+      void
+      _M_set_backref(bool __b)
+      { _M_has_backref = __b; }
+
+#ifdef _GLIBCXX_DEBUG
+      std::ostream&
+      _M_dot(std::ostream& __ostr) const;
+#endif
+
+      _FlagT                   _M_flags;
+      _StateIdT                _M_start_state;
+      _StateSet                _M_accepting_states;
+      _SizeT                   _M_subexpr_count;
+      bool                     _M_has_backref;
+      std::stack<unsigned int> _M_paren_stack;
+    };
+
+  /// Describes a sequence of one or more %_State, its current start
+  /// and end(s).  This structure contains fragments of an NFA during
+  /// construction.
+  template<typename _CharT, typename _TraitsT>
+    class _StateSeq
+    {
+    public:
+      typedef _NFA<_CharT, _TraitsT> _RegexT;
+    public:
+      // Constructs a single-node sequence
+      _StateSeq(_RegexT& __ss, _StateIdT __s,
+                _StateIdT __e = _S_invalid_state_id)
+      : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
+      { }
+      // Constructs a split sequence from two other sequencces
+      _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
+      : _M_nfa(__e1._M_nfa),
+        _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
+        _M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
+      { }
+
+      // Constructs a split sequence from a single sequence
+      _StateSeq(const _StateSeq& __e, _StateIdT __id)
+      : _M_nfa(__e._M_nfa),
+        _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
+        _M_end1(__id), _M_end2(__e._M_end1)
+      { }
+
+      // Constructs a copy of a %_StateSeq
+      _StateSeq(const _StateSeq& __rhs)
+      : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
+        _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
+      { }
+
+      _StateSeq& operator=(const _StateSeq& __rhs);
+
+      _StateIdT
+      _M_front() const
+      { return _M_start; }
+
+      // Extends a sequence by one.
+      void
+      _M_push_back(_StateIdT __id);
+
+      // Extends and maybe joins a sequence.
+      void
+      _M_append(_StateIdT __id);
+
+      void
+      _M_append(_StateSeq& __rhs);
+
+      // Clones an entire sequence.
+      _StateIdT
+      _M_clone();
+
+    private:
+      _RegexT&  _M_nfa;
+      _StateIdT _M_start;
+      _StateIdT _M_end1;
+      _StateIdT _M_end2;
+    };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_automaton.tcc>
Index: include/bits/regex_automaton.tcc
===================================================================
--- include/bits/regex_automaton.tcc	(revision 0)
+++ include/bits/regex_automaton.tcc	(working copy)
@@ -0,0 +1,181 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_automaton.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#ifdef _GLIBCXX_DEBUG
+  template<typename _CharT, typename _TraitsT>
+    std::ostream& _State<_CharT, _TraitsT>::
+    _M_print(std::ostream& ostr) const
+    {
+      switch (_M_opcode)
+      {
+        case _S_opcode_alternative:
+          ostr << "alt next=" << _M_next << " alt=" << _M_alt;
+          break;
+        case _S_opcode_subexpr_begin:
+          ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
+          break;
+        case _S_opcode_subexpr_end:
+          ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
+          break;
+        case _S_opcode_match:
+          ostr << "match next=" << _M_next;
+          break;
+        case _S_opcode_accept:
+          ostr << "accept next=" << _M_next;
+          break;
+        default:
+          ostr << "unknown next=" << _M_next;
+          break;
+      }
+      return ostr;
+    }
+
+  // Prints graphviz dot commands for state.
+  template<typename _CharT, typename _TraitsT>
+    std::ostream& _State<_CharT, _TraitsT>::
+    _M_dot(std::ostream& __ostr, _StateIdT __id) const
+    {
+      switch (_M_opcode)
+      {
+        case _S_opcode_alternative:
+          __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n"
+                 << __id << " -> " << _M_next
+                 << " [label=\"epsilon\", tailport=\"s\"];\n"
+                 << __id << " -> " << _M_alt
+                 << " [label=\"epsilon\", tailport=\"n\"];\n";
+          break;
+        case _S_opcode_subexpr_begin:
+          __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
+                 << _M_subexpr << "\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
+          break;
+        case _S_opcode_subexpr_end:
+          __ostr << __id << " [label=\"" << __id << "\\nSEND "
+                 << _M_subexpr << "\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
+          break;
+        case _S_opcode_match:
+          __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
+          break;
+        case _S_opcode_accept:
+          __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
+          break;
+        default:
+          __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"?\"];\n";
+          break;
+      }
+      return __ostr;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    std::ostream& _NFA<_CharT, _TraitsT>::
+    _M_dot(std::ostream& __ostr) const
+    {
+      __ostr << "digraph _Nfa {\n"
+       << "  rankdir=LR;\n";
+      for (unsigned int __i = 0; __i < this->size(); ++__i)
+      { this->at(__i)._M_dot(__ostr, __i); }
+      __ostr << "}\n";
+      return __ostr;
+    }
+#endif
+
+  template<typename _CharT, typename _TraitsT>
+    _StateSeq<_CharT, _TraitsT>& _StateSeq<_CharT, _TraitsT>::
+    operator=(const _StateSeq& __rhs)
+    {
+      _M_start = __rhs._M_start;
+      _M_end1  = __rhs._M_end1;
+      _M_end2  = __rhs._M_end2;
+      return *this;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    void _StateSeq<_CharT, _TraitsT>::
+    _M_push_back(_StateIdT __id)
+    {
+      if (_M_end1 != _S_invalid_state_id)
+        _M_nfa[_M_end1]._M_next = __id;
+      _M_end1 = __id;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    void _StateSeq<_CharT, _TraitsT>::
+    _M_append(_StateIdT __id)
+    {
+      if (_M_end2 != _S_invalid_state_id)
+      {
+        if (_M_end2 == _M_end1)
+          _M_nfa[_M_end2]._M_alt = __id;
+        else
+          _M_nfa[_M_end2]._M_next = __id;
+        _M_end2 = _S_invalid_state_id;
+      }
+      if (_M_end1 != _S_invalid_state_id)
+        _M_nfa[_M_end1]._M_next = __id;
+      _M_end1 = __id;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    void _StateSeq<_CharT, _TraitsT>::
+    _M_append(_StateSeq& __rhs)
+    {
+      if (_M_end2 != _S_invalid_state_id)
+      {
+        if (_M_end2 == _M_end1)
+          _M_nfa[_M_end2]._M_alt = __rhs._M_start;
+        else
+          _M_nfa[_M_end2]._M_next = __rhs._M_start;
+        _M_end2 = _S_invalid_state_id;
+      }
+      if (__rhs._M_end2 != _S_invalid_state_id)
+        _M_end2 = __rhs._M_end2;
+      if (_M_end1 != _S_invalid_state_id)
+        _M_nfa[_M_end1]._M_next = __rhs._M_start;
+      _M_end1 = __rhs._M_end1;
+    }
+
+  // @todo implement this function.
+  template<typename _CharT, typename _TraitsT>
+    _StateIdT _StateSeq<_CharT, _TraitsT>::
+    _M_clone()
+    { return 0; }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
Index: include/bits/regex_compiler.h
===================================================================
--- include/bits/regex_compiler.h	(revision 201492)
+++ include/bits/regex_compiler.h	(working copy)
@@ -1,6 +1,6 @@
 // class template regex -*- C++ -*-
 
-// Copyright (C) 2010-2013 Free Software Foundation, Inc.
+// Copyright (C) 2013 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
@@ -35,21 +35,95 @@
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /**
-   * @addtogroup regex-detail
-   * @{
+   *  @defgroup regex-detail Base and Implementation Classes
+   *  @ingroup regex
+   *  @{
    */
 
-  /// Base class for scanner.
-  struct _Scanner_base
-  {
-    typedef unsigned int _StateT;
+  /// Matches a character range (bracket expression)
+  template<typename _CharT, typename _TraitsT>
+    struct _BracketMatcher
+    {
+      typedef typename _TraitsT::char_class_type  _CharClassT;
+      typedef typename _TraitsT::string_type      _StringT;
+      typedef regex_constants::syntax_option_type _FlagT;
 
-    static constexpr _StateT _S_state_in_brace    = 1 << 0;
-    static constexpr _StateT _S_state_in_bracket  = 1 << 1;
+      explicit
+      _BracketMatcher(bool __is_non_matching,
+                      const _TraitsT& __t,
+                      _FlagT __flags)
+      : _M_is_non_matching(__is_non_matching), _M_traits(__t),
+        _M_flags(__flags), _M_class_set(0)
+      { }
 
-    virtual ~_Scanner_base() { };
-  };
+      bool
+      operator()(_CharT) const;
 
+      void
+      _M_add_char(_CharT __c)
+      {
+        if (_M_flags & regex_constants::collate)
+          if (_M_is_icase())
+            _M_char_set.push_back(_M_traits.translate_nocase(__c));
+          else
+            _M_char_set.push_back(_M_traits.translate(__c));
+        else
+          _M_char_set.push_back(__c);
+      }
+
+      void
+      _M_add_collating_element(const _StringT& __s)
+      {
+        auto __st = _M_traits.lookup_collatename(&*__s.begin(), &*__s.end());
+        if (__st.empty())
+          __throw_regex_error(regex_constants::error_collate);
+        // TODO: digraph
+        _M_char_set.push_back(__st[0]);
+      }
+
+      void
+      _M_add_equivalence_class(const _StringT& __s)
+      {
+        _M_add_character_class(
+          _M_traits.transform_primary(&*__s.begin(), &*__s.end()));
+      }
+
+      void
+      _M_add_character_class(const _StringT& __s)
+      {
+        auto __st = _M_traits.
+          lookup_classname(&*__s.begin(), &*__s.end(), _M_is_icase());
+        if (__st == 0)
+          __throw_regex_error(regex_constants::error_ctype);
+        _M_class_set |= __st;
+      }
+
+      void
+      _M_make_range(_CharT __l, _CharT __r)
+      { _M_range_set.push_back(make_pair(_M_get_str(__l), _M_get_str(__r))); }
+
+      bool
+      _M_is_icase() const
+      { return _M_flags & regex_constants::icase; }
+
+      _StringT
+      _M_get_str(_CharT __c) const
+      {
+        auto __s = _StringT(1,
+                            _M_is_icase()
+                            ? _M_traits.translate_nocase(__c)
+                            : _M_traits.translate(__c));
+        return _M_traits.transform(__s.begin(), __s.end());
+      }
+
+      _TraitsT                              _M_traits;
+      _FlagT                                _M_flags;
+      bool                                  _M_is_non_matching;
+      std::vector<_CharT>                   _M_char_set;
+      std::vector<pair<_StringT, _StringT>> _M_range_set;
+      _CharClassT                           _M_class_set;
+    };
+
   /**
    * @brief struct _Scanner. Scans an input range for regex tokens.
    *
@@ -60,12 +134,12 @@
    * constructor: different regular expression grammars will interpret
    * the same input pattern in syntactically different ways.
    */
-  template<typename _InputIterator>
-    class _Scanner: public _Scanner_base
+  template<typename _InputIter>
+    class _Scanner
     {
     public:
-      typedef _InputIterator                                        _IteratorT;
-      typedef typename std::iterator_traits<_IteratorT>::value_type _CharT;
+      typedef unsigned int                                          _StateT;
+      typedef typename std::iterator_traits<_InputIter>::value_type _CharT;
       typedef std::basic_string<_CharT>                             _StringT;
       typedef regex_constants::syntax_option_type                   _FlagT;
       typedef const std::ctype<_CharT>                              _CtypeT;
@@ -103,8 +177,8 @@
 	_S_token_unknown
       };
 
-      _Scanner(_IteratorT __begin, _IteratorT __end, _FlagT __flags,
-	       std::locale __loc)
+      _Scanner(_InputIter __begin, _InputIter __end,
+               _FlagT __flags, std::locale __loc)
       : _M_current(__begin) , _M_end(__end) , _M_flags(__flags),
         _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_state(0)
       { _M_advance(); }
@@ -144,8 +218,10 @@
       void
       _M_eat_collsymbol();
 
-      _IteratorT  _M_current;
-      _IteratorT  _M_end;
+      static constexpr _StateT _S_state_in_brace    = 1 << 0;
+      static constexpr _StateT _S_state_in_bracket  = 1 << 1;
+      _InputIter  _M_current;
+      _InputIter  _M_end;
       _FlagT      _M_flags;
       _CtypeT&    _M_ctype;
       _TokenT     _M_curToken;
@@ -153,520 +229,28 @@
       _StateT     _M_state;
     };
 
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_advance()
-    {
-      if (_M_current == _M_end)
-	{
-	  _M_curToken = _S_token_eof;
-	  return;
-	}
-
-      _CharT __c = *_M_current;
-      if (_M_state & _S_state_in_bracket)
-	{
-	  _M_scan_in_bracket();
-	  return;
-	}
-      if (_M_state & _S_state_in_brace)
-	{
-	  _M_scan_in_brace();
-	  return;
-	}
-#if 0
-      // TODO: re-enable line anchors when _M_assertion is implemented.
-      // See PR libstdc++/47724
-      else if (_M_state & _S_state_at_start && __c == _M_ctype.widen('^'))
-	{
-	  _M_curToken = _S_token_line_begin;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('$'))
-	{
-	  _M_curToken = _S_token_line_end;
-	  ++_M_current;
-	  return;
-	}
-#endif
-      else if (__c == _M_ctype.widen('.'))
-	{
-	  _M_curToken = _S_token_anychar;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('*'))
-	{
-	  _M_curToken = _S_token_closure0;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('+'))
-	{
-	  _M_curToken = _S_token_closure1;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('|'))
-	{
-	  _M_curToken = _S_token_or;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('['))
-	{
-          if (*++_M_current == _M_ctype.widen('^'))
-            {
-              _M_curToken = _S_token_bracket_inverse_begin;
-              ++_M_current;
-            }
-          else
-            _M_curToken = _S_token_bracket_begin;
-	  _M_state |= _S_state_in_bracket;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('\\'))
-	{
-	  _M_eat_escape();
-	  return;
-	}
-      else if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	{
-	  if (__c == _M_ctype.widen('('))
-	    {
-	      _M_curToken = _S_token_subexpr_begin;
-	      ++_M_current;
-	      return;
-	    }
-	  else if (__c == _M_ctype.widen(')'))
-	    {
-	      _M_curToken = _S_token_subexpr_end;
-	      ++_M_current;
-	      return;
-	    }
-	  else if (__c == _M_ctype.widen('{'))
-	    {
-	      _M_curToken = _S_token_interval_begin;
-	      _M_state |= _S_state_in_brace;
-	      ++_M_current;
-	      return;
-	    }
-	}
-
-      _M_curToken = _S_token_ord_char;
-      _M_curValue.assign(1, __c);
-      ++_M_current;
-    }
-
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_scan_in_brace()
-    {
-      if (_M_ctype.is(_CtypeT::digit, *_M_current))
-	{
-	  _M_curToken = _S_token_dup_count;
-	  _M_curValue.assign(1, *_M_current);
-	  ++_M_current;
-	  while (_M_current != _M_end
-		 && _M_ctype.is(_CtypeT::digit, *_M_current))
-	    {
-	      _M_curValue += *_M_current;
-	      ++_M_current;
-	    }
-	  return;
-	}
-      else if (*_M_current == _M_ctype.widen(','))
-	{
-	  _M_curToken = _S_token_comma;
-	  ++_M_current;
-	  return;
-	}
-      if (_M_flags & (regex_constants::basic | regex_constants::grep))
-	{
-	  if (*_M_current == _M_ctype.widen('\\'))
-	    _M_eat_escape();
-	}
-      else 
-	{
-	  if (*_M_current == _M_ctype.widen('}'))
-	    {
-	      _M_curToken = _S_token_interval_end;
-	      _M_state &= ~_S_state_in_brace;
-	      ++_M_current;
-	      return;
-	    }
-	}
-    }
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_scan_in_bracket()
-    {
-      if (*_M_current == _M_ctype.widen('['))
-	{
-	  ++_M_current;
-	  if (_M_current == _M_end)
-	    {
-	      _M_curToken = _S_token_eof;
-	      return;
-	    }
-
-	  if (*_M_current == _M_ctype.widen('.'))
-	    {
-	      _M_curToken = _S_token_collsymbol;
-	      _M_eat_collsymbol();
-	      return;
-	    }
-	  else if (*_M_current == _M_ctype.widen(':'))
-	    {
-	      _M_curToken = _S_token_char_class_name;
-	      _M_eat_charclass();
-	      return;
-	    }
-	  else if (*_M_current == _M_ctype.widen('='))
-	    {
-	      _M_curToken = _S_token_equiv_class_name;
-	      _M_eat_equivclass();
-	      return;
-	    }
-	}
-      else if (*_M_current == _M_ctype.widen('-'))
-	{
-	  _M_curToken = _S_token_dash;
-	  ++_M_current;
-	  return;
-	}
-      else if (*_M_current == _M_ctype.widen(']'))
-	{
-          _M_curToken = _S_token_bracket_end;
-          _M_state &= ~_S_state_in_bracket;
-          ++_M_current;
-          return;
-	}
-      else if (*_M_current == _M_ctype.widen('\\'))
-        {
-	  _M_eat_escape();
-	  return;
-        }
-      _M_curToken = _S_token_collelem_single;
-      _M_curValue.assign(1, *_M_current);
-      ++_M_current;
-    }
-
-  // TODO implement it.
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_escape()
-    {
-      ++_M_current;
-      if (_M_current == _M_end)
-	{
-	  _M_curToken = _S_token_eof;
-	  return;
-	}
-      _CharT __c = *_M_current;
-      ++_M_current;
-
-      if (__c == _M_ctype.widen('('))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    _M_curToken = _S_token_subexpr_begin;
-	}
-      else if (__c == _M_ctype.widen(')'))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    _M_curToken = _S_token_subexpr_end;
-	}
-      else if (__c == _M_ctype.widen('{'))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    {
-	      _M_curToken = _S_token_interval_begin;
-	      _M_state |= _S_state_in_brace;
-	    }
-	}
-      else if (__c == _M_ctype.widen('}'))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    {
-	      if (!(_M_state && _S_state_in_brace))
-		__throw_regex_error(regex_constants::error_badbrace);
-	      _M_state &= ~_S_state_in_brace;
-	      _M_curToken = _S_token_interval_end;
-	    }
-	}
-      else if (__c == _M_ctype.widen('x'))
-	{
-	  ++_M_current;
-	  if (_M_current == _M_end)
-	    {
-	      _M_curToken = _S_token_eof;
-	      return;
-	    }
-	  if (_M_ctype.is(_CtypeT::digit, *_M_current))
-	    {
-	      _M_curValue.assign(1, *_M_current);
-	      ++_M_current;
-	      if (_M_current == _M_end)
-		{
-		  _M_curToken = _S_token_eof;
-		  return;
-		}
-	      if (_M_ctype.is(_CtypeT::digit, *_M_current))
-		{
-		  _M_curValue += *_M_current;
-		  ++_M_current;
-		  return;
-		}
-	    }
-	}
-      else if (__c == _M_ctype.widen('^')
-	       || __c == _M_ctype.widen('.')
-	       || __c == _M_ctype.widen('*')
-	       || __c == _M_ctype.widen('$')
-	       || __c == _M_ctype.widen('\\'))
-	{
-	  _M_curToken = _S_token_ord_char;
-	  _M_curValue.assign(1, __c);
-	}
-      else if (_M_ctype.is(_CtypeT::digit, __c))
-	{
-	  _M_curToken = _S_token_backref;
-	  _M_curValue.assign(1, __c);
-	}
-      else if (_M_state & _S_state_in_bracket)
-        {
-          if (__c == _M_ctype.widen('-')
-              || __c == _M_ctype.widen('[')
-              || __c == _M_ctype.widen(']'))
-            {
-              _M_curToken = _S_token_ord_char;
-              _M_curValue.assign(1, __c);
-            }
-          else if ((_M_flags & regex_constants::ECMAScript)
-                   && __c == _M_ctype.widen('b'))
-            {
-              _M_curToken = _S_token_ord_char;
-              _M_curValue.assign(1, _M_ctype.widen(' '));
-            }
-          else
-            __throw_regex_error(regex_constants::error_escape);
-        }
-      else
-	__throw_regex_error(regex_constants::error_escape);
-    }
-
-  // Eats a character class or throwns an exception.
-  // current point to ':' delimiter on entry, char after ']' on return
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_charclass()
-    {
-      ++_M_current; // skip ':'
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_ctype);
-      for (_M_curValue.clear();
-	   _M_current != _M_end && *_M_current != _M_ctype.widen(':');
-	   ++_M_current)
-	_M_curValue += *_M_current;
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_ctype);
-      ++_M_current; // skip ':'
-      if (*_M_current != _M_ctype.widen(']'))
-	__throw_regex_error(regex_constants::error_ctype);
-      ++_M_current; // skip ']'
-    }
-
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_equivclass()
-    {
-      ++_M_current; // skip '='
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      for (_M_curValue.clear();
-	   _M_current != _M_end && *_M_current != _M_ctype.widen('=');
-	   ++_M_current)
-	_M_curValue += *_M_current;
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip '='
-      if (*_M_current != _M_ctype.widen(']'))
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip ']'
-    }
-
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_collsymbol()
-    {
-      ++_M_current; // skip '.'
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      for (_M_curValue.clear();
-	   _M_current != _M_end && *_M_current != _M_ctype.widen('.');
-	   ++_M_current)
-	_M_curValue += *_M_current;
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip '.'
-      if (*_M_current != _M_ctype.widen(']'))
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip ']'
-    }
-
-#ifdef _GLIBCXX_DEBUG
-  template<typename _InputIterator>
-    std::ostream&
-    _Scanner<_InputIterator>::
-    _M_print(std::ostream& ostr)
-    {
-      switch (_M_curToken)
-      {
-	case _S_token_anychar:
-	  ostr << "any-character\n";
-	  break;
-	case _S_token_backref:
-	  ostr << "backref\n";
-	  break;
-	case _S_token_bracket_begin:
-	  ostr << "bracket-begin\n";
-	  break;
-	case _S_token_bracket_inverse_begin:
-          ostr << "bracket-inverse-begin\n";
-          break;
-	case _S_token_bracket_end:
-	  ostr << "bracket-end\n";
-	  break;
-	case _S_token_char_class_name:
-	  ostr << "char-class-name \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_closure0:
-	  ostr << "closure0\n";
-	  break;
-	case _S_token_closure1:
-	  ostr << "closure1\n";
-	  break;
-	case _S_token_collelem_multi:
-	  ostr << "coll-elem-multi \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_collelem_single:
-	  ostr << "coll-elem-single \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_collsymbol:
-	  ostr << "collsymbol \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_comma:
-	  ostr << "comma\n";
-	  break;
-	case _S_token_dash:
-	  ostr << "dash\n";
-	  break;
-	case _S_token_dup_count:
-	  ostr << "dup count: " << _M_curValue << "\n";
-	  break;
-	case _S_token_eof:
-	  ostr << "EOF\n";
-	  break;
-	case _S_token_equiv_class_name:
-	  ostr << "equiv-class-name \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_interval_begin:
-	  ostr << "interval begin\n";
-	  break;
-	case _S_token_interval_end:
-	  ostr << "interval end\n";
-	  break;
-	case _S_token_line_begin:
-	  ostr << "line begin\n";
-	  break;
-	case _S_token_line_end:
-	  ostr << "line end\n";
-	  break;
-	case _S_token_opt:
-	  ostr << "opt\n";
-	  break;
-	case _S_token_or:
-	  ostr << "or\n";
-	  break;
-	case _S_token_ord_char:
-	  ostr << "ordinary character: \"" << _M_value() << "\"\n";
-	  break;
-	case _S_token_subexpr_begin:
-	  ostr << "subexpr begin\n";
-	  break;
-	case _S_token_subexpr_end:
-	  ostr << "subexpr end\n";
-	  break;
-	case _S_token_word_begin:
-	  ostr << "word begin\n";
-	  break;
-	case _S_token_word_end:
-	  ostr << "word end\n";
-	  break;
-	case _S_token_unknown:
-	  ostr << "-- unknown token --\n";
-	  break;
-        default:
-          _GLIBCXX_DEBUG_ASSERT(false);
-      }
-      return ostr;
-    }
-#endif
-
   /// Builds an NFA from an input iterator interval.
-  template<typename _InIter, typename _TraitsT>
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
     class _Compiler
     {
     public:
-      typedef _InIter                                            _IterT;
-      typedef typename std::iterator_traits<_InIter>::value_type _CharT;
-      typedef std::basic_string<_CharT>                          _StringT;
-      typedef regex_constants::syntax_option_type                _FlagT;
+      typedef typename _TraitsT::string_type      _StringT;
+      typedef _NFA<_CharT, _TraitsT>              _RegexT;
+      typedef regex_constants::syntax_option_type _FlagT;
 
-      _Compiler(const _InIter& __b, const _InIter& __e,
-		_TraitsT& __traits, _FlagT __flags);
+      _Compiler(_InputIter __b, _InputIter __e,
+                const _TraitsT& __traits, _FlagT __flags);
 
-      const _Nfa&
-      _M_nfa() const
-      { return _M_state_store; }
+      std::shared_ptr<_RegexT>
+      _M_get_nfa() const
+      { return std::shared_ptr<_RegexT>(new _RegexT(_M_state_store)); }
 
     private:
-      typedef _Scanner<_InIter>                              _ScannerT;
-      typedef typename _ScannerT::_TokenT                    _TokenT;
-      typedef std::stack<_StateSeq, std::vector<_StateSeq> > _StackT;
-      typedef _BracketMatcher<_InIter, _TraitsT>             _BMatcherT;
+      typedef _Scanner<_InputIter>                            _ScannerT;
+      typedef typename _ScannerT::_TokenT                     _TokenT;
+      typedef _StateSeq<_CharT, _TraitsT>                     _StateSeqT;
+      typedef std::stack<_StateSeqT, std::vector<_StateSeqT>> _StackT;
+      typedef _BracketMatcher<_CharT, _TraitsT>               _BMatcherT;
 
       // accepts a specific token or returns false.
       bool
@@ -720,345 +304,17 @@
       int
       _M_cur_int_value(int __radix);
 
-      _TraitsT&      _M_traits;
-      _ScannerT      _M_scanner;
-      _StringT       _M_cur_value;
-      _Nfa           _M_state_store;
-      _StackT        _M_stack;
-      _FlagT         _M_flags;
+      const _TraitsT& _M_traits;
+      _ScannerT       _M_scanner;
+      _StringT        _M_cur_value;
+      _RegexT         _M_state_store;
+      _StackT         _M_stack;
+      _FlagT          _M_flags;
     };
 
-  template<typename _InIter, typename _TraitsT>
-    _Compiler<_InIter, _TraitsT>::
-    _Compiler(const _InIter& __b, const _InIter& __e, _TraitsT& __traits,
-	      _Compiler<_InIter, _TraitsT>::_FlagT __flags)
-    : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()),
-      _M_state_store(__flags), _M_flags(__flags)
-    {
-      typedef _StartTagger<_InIter, _TraitsT> _Start;
-      typedef _EndTagger<_InIter, _TraitsT> _End;
-
-      _StateSeq __r(_M_state_store,
-      		    _M_state_store._M_insert_subexpr_begin(_Start(0)));
-      _M_disjunction();
-      if (!_M_stack.empty())
-	{
-	  __r._M_append(_M_stack.top());
-	  _M_stack.pop();
-	}
-      __r._M_append(_M_state_store._M_insert_subexpr_end(0, _End(0)));
-      __r._M_append(_M_state_store._M_insert_accept());
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_match_token(_Compiler<_InIter, _TraitsT>::_TokenT token)
-    { 
-      if (token == _M_scanner._M_token())
-	{
-          _M_cur_value = _M_scanner._M_value();
-          _M_scanner._M_advance();
-	  return true;
-	}
-      return false;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_disjunction()
-    {
-      this->_M_alternative();
-      if (_M_match_token(_ScannerT::_S_token_or))
-	{
-	  _StateSeq __alt1 = _M_stack.top(); _M_stack.pop();
-	  this->_M_disjunction();
-	  _StateSeq __alt2 = _M_stack.top(); _M_stack.pop();
-	  _M_stack.push(_StateSeq(__alt1, __alt2));
-	}
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_alternative()
-    {
-      if (this->_M_term())
-	{
-	  _StateSeq __re = _M_stack.top(); _M_stack.pop();
-	  this->_M_alternative();
-	  if (!_M_stack.empty())
-	    {
-	      __re._M_append(_M_stack.top());
-	      _M_stack.pop();
-	    }
-	  _M_stack.push(__re);
-	}
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_term()
-    {
-      if (this->_M_assertion())
-	return true;
-      if (this->_M_atom())
-	{
-	  this->_M_quantifier();
-	  return true;
-	}
-      return false;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_assertion()
-    {
-      if (_M_match_token(_ScannerT::_S_token_line_begin))
-	{
-	  // __m.push(_Matcher::_S_opcode_line_begin);
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_line_end))
-	{
-	  // __m.push(_Matcher::_S_opcode_line_end);
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_word_begin))
-	{
-	  // __m.push(_Matcher::_S_opcode_word_begin);
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_word_end))
-	{
-	  // __m.push(_Matcher::_S_opcode_word_end);
-	  return true;
-	}
-      return false;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_quantifier()
-    {
-      if (_M_match_token(_ScannerT::_S_token_closure0))
-	{
-	  if (_M_stack.empty())
-	    __throw_regex_error(regex_constants::error_badrepeat);
-	  _StateSeq __r(_M_stack.top(), -1);
-	  __r._M_append(__r._M_front());
-	  _M_stack.pop();
-	  _M_stack.push(__r);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_closure1))
-	{
-	  if (_M_stack.empty())
-	    __throw_regex_error(regex_constants::error_badrepeat);
-	  _StateSeq __r(_M_state_store,
-			_M_state_store.
-			_M_insert_alt(_S_invalid_state_id,
-				      _M_stack.top()._M_front()));
-	  _M_stack.top()._M_append(__r);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_opt))
-	{
-	  if (_M_stack.empty())
-	  __throw_regex_error(regex_constants::error_badrepeat);
-	  _StateSeq __r(_M_stack.top(), -1);
-	  _M_stack.pop();
-	  _M_stack.push(__r);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_interval_begin))
-	{
-	  if (_M_stack.empty())
-	    __throw_regex_error(regex_constants::error_badrepeat);
-	  if (!_M_match_token(_ScannerT::_S_token_dup_count))
-	    __throw_regex_error(regex_constants::error_badbrace);
-	  _StateSeq __r(_M_stack.top());
-	  int __min_rep = _M_cur_int_value(10);
-	  for (int __i = 1; __i < __min_rep; ++__i)
-	    _M_stack.top()._M_append(__r._M_clone()); 
-	  if (_M_match_token(_ScannerT::_S_token_comma))
-	    if (_M_match_token(_ScannerT::_S_token_dup_count))
-	      {
-		int __n = _M_cur_int_value(10) - __min_rep;
-		if (__n < 0)
-		  __throw_regex_error(regex_constants::error_badbrace);
-		for (int __i = 0; __i < __n; ++__i)
-		  {
-		    _StateSeq __r(_M_state_store,
-				  _M_state_store.
-				  _M_insert_alt(_S_invalid_state_id,
-						_M_stack.top()._M_front()));
-		    _M_stack.top()._M_append(__r);
-		  }
-	      }
-	    else
-	      {
-		_StateSeq __r(_M_stack.top(), -1);
-		__r._M_push_back(__r._M_front());
-		_M_stack.pop();
-		_M_stack.push(__r);
-	      }
-	  if (!_M_match_token(_ScannerT::_S_token_interval_end))
-	    __throw_regex_error(regex_constants::error_brace);
-	  return;
-	}
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_atom()
-    {
-      typedef _CharMatcher<_InIter, _TraitsT> _CMatcher;
-      typedef _StartTagger<_InIter, _TraitsT> _Start;
-      typedef _EndTagger<_InIter, _TraitsT> _End;
-
-      if (_M_match_token(_ScannerT::_S_token_anychar))
-	{
-	  _M_stack.push(_StateSeq(_M_state_store,
-                                  _M_state_store._M_insert_matcher
-                                  (_AnyMatcher)));
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_ord_char))
-	{
-	  _M_stack.push(_StateSeq(_M_state_store,
-                                  _M_state_store._M_insert_matcher
-                                  (_CMatcher(_M_cur_value[0], _M_flags, _M_traits))));
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_backref))
-	{
-	  // __m.push(_Matcher::_S_opcode_ordchar, _M_cur_value);
-          _M_state_store._M_set_back_ref(true);
-	  //return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
-	{
-	  int __mark = _M_state_store._M_sub_count();
-	  _StateSeq __r(_M_state_store,
-			_M_state_store.
-			_M_insert_subexpr_begin(_Start(__mark)));
-	  this->_M_disjunction();
-	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
-	    __throw_regex_error(regex_constants::error_paren);
-	  if (!_M_stack.empty())
-	    {
-	      __r._M_append(_M_stack.top());
-	      _M_stack.pop();
-	    }
-	  __r._M_append(_M_state_store._M_insert_subexpr_end
-			(__mark, _End(__mark)));
-	  _M_stack.push(__r);
-	  return true;
-	}
-      return _M_bracket_expression();
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_bracket_expression()
-    {
-      bool __inverse =
-        _M_match_token(_ScannerT::_S_token_bracket_inverse_begin);
-      if (!(__inverse || _M_match_token(_ScannerT::_S_token_bracket_begin)))
-        return false;
-      _BMatcherT __matcher( __inverse, _M_flags, _M_traits);
-      // special case: only if  _not_ chr first after
-      // '[' or '[^' or if ECMAscript
-      if (!_M_bracket_list(__matcher) // list is empty
-          && !(_M_flags & regex_constants::ECMAScript))
-        __throw_regex_error(regex_constants::error_brack);
-      _M_stack.push(_StateSeq(_M_state_store,
-                              _M_state_store._M_insert_matcher(__matcher)));
-      return true;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool // list is non-empty
-    _Compiler<_InIter, _TraitsT>::
-    _M_bracket_list(_BMatcherT& __matcher)
-    {
-      if (_M_match_token(_ScannerT::_S_token_bracket_end))
-        return false;
-      _M_expression_term(__matcher);
-      _M_bracket_list(__matcher);
-      return true;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_expression_term(_BMatcherT& __matcher)
-    {
-      if (_M_match_token(_ScannerT::_S_token_collsymbol))
-	{
-	  __matcher._M_add_collating_element(_M_cur_value);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
-	{
-	  __matcher._M_add_equivalence_class(_M_cur_value);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_char_class_name))
-	{
-	  __matcher._M_add_character_class(_M_cur_value);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_collelem_single)) // [a
-        {
-          auto __ch = _M_cur_value[0];
-          if (_M_match_token(_ScannerT::_S_token_dash)) // [a-
-            {
-              // If the dash is the last character in the bracket expression,
-              // it is not special.
-              if (_M_scanner._M_token() == _ScannerT::_S_token_bracket_end)
-                __matcher._M_add_char(_M_cur_value[0]); // [a-] <=> [a\-]
-              else // [a-z]
-                {
-                  if (!_M_match_token(_ScannerT::_S_token_collelem_single))
-                    __throw_regex_error(regex_constants::error_range);
-                  __matcher._M_make_range(__ch, _M_cur_value[0]);
-                }
-            }
-          else // [a]
-            __matcher._M_add_char(__ch);
-          return;
-        }
-      __throw_regex_error(regex_constants::error_brack);
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    int
-    _Compiler<_InIter, _TraitsT>::
-    _M_cur_int_value(int __radix)
-    {
-      int __v = 0;
-      for (typename _StringT::size_type __i = 0;
-	   __i < _M_cur_value.length(); ++__i)
-	__v =__v * __radix + _M_traits.value(_M_cur_value[__i], __radix);
-      return __v;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    _AutomatonPtr
-    __compile(const _InIter& __b, const _InIter& __e, _TraitsT& __t,
-	      regex_constants::syntax_option_type __f)
-    { return _AutomatonPtr(new _Nfa(_Compiler<_InIter, _TraitsT>(__b, __e, __t,
-                                        __f)._M_nfa())); }
-
  //@} regex-detail
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace __detail
 } // namespace std
+
+#include <bits/regex_compiler.tcc>
Index: include/bits/regex_compiler.tcc
===================================================================
--- include/bits/regex_compiler.tcc	(revision 0)
+++ include/bits/regex_compiler.tcc	(working copy)
@@ -0,0 +1,896 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_compiler.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_advance()
+    {
+      if (_M_current == _M_end)
+	{
+	  _M_curToken = _S_token_eof;
+	  return;
+	}
+
+      _CharT __c = *_M_current;
+      if (_M_state & _S_state_in_bracket)
+	{
+	  _M_scan_in_bracket();
+	  return;
+	}
+      if (_M_state & _S_state_in_brace)
+	{
+	  _M_scan_in_brace();
+	  return;
+	}
+#if 0
+      // TODO: re-enable line anchors when _M_assertion is implemented.
+      // See PR libstdc++/47724
+      else if (_M_state & _S_state_at_start && __c == _M_ctype.widen('^'))
+	{
+	  _M_curToken = _S_token_line_begin;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('$'))
+	{
+	  _M_curToken = _S_token_line_end;
+	  ++_M_current;
+	  return;
+	}
+#endif
+      else if (__c == _M_ctype.widen('.'))
+	{
+	  _M_curToken = _S_token_anychar;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('*'))
+	{
+	  _M_curToken = _S_token_closure0;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('+'))
+	{
+	  _M_curToken = _S_token_closure1;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('|'))
+	{
+	  _M_curToken = _S_token_or;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('['))
+	{
+          if (*++_M_current == _M_ctype.widen('^'))
+            {
+              _M_curToken = _S_token_bracket_inverse_begin;
+              ++_M_current;
+            }
+          else
+            _M_curToken = _S_token_bracket_begin;
+	  _M_state |= _S_state_in_bracket;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('\\'))
+	{
+	  _M_eat_escape();
+	  return;
+	}
+      else if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	{
+	  if (__c == _M_ctype.widen('('))
+	    {
+	      _M_curToken = _S_token_subexpr_begin;
+	      ++_M_current;
+	      return;
+	    }
+	  else if (__c == _M_ctype.widen(')'))
+	    {
+	      _M_curToken = _S_token_subexpr_end;
+	      ++_M_current;
+	      return;
+	    }
+	  else if (__c == _M_ctype.widen('{'))
+	    {
+	      _M_curToken = _S_token_interval_begin;
+	      _M_state |= _S_state_in_brace;
+	      ++_M_current;
+	      return;
+	    }
+	}
+
+      _M_curToken = _S_token_ord_char;
+      _M_curValue.assign(1, __c);
+      ++_M_current;
+    }
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_scan_in_brace()
+    {
+      if (_M_ctype.is(_CtypeT::digit, *_M_current))
+	{
+	  _M_curToken = _S_token_dup_count;
+	  _M_curValue.assign(1, *_M_current);
+	  ++_M_current;
+	  while (_M_current != _M_end
+		 && _M_ctype.is(_CtypeT::digit, *_M_current))
+	    {
+	      _M_curValue += *_M_current;
+	      ++_M_current;
+	    }
+	  return;
+	}
+      else if (*_M_current == _M_ctype.widen(','))
+	{
+	  _M_curToken = _S_token_comma;
+	  ++_M_current;
+	  return;
+	}
+      if (_M_flags & (regex_constants::basic | regex_constants::grep))
+	{
+	  if (*_M_current == _M_ctype.widen('\\'))
+	    _M_eat_escape();
+	}
+      else
+	{
+	  if (*_M_current == _M_ctype.widen('}'))
+	    {
+	      _M_curToken = _S_token_interval_end;
+	      _M_state &= ~_S_state_in_brace;
+	      ++_M_current;
+	      return;
+	    }
+	}
+    }
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_scan_in_bracket()
+    {
+      if (*_M_current == _M_ctype.widen('['))
+	{
+	  ++_M_current;
+	  if (_M_current == _M_end)
+	    {
+	      _M_curToken = _S_token_eof;
+	      return;
+	    }
+
+	  if (*_M_current == _M_ctype.widen('.'))
+	    {
+	      _M_curToken = _S_token_collsymbol;
+	      _M_eat_collsymbol();
+	      return;
+	    }
+	  else if (*_M_current == _M_ctype.widen(':'))
+	    {
+	      _M_curToken = _S_token_char_class_name;
+	      _M_eat_charclass();
+	      return;
+	    }
+	  else if (*_M_current == _M_ctype.widen('='))
+	    {
+	      _M_curToken = _S_token_equiv_class_name;
+	      _M_eat_equivclass();
+	      return;
+	    }
+	}
+      else if (*_M_current == _M_ctype.widen('-'))
+	{
+	  _M_curToken = _S_token_dash;
+	  ++_M_current;
+	  return;
+	}
+      else if (*_M_current == _M_ctype.widen(']'))
+	{
+          _M_curToken = _S_token_bracket_end;
+          _M_state &= ~_S_state_in_bracket;
+          ++_M_current;
+          return;
+	}
+      else if (*_M_current == _M_ctype.widen('\\'))
+        {
+	  _M_eat_escape();
+	  return;
+        }
+      _M_curToken = _S_token_collelem_single;
+      _M_curValue.assign(1, *_M_current);
+      ++_M_current;
+    }
+
+  // TODO implement it.
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_escape()
+    {
+      ++_M_current;
+      if (_M_current == _M_end)
+	{
+	  _M_curToken = _S_token_eof;
+	  return;
+	}
+      _CharT __c = *_M_current;
+      ++_M_current;
+
+      if (__c == _M_ctype.widen('('))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    _M_curToken = _S_token_subexpr_begin;
+	}
+      else if (__c == _M_ctype.widen(')'))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    _M_curToken = _S_token_subexpr_end;
+	}
+      else if (__c == _M_ctype.widen('{'))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    {
+	      _M_curToken = _S_token_interval_begin;
+	      _M_state |= _S_state_in_brace;
+	    }
+	}
+      else if (__c == _M_ctype.widen('}'))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    {
+	      if (!(_M_state && _S_state_in_brace))
+		__throw_regex_error(regex_constants::error_badbrace);
+	      _M_state &= ~_S_state_in_brace;
+	      _M_curToken = _S_token_interval_end;
+	    }
+	}
+      else if (__c == _M_ctype.widen('x'))
+	{
+	  ++_M_current;
+	  if (_M_current == _M_end)
+	    {
+	      _M_curToken = _S_token_eof;
+	      return;
+	    }
+	  if (_M_ctype.is(_CtypeT::digit, *_M_current))
+	    {
+	      _M_curValue.assign(1, *_M_current);
+	      ++_M_current;
+	      if (_M_current == _M_end)
+		{
+		  _M_curToken = _S_token_eof;
+		  return;
+		}
+	      if (_M_ctype.is(_CtypeT::digit, *_M_current))
+		{
+		  _M_curValue += *_M_current;
+		  ++_M_current;
+		  return;
+		}
+	    }
+	}
+      else if (__c == _M_ctype.widen('^')
+	       || __c == _M_ctype.widen('.')
+	       || __c == _M_ctype.widen('*')
+	       || __c == _M_ctype.widen('$')
+	       || __c == _M_ctype.widen('\\'))
+	{
+	  _M_curToken = _S_token_ord_char;
+	  _M_curValue.assign(1, __c);
+	}
+      else if (_M_ctype.is(_CtypeT::digit, __c))
+	{
+	  _M_curToken = _S_token_backref;
+	  _M_curValue.assign(1, __c);
+	}
+      else if (_M_state & _S_state_in_bracket)
+        {
+          if (__c == _M_ctype.widen('-')
+              || __c == _M_ctype.widen('[')
+              || __c == _M_ctype.widen(']'))
+            {
+              _M_curToken = _S_token_ord_char;
+              _M_curValue.assign(1, __c);
+            }
+          else if ((_M_flags & regex_constants::ECMAScript)
+                   && __c == _M_ctype.widen('b'))
+            {
+              _M_curToken = _S_token_ord_char;
+              _M_curValue.assign(1, _M_ctype.widen(' '));
+            }
+          else
+            __throw_regex_error(regex_constants::error_escape);
+        }
+      else
+	__throw_regex_error(regex_constants::error_escape);
+    }
+
+  // Eats a character class or throwns an exception.
+  // current point to ':' delimiter on entry, char after ']' on return
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_charclass()
+    {
+      ++_M_current; // skip ':'
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_ctype);
+      for (_M_curValue.clear();
+	   _M_current != _M_end && *_M_current != _M_ctype.widen(':');
+	   ++_M_current)
+	_M_curValue += *_M_current;
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_ctype);
+      ++_M_current; // skip ':'
+      if (*_M_current != _M_ctype.widen(']'))
+	__throw_regex_error(regex_constants::error_ctype);
+      ++_M_current; // skip ']'
+    }
+
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_equivclass()
+    {
+      ++_M_current; // skip '='
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      for (_M_curValue.clear();
+	   _M_current != _M_end && *_M_current != _M_ctype.widen('=');
+	   ++_M_current)
+	_M_curValue += *_M_current;
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip '='
+      if (*_M_current != _M_ctype.widen(']'))
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip ']'
+    }
+
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_collsymbol()
+    {
+      ++_M_current; // skip '.'
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      for (_M_curValue.clear();
+	   _M_current != _M_end && *_M_current != _M_ctype.widen('.');
+	   ++_M_current)
+	_M_curValue += *_M_current;
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip '.'
+      if (*_M_current != _M_ctype.widen(']'))
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip ']'
+    }
+
+#ifdef _GLIBCXX_DEBUG
+  template<typename _BiIter>
+    std::ostream&
+    _Scanner<_BiIter>::
+    _M_print(std::ostream& ostr)
+    {
+      switch (_M_curToken)
+      {
+	case _S_token_anychar:
+	  ostr << "any-character\n";
+	  break;
+	case _S_token_backref:
+	  ostr << "backref\n";
+	  break;
+	case _S_token_bracket_begin:
+	  ostr << "bracket-begin\n";
+	  break;
+	case _S_token_bracket_inverse_begin:
+          ostr << "bracket-inverse-begin\n";
+          break;
+	case _S_token_bracket_end:
+	  ostr << "bracket-end\n";
+	  break;
+	case _S_token_char_class_name:
+	  ostr << "char-class-name \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_closure0:
+	  ostr << "closure0\n";
+	  break;
+	case _S_token_closure1:
+	  ostr << "closure1\n";
+	  break;
+	case _S_token_collelem_multi:
+	  ostr << "coll-elem-multi \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_collelem_single:
+	  ostr << "coll-elem-single \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_collsymbol:
+	  ostr << "collsymbol \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_comma:
+	  ostr << "comma\n";
+	  break;
+	case _S_token_dash:
+	  ostr << "dash\n";
+	  break;
+	case _S_token_dup_count:
+	  ostr << "dup count: " << _M_curValue << "\n";
+	  break;
+	case _S_token_eof:
+	  ostr << "EOF\n";
+	  break;
+	case _S_token_equiv_class_name:
+	  ostr << "equiv-class-name \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_interval_begin:
+	  ostr << "interval begin\n";
+	  break;
+	case _S_token_interval_end:
+	  ostr << "interval end\n";
+	  break;
+	case _S_token_line_begin:
+	  ostr << "line begin\n";
+	  break;
+	case _S_token_line_end:
+	  ostr << "line end\n";
+	  break;
+	case _S_token_opt:
+	  ostr << "opt\n";
+	  break;
+	case _S_token_or:
+	  ostr << "or\n";
+	  break;
+	case _S_token_ord_char:
+	  ostr << "ordinary character: \"" << _M_value() << "\"\n";
+	  break;
+	case _S_token_subexpr_begin:
+	  ostr << "subexpr begin\n";
+	  break;
+	case _S_token_subexpr_end:
+	  ostr << "subexpr end\n";
+	  break;
+	case _S_token_word_begin:
+	  ostr << "word begin\n";
+	  break;
+	case _S_token_word_end:
+	  ostr << "word end\n";
+	  break;
+	case _S_token_unknown:
+	  ostr << "-- unknown token --\n";
+	  break;
+        default:
+          _GLIBCXX_DEBUG_ASSERT(false);
+      }
+      return ostr;
+    }
+#endif
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _Compiler(_InputIter __b, _InputIter __e,
+              const _TraitsT& __traits, _FlagT __flags)
+    : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()),
+      _M_state_store(__flags), _M_flags(__flags)
+    {
+      _StateSeqT __r(_M_state_store,
+      		    _M_state_store._M_insert_subexpr_begin());
+      _M_disjunction();
+      if (!_M_stack.empty())
+	{
+	  __r._M_append(_M_stack.top());
+	  _M_stack.pop();
+	}
+      __r._M_append(_M_state_store._M_insert_subexpr_end());
+      __r._M_append(_M_state_store._M_insert_accept());
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_match_token(_Compiler<_InputIter, _CharT, _TraitsT>::_TokenT token)
+    {
+      if (token == _M_scanner._M_token())
+	{
+          _M_cur_value = _M_scanner._M_value();
+          _M_scanner._M_advance();
+	  return true;
+	}
+      return false;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_disjunction()
+    {
+      this->_M_alternative();
+      if (_M_match_token(_ScannerT::_S_token_or))
+	{
+	  _StateSeqT __alt1 = _M_stack.top(); _M_stack.pop();
+	  this->_M_disjunction();
+	  _StateSeqT __alt2 = _M_stack.top(); _M_stack.pop();
+	  _M_stack.push(_StateSeqT(__alt1, __alt2));
+	}
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_alternative()
+    {
+      if (this->_M_term())
+	{
+	  _StateSeqT __re = _M_stack.top(); _M_stack.pop();
+	  this->_M_alternative();
+	  if (!_M_stack.empty())
+	    {
+	      __re._M_append(_M_stack.top());
+	      _M_stack.pop();
+	    }
+	  _M_stack.push(__re);
+	}
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_term()
+    {
+      if (this->_M_assertion())
+	return true;
+      if (this->_M_atom())
+	{
+	  this->_M_quantifier();
+	  return true;
+	}
+      return false;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_assertion()
+    {
+      if (_M_match_token(_ScannerT::_S_token_line_begin))
+	{
+	  // __m.push(_Matcher::_S_opcode_line_begin);
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_line_end))
+	{
+	  // __m.push(_Matcher::_S_opcode_line_end);
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_word_begin))
+	{
+	  // __m.push(_Matcher::_S_opcode_word_begin);
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_word_end))
+	{
+	  // __m.push(_Matcher::_S_opcode_word_end);
+	  return true;
+	}
+      return false;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_quantifier()
+    {
+      if (_M_match_token(_ScannerT::_S_token_closure0))
+	{
+	  if (_M_stack.empty())
+	    __throw_regex_error(regex_constants::error_badrepeat);
+	  _StateSeqT __r(_M_stack.top(), -1);
+	  __r._M_append(__r._M_front());
+	  _M_stack.pop();
+	  _M_stack.push(__r);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_closure1))
+	{
+	  if (_M_stack.empty())
+	    __throw_regex_error(regex_constants::error_badrepeat);
+	  _StateSeqT __r(_M_state_store,
+			_M_state_store.
+			_M_insert_alt(_S_invalid_state_id,
+				      _M_stack.top()._M_front()));
+	  _M_stack.top()._M_append(__r);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_opt))
+	{
+	  if (_M_stack.empty())
+	  __throw_regex_error(regex_constants::error_badrepeat);
+	  _StateSeqT __r(_M_stack.top(), -1);
+	  _M_stack.pop();
+	  _M_stack.push(__r);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_interval_begin))
+	{
+	  if (_M_stack.empty())
+	    __throw_regex_error(regex_constants::error_badrepeat);
+	  if (!_M_match_token(_ScannerT::_S_token_dup_count))
+	    __throw_regex_error(regex_constants::error_badbrace);
+	  _StateSeqT __r(_M_stack.top());
+	  int __min_rep = _M_cur_int_value(10);
+	  for (int __i = 1; __i < __min_rep; ++__i)
+	    _M_stack.top()._M_append(__r._M_clone());
+	  if (_M_match_token(_ScannerT::_S_token_comma))
+	    if (_M_match_token(_ScannerT::_S_token_dup_count))
+	      {
+		int __n = _M_cur_int_value(10) - __min_rep;
+		if (__n < 0)
+		  __throw_regex_error(regex_constants::error_badbrace);
+		for (int __i = 0; __i < __n; ++__i)
+		  {
+		    _StateSeqT __r(_M_state_store,
+				  _M_state_store.
+				  _M_insert_alt(_S_invalid_state_id,
+						_M_stack.top()._M_front()));
+		    _M_stack.top()._M_append(__r);
+		  }
+	      }
+	    else
+	      {
+		_StateSeqT __r(_M_stack.top(), -1);
+		__r._M_push_back(__r._M_front());
+		_M_stack.pop();
+		_M_stack.push(__r);
+	      }
+	  if (!_M_match_token(_ScannerT::_S_token_interval_end))
+	    __throw_regex_error(regex_constants::error_brace);
+	  return;
+	}
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_atom()
+    {
+      if (_M_match_token(_ScannerT::_S_token_anychar))
+	{
+          const static auto&
+          __any_matcher = [](_CharT) -> bool
+          { return true; };
+
+	  _M_stack.push(_StateSeqT(_M_state_store,
+                                  _M_state_store._M_insert_matcher
+                                  (__any_matcher)));
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_ord_char))
+	{
+          auto __c = _M_cur_value[0];
+          __detail::_Matcher<_CharT> f;
+          if (_M_flags & regex_constants::icase)
+            {
+              auto __traits = this->_M_traits;
+              __c = __traits.translate_nocase(__c);
+              f = [__traits, __c](_CharT __ch) -> bool
+              { return __traits.translate_nocase(__ch) == __c; };
+            }
+          else
+            f = [__c](_CharT __ch) -> bool
+            { return __ch == __c; };
+
+	  _M_stack.push(_StateSeqT(_M_state_store,
+                                   _M_state_store._M_insert_matcher(f)));
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_backref))
+	{
+	  // __m.push(_Matcher::_S_opcode_ordchar, _M_cur_value);
+          _M_state_store._M_set_backref(true);
+	  //return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
+	{
+	  int __mark = _M_state_store._M_sub_count();
+	  _StateSeqT __r(_M_state_store,
+			_M_state_store.
+			_M_insert_subexpr_begin());
+	  this->_M_disjunction();
+	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
+	    __throw_regex_error(regex_constants::error_paren);
+	  if (!_M_stack.empty())
+	    {
+	      __r._M_append(_M_stack.top());
+	      _M_stack.pop();
+	    }
+	  __r._M_append(_M_state_store._M_insert_subexpr_end());
+	  _M_stack.push(__r);
+	  return true;
+	}
+      return _M_bracket_expression();
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_bracket_expression()
+    {
+      bool __inverse =
+        _M_match_token(_ScannerT::_S_token_bracket_inverse_begin);
+      if (!(__inverse || _M_match_token(_ScannerT::_S_token_bracket_begin)))
+        return false;
+      _BMatcherT __matcher( __inverse, _M_traits, _M_flags);
+      // special case: only if  _not_ chr first after
+      // '[' or '[^' or if ECMAscript
+      if (!_M_bracket_list(__matcher) // list is empty
+          && !(_M_flags & regex_constants::ECMAScript))
+        __throw_regex_error(regex_constants::error_brack);
+      _M_stack.push(_StateSeqT(_M_state_store,
+                              _M_state_store._M_insert_matcher(__matcher)));
+      return true;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool // list is non-empty
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_bracket_list(_BMatcherT& __matcher)
+    {
+      if (_M_match_token(_ScannerT::_S_token_bracket_end))
+        return false;
+      _M_expression_term(__matcher);
+      _M_bracket_list(__matcher);
+      return true;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_expression_term(_BMatcherT& __matcher)
+    {
+      if (_M_match_token(_ScannerT::_S_token_collsymbol))
+	{
+	  __matcher._M_add_collating_element(_M_cur_value);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
+	{
+	  __matcher._M_add_equivalence_class(_M_cur_value);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_char_class_name))
+	{
+	  __matcher._M_add_character_class(_M_cur_value);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_collelem_single)) // [a
+        {
+          auto __ch = _M_cur_value[0];
+          if (_M_match_token(_ScannerT::_S_token_dash)) // [a-
+            {
+              // If the dash is the last character in the bracket expression,
+              // it is not special.
+              if (_M_scanner._M_token() == _ScannerT::_S_token_bracket_end)
+                __matcher._M_add_char(_M_cur_value[0]); // [a-] <=> [a\-]
+              else // [a-z]
+                {
+                  if (!_M_match_token(_ScannerT::_S_token_collelem_single))
+                    __throw_regex_error(regex_constants::error_range);
+                  __matcher._M_make_range(__ch, _M_cur_value[0]);
+                }
+            }
+          else // [a]
+            __matcher._M_add_char(__ch);
+          return;
+        }
+      __throw_regex_error(regex_constants::error_brack);
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    int
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_cur_int_value(int __radix)
+    {
+      int __v = 0;
+      for (typename _StringT::size_type __i = 0;
+	   __i < _M_cur_value.length(); ++__i)
+	__v =__v * __radix + _M_traits.value(_M_cur_value[__i], __radix);
+      return __v;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    bool _BracketMatcher<_CharT, _TraitsT>::
+    operator()(_CharT __ch) const
+    {
+      auto __oldch = __ch;
+      if (_M_flags & regex_constants::collate)
+        if (_M_is_icase())
+          __ch = _M_traits.translate_nocase(__ch);
+        else
+          __ch = _M_traits.translate(__ch);
+
+      bool __ret = false;
+      for (auto __c : _M_char_set)
+        if (__c == __ch)
+          {
+            __ret = true;
+            break;
+          }
+      if (!__ret && _M_traits.isctype(__oldch, _M_class_set))
+        __ret = true;
+      else
+        {
+          _StringT __s = _M_get_str(__ch);
+          for (auto& __it : _M_range_set)
+            if (__it.first <= __s && __s <= __it.second)
+              {
+                __ret = true;
+                break;
+              }
+        }
+      if (_M_is_non_matching)
+        __ret = !__ret;
+      return __ret;
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
Index: include/bits/regex_constants.h
===================================================================
--- include/bits/regex_constants.h	(revision 201492)
+++ include/bits/regex_constants.h	(working copy)
@@ -79,7 +79,7 @@
    */
   typedef unsigned int syntax_option_type;
 
-  /** 
+  /**
    * Specifies that the matching of regular expressions against a character
    * sequence shall be performed without regard to case.
    */
@@ -139,7 +139,7 @@
    * 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).  
+   * and \\ddd (where ddd is one, two, or three octal digits).
    */
   constexpr syntax_option_type awk        = 1 << _S_awk;
 
@@ -154,7 +154,7 @@
   /**
    * 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 
+   * IEEE Std 1003.1-2001.  This option is identical to syntax_option_type
    * extended, except that newlines are treated as whitespace.
    */
   constexpr syntax_option_type egrep      = 1 << _S_egrep;
@@ -215,35 +215,35 @@
    * expression shall not match [last, last).
    */
   constexpr match_flag_type match_not_eol     = 1 << _S_not_eol;
-   
+
   /**
    * The expression \\b is not matched against the sub-sequence
    * [first,first).
    */
   constexpr match_flag_type match_not_bow     = 1 << _S_not_bow;
-   
+
   /**
    * The expression \\b should not be matched against the sub-sequence
    * [last,last).
    */
   constexpr match_flag_type match_not_eow     = 1 << _S_not_eow;
-   
+
   /**
    * If more than one match is possible then any match is an acceptable
    * result.
    */
   constexpr match_flag_type match_any         = 1 << _S_any;
-   
+
   /**
    * The expression does not match an empty sequence.
    */
   constexpr match_flag_type match_not_null    = 1 << _S_not_null;
-   
+
   /**
    * The expression only matches a sub-sequence that begins at first .
    */
   constexpr 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
@@ -260,7 +260,7 @@
    * 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.
Index: include/bits/regex_cursor.h
===================================================================
--- include/bits/regex_cursor.h	(revision 201492)
+++ include/bits/regex_cursor.h	(working copy)
@@ -1,105 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_cursor.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   *  @defgroup regex-detail Base and Implementation Classes
-   *  @ingroup regex
-   *  @{
-   */
-
-  /// ABC for pattern matching
-  struct _PatternCursor
-  {
-    virtual ~_PatternCursor() { };
-    virtual void _M_next() = 0;
-    virtual void _M_prev() = 0;
-    virtual bool _M_at_end() const = 0;
-  };
-
-  /// Provides a cursor into the specific target string.
-  template<typename _FwdIterT>
-    class _SpecializedCursor
-    : public _PatternCursor
-    {
-    public:
-      _SpecializedCursor(const _FwdIterT& __b, const _FwdIterT __e)
-      : _M_b(__b), _M_c(__b), _M_e(__e)
-      { }
-
-      typename std::iterator_traits<_FwdIterT>::value_type
-      _M_current() const
-      { return *_M_c; }
-
-      void
-      _M_next()
-      { ++_M_c; }
-
-      void
-      _M_prev()
-      { --_M_c; }
-
-      _FwdIterT
-      _M_pos() const
-      { return _M_c; }
-
-      const _FwdIterT&
-      _M_begin() const
-      { return _M_b; }
-
-      const _FwdIterT&
-      _M_end() const
-      { return _M_e; }
-
-      bool
-      _M_at_end() const
-      { return _M_c == _M_e; }
-
-    private:
-      _FwdIterT _M_b;
-      _FwdIterT _M_c;
-      _FwdIterT _M_e;
-    };
-
-  // Helper function to create a cursor specialized for an iterator class.
-  template<typename _FwdIterT>
-    inline _SpecializedCursor<_FwdIterT>
-    __cursor(const _FwdIterT& __b, const _FwdIterT __e)
-    { return _SpecializedCursor<_FwdIterT>(__b, __e); }
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
Index: include/bits/regex_error.h
===================================================================
--- include/bits/regex_error.h	(revision 201492)
+++ include/bits/regex_error.h	(working copy)
@@ -45,7 +45,7 @@
    * @name 5.3 Error Types
    */
   //@{
- 
+
   enum error_type
     {
       _S_error_collate,
Index: include/bits/regex_executor.h
===================================================================
--- include/bits/regex_executor.h	(revision 0)
+++ include/bits/regex_executor.h	(working copy)
@@ -0,0 +1,200 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_executor.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template<typename, typename>
+    class basic_regex;
+
+  template<typename, typename>
+    class match_results;
+_GLIBCXX_END_NAMESPACE_VERSION
+
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @defgroup regex-detail Base and Implementation Classes
+   *  @ingroup regex
+   *  @{
+   */
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    class _Executor
+    {
+    public:
+      typedef match_results<_BiIter, _Alloc>   _ResultsT;
+      typedef regex_constants::match_flag_type _FlagT;
+
+      virtual
+      ~_Executor()
+      { }
+
+      // Set matched when string exactly match the pattern.
+      virtual bool
+      _M_match() = 0;
+
+      // Set matched when some prefix of the string matches the pattern.
+      virtual bool
+      _M_search_from_first() = 0;
+
+    protected:
+      typedef typename _NFA<_CharT, _TraitsT>::_SizeT _SizeT;
+      _Executor(_BiIter    __begin,
+                _BiIter    __end,
+                _ResultsT& __results,
+                _FlagT     __flags,
+                _SizeT     __size)
+      : _M_current(__begin), _M_end(__end),
+        _M_results(__results), _M_flags(__flags)
+      {
+        __results.resize(__size + 2);
+        for (auto __it : __results)
+          __it.matched = false;
+      }
+
+      _BiIter   _M_current;
+      _BiIter   _M_end;
+      _ResultsT& _M_results;
+      _FlagT    _M_flags;
+    };
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    class _DFSExecutor
+    : public _Executor<_BiIter, _Alloc, _CharT, _TraitsT>
+    {
+    public:
+      typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT;
+      typedef _NFA<_CharT, _TraitsT>                       _RegexT;
+      typedef typename _BaseT::_ResultsT                    _ResultsT;
+      typedef regex_constants::match_flag_type             _FlagT;
+
+      _DFSExecutor(_BiIter        __begin,
+                   _BiIter        __end,
+                   _ResultsT&      __results,
+                   const _RegexT& __nfa,
+                   _FlagT         __flags)
+      : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
+        _M_nfa(__nfa)
+      { }
+
+      bool
+      _M_match()
+      { return _M_dfs<true>(_M_nfa._M_start()); }
+
+      bool
+      _M_search_from_first()
+      { return _M_dfs<false>(_M_nfa._M_start()); }
+
+    private:
+      template<bool __match_mode>
+        bool
+        _M_dfs(_StateIdT __i);
+
+      const _RegexT& _M_nfa;
+    };
+
+  // It's essentially a variant of Single-Source-Shortest-Path problem, where,
+  // the matching results is the final distance and should be minimized.
+  // Instead of using Dijkstra Algorithm, I pick up the queue-optimizaed
+  // (BFS-like) Bellman-Ford algorithm,
+  // SPFA(http://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm).
+  //
+  // Every entry of _M_covered saves the solution(grouping status) for every
+  // matching head. When states transfer, solutions will be compared and
+  // deduplicated(based on which greedy mode we have).
+  //
+  // Time complexity: O(_M_str_cur.size() * _M_nfa.size())
+  // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count())
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    class _BFSExecutor
+    : public _Executor<_BiIter, _Alloc, _CharT, _TraitsT>
+    {
+    public:
+      typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT;
+      typedef _NFA<_CharT, _TraitsT>                       _RegexT;
+      typedef typename _BaseT::_ResultsT                   _ResultsT;
+      typedef std::unique_ptr<_ResultsT>                   _ResultsPtr;
+      typedef regex_constants::match_flag_type             _FlagT;
+
+      _BFSExecutor(_BiIter        __begin,
+                   _BiIter        __end,
+                   _ResultsT&      __results,
+                   const _RegexT& __nfa,
+                   _FlagT         __flags)
+      : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
+        _M_nfa(__nfa)
+      {
+        if (_M_nfa._M_start() != _S_invalid_state_id)
+          _M_covered[_M_nfa._M_start()] =
+            _ResultsPtr(new _ResultsT(this->_M_results));
+        _M_e_closure();
+      }
+
+      bool
+      _M_match()
+      { return _M_main_loop<true>(); }
+
+      bool
+      _M_search_from_first()
+      { return _M_main_loop<false>(); }
+
+    private:
+      template<bool __match_mode>
+        bool
+        _M_main_loop();
+
+      void
+      _M_e_closure();
+
+      void
+      _M_move();
+
+      bool
+      _M_match_less_than(_StateIdT __u, _StateIdT __v) const;
+
+      bool
+      _M_includes_some() const;
+
+      std::map<_StateIdT, _ResultsPtr>     _M_covered;
+      const _RegexT& _M_nfa;
+    };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_executor.tcc>
Index: include/bits/regex_executor.tcc
===================================================================
--- include/bits/regex_executor.tcc	(revision 0)
+++ include/bits/regex_executor.tcc	(working copy)
@@ -0,0 +1,252 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_executor.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // TODO: This is too slow. Try to compile the NFA to a DFA.
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+  template<bool __match_mode>
+    bool _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_dfs(_StateIdT __i)
+    {
+      auto& __current = this->_M_current;
+      auto& __end = this->_M_end;
+      auto& __results = this->_M_results;
+      if (__i == _S_invalid_state_id)
+        // This is not that certain. Need deeper investigate.
+        return false;
+      const auto& __state = _M_nfa[__i];
+      bool __ret = false;
+      switch (__state._M_opcode)
+        {
+        case _S_opcode_alternative:
+          // Greedy mode by default. For non-greedy mode,
+          // swap _M_alt and _M_next.
+          // TODO: Add greedy mode option.
+          __ret = _M_dfs<__match_mode>(__state._M_alt)
+            || _M_dfs<__match_mode>(__state._M_next);
+          break;
+        case _S_opcode_subexpr_begin:
+          __results.at(__state._M_subexpr).first = __current;
+          __ret = _M_dfs<__match_mode>(__state._M_next);
+          break;
+        case _S_opcode_subexpr_end:
+          __ret = _M_dfs<__match_mode>(__state._M_next);
+          __results.at(__state._M_subexpr).second = __current;
+          __results.at(__state._M_subexpr).matched = __ret;
+          break;
+        case _S_opcode_match:
+          if (__current != __end && __state._M_matches(*__current))
+            {
+              ++__current;
+              __ret = _M_dfs<__match_mode>(__state._M_next);
+              --__current;
+            }
+          break;
+        case _S_opcode_accept:
+          if (__match_mode)
+            __ret = __current == __end;
+          else
+            __ret = true;
+          break;
+        default:
+          _GLIBCXX_DEBUG_ASSERT(false);
+        }
+      return __ret;
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+  template<bool __match_mode>
+    bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_main_loop()
+    {
+      while (this->_M_current != this->_M_end)
+        {
+          if (!__match_mode)
+            if (_M_includes_some())
+              return true;
+          _M_move();
+          ++this->_M_current;
+          _M_e_closure();
+        }
+      return _M_includes_some();
+    }
+
+  // The SPFA approach.
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_e_closure()
+    {
+      auto& __current = this->_M_current;
+      std::queue<_StateIdT> __q;
+      std::vector<bool> __in_q(_M_nfa.size(), false);
+      for (auto& __it : _M_covered)
+        {
+          __in_q[__it.first] = true;
+          __q.push(__it.first);
+        }
+      while (!__q.empty())
+        {
+          auto __u = __q.front();
+          __q.pop();
+          __in_q[__u] = false;
+          const auto& __state = _M_nfa[__u];
+
+          // Can be implemented using method, but there're too much arguments.
+          auto __add_visited_state = [&](_StateIdT __v)
+          {
+            if (__v == _S_invalid_state_id)
+              return;
+            if (_M_match_less_than(__u, __v))
+              {
+                _M_covered[__v] = _ResultsPtr(new _ResultsT(*_M_covered[__u]));
+                // if a state is updated, it's outgoing neighbors should be
+                // reconsidered too. Push them to the queue.
+                if (!__in_q[__v])
+                  {
+                    __in_q[__v] = true;
+                    __q.push(__v);
+                  }
+              }
+          };
+
+          switch (__state._M_opcode)
+            {
+              case _S_opcode_alternative:
+                __add_visited_state(__state._M_next);
+                __add_visited_state(__state._M_alt);
+                break;
+              case _S_opcode_subexpr_begin:
+                _M_covered[__u]->at(__state._M_subexpr).first = __current;
+                __add_visited_state(__state._M_next);
+                break;
+              case _S_opcode_subexpr_end:
+                _M_covered[__u]->at(__state._M_subexpr).second = __current;
+                _M_covered[__u]->at(__state._M_subexpr).matched = true;
+                __add_visited_state(__state._M_next);
+                break;
+              case _S_opcode_match:
+                break;
+              case _S_opcode_accept:
+                __add_visited_state(__state._M_next);
+                break;
+              default:
+                _GLIBCXX_DEBUG_ASSERT(false);
+            }
+        }
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_move()
+    {
+      decltype(_M_covered) __next;
+      for (auto& __it : _M_covered)
+        {
+          const auto& __state = _M_nfa[__it.first];
+          if (__state._M_opcode == _S_opcode_match
+              && __state._M_matches(*this->_M_current))
+            if (_M_match_less_than(__it.first, __state._M_next)
+                && __state._M_next != _S_invalid_state_id)
+              __next[__state._M_next] = move(__it.second);
+        }
+      _M_covered = move(__next);
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_match_less_than(_StateIdT __u, _StateIdT __v) const
+    {
+      if (_M_covered.count(__u) == 0)
+        return false;
+      if (_M_covered.count(__v) > 0)
+        return true;
+      // TODO: Greedy and Non-greedy support
+      return true;
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_includes_some() const
+    {
+      auto& __s = _M_nfa._M_final_states();
+      auto& __t = _M_covered;
+      if (__s.size() > 0 && __t.size() > 0)
+        {
+          auto __first = __s.begin();
+          auto __second = __t.begin();
+          while (__first != __s.end() && __second != __t.end())
+            {
+              if (*__first < __second->first)
+                ++__first;
+              else if (__second->first < *__first)
+                ++__second;
+              else
+                {
+                  this->_M_results = *__second->second;
+                  return true;
+                }
+            }
+        }
+      return false;
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+    __get_executor(_BiIter __b,
+                   _BiIter __e,
+                   match_results<_BiIter, _Alloc>& __m,
+                   const basic_regex<_CharT, _TraitsT>& __re,
+                   regex_constants::match_flag_type __flags)
+    {
+      typedef std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+        _ExecutorPtr;
+      typedef _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _DFSExecutorT;
+      auto __p = std::static_pointer_cast<_NFA<_CharT, _TraitsT>>
+        (__re._M_automaton);
+      if (__p->_M_has_backref)
+        return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p, __flags));
+      return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p, __flags));
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
Index: include/bits/regex_grep_matcher.h
===================================================================
--- include/bits/regex_grep_matcher.h	(revision 201492)
+++ include/bits/regex_grep_matcher.h	(working copy)
@@ -1,260 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_grep_matcher.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _BiIter>
-    class sub_match;
-
-  template<typename _Bi_iter, typename _Allocator>
-    class match_results;
-
-_GLIBCXX_END_NAMESPACE_VERSION
-  
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   *  @defgroup regex-detail Base and Implementation Classes
-   *  @ingroup regex
-   *  @{
-   */
-
-  /// A _Results facade specialized for wrapping a templated match_results.
-  template<typename _FwdIterT, typename _Alloc>
-    class _SpecializedResults
-    : public _Results
-    {
-    public:
-      _SpecializedResults(const _Automaton::_SizeT __size,
-			  const _SpecializedCursor<_FwdIterT>& __cursor,
-			  match_results<_FwdIterT, _Alloc>& __m);
-
-      ~_SpecializedResults()
-      {
-        if (_M_managed)
-          delete &_M_results;
-      }
-
-    private:
-      _SpecializedResults(const _SpecializedResults& __rhs)
-      : _M_results(*new match_results<_FwdIterT, _Alloc>(__rhs._M_results)),
-      _M_managed(true)
-      { }
-
-    public:
-      void
-      _M_set_pos(int __i, int __j, const _PatternCursor& __pc);
-
-      void
-      _M_set_range(int __i, const _PatternCursor& __pc)
-      {
-        typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
-        _CursorT __c = static_cast<_CursorT>(__pc);
-        _M_results.at(__i).first = __c._M_begin();
-        _M_results.at(__i).second = __c._M_end();
-      }
-
-      void
-      _M_set_matched(int __i, bool __is_matched)
-      { _M_results.at(__i).matched = __is_matched; }
-
-      std::unique_ptr<_Results>
-      _M_clone() const
-      { return unique_ptr<_Results>(new _SpecializedResults(*this)); }
-
-      void
-      _M_assign(const _Results& __rhs)
-      {
-        auto __r = static_cast<const _SpecializedResults*>(&__rhs);
-        _M_results = __r->_M_results;
-      }
-
-    private:
-      match_results<_FwdIterT, _Alloc>& _M_results;
-      bool                              _M_managed;
-    };
-
-  template<typename _FwdIterT, typename _Alloc>
-    _SpecializedResults<_FwdIterT, _Alloc>::
-    _SpecializedResults(const _Automaton::_SizeT __size,
-    			const _SpecializedCursor<_FwdIterT>& __cursor,
-                        match_results<_FwdIterT, _Alloc>& __m)
-    : _M_results(__m), _M_managed(false)
-    {
-      _M_results.clear();
-      _M_results.reserve(__size + 2);
-      _M_results.resize(__size);
-      typename match_results<_FwdIterT, _Alloc>::value_type __sm;
-      __sm.first = __sm.second = __cursor._M_begin();
-      _M_results.push_back(__sm);
-      __sm.first = __sm.second = __cursor._M_end();
-      _M_results.push_back(__sm);
-    }
-
-  template<typename _FwdIterT, typename _Alloc>
-    void
-    _SpecializedResults<_FwdIterT, _Alloc>::
-    _M_set_pos(int __i, int __j, const _PatternCursor& __pc)
-    { 
-      typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
-      _CursorT __c = static_cast<_CursorT>(__pc);
-      if (__j == 0)
-        _M_results.at(__i).first = __c._M_pos();
-      else
-        _M_results.at(__i).second = __c._M_pos();
-    }
-
-  /// Executes a regular expression NFA/DFA over a range using a
-  /// variant of the parallel execution algorithm featured in the grep
-  /// utility, modified to use Laurikari tags.
-  class _Grep_matcher
-  {
-  public:
-    _Grep_matcher(_PatternCursor&                   __p,
-                  _Results&                         __r,
-                  const _AutomatonPtr&              __automaton,
-                  regex_constants::match_flag_type  __flags)
-    : _M_nfa(static_pointer_cast<_Nfa>(__automaton)),
-      _M_str_cur(__p), _M_results(__r)
-    { }
-
-    virtual
-    ~_Grep_matcher()
-    { }
-
-    // Set matched when string exactly match the pattern.
-    virtual bool
-    _M_match() = 0;
-
-    // Set matched when some prefix of the string matches the pattern.
-    virtual bool
-    _M_search_from_first() = 0;
-
-  protected:
-    const std::shared_ptr<_Nfa>        _M_nfa;
-    _PatternCursor&                    _M_str_cur;
-    _Results&                          _M_results;
-  };
-
-  // Time complexity: exponential
-  // Space complexity: O(_M_str_cur.size())
-  // _M_dfs() take a state, along with current string cursor(_M_str_cur),
-  // trying to match current state with current character.
-  // Only _S_opcode_match will consume a character.
-  class _DFSMatcher
-  : public _Grep_matcher
-  {
-  public:
-    _DFSMatcher(_PatternCursor&                   __p,
-                _Results&                         __r,
-                const _AutomatonPtr&              __automaton,
-                regex_constants::match_flag_type  __flags)
-    : _Grep_matcher(__p, __r, __automaton, __flags)
-    { }
-
-    bool
-    _M_match()
-    { return _M_dfs<true>(_M_nfa->_M_start()); }
-
-    bool
-    _M_search_from_first()
-    { return _M_dfs<false>(_M_nfa->_M_start()); }
-
-  private:
-    template<bool __match_mode>
-      bool
-      _M_dfs(_StateIdT __i);
-  };
-
-  // It's essentially a variant of Single-Source-Shortest-Path problem, where,
-  // the matching results is the final distance and should be minimized.
-  // Instead of using Dijkstra Algorithm, I pick up the queue-optimizaed
-  // (BFS-like) Bellman-Ford algorithm,
-  // SPFA(http://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm).
-  //
-  // Every entry of _M_current saves the solution(grouping status) for every
-  // matching head. When states transfer, solutions will be compared and
-  // deduplicated(based on which greedy mode we have).
-  //
-  // Time complexity: O(_M_str_cur.size() * _M_nfa.size())
-  // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count())
-  class _BFSMatcher
-  : public _Grep_matcher
-  {
-  public:
-    _BFSMatcher(_PatternCursor&                   __p,
-                _Results&                         __r,
-                const _AutomatonPtr&              __automaton,
-                regex_constants::match_flag_type  __flags)
-    : _Grep_matcher(__p, __r, __automaton, __flags)
-    {
-      if (_M_nfa->_M_start() != _S_invalid_state_id)
-        _M_current[_M_nfa->_M_start()] = _M_results._M_clone();
-      _M_e_closure();
-    }
-
-    bool
-    _M_match()
-    { return _M_main_loop<true>(); }
-
-    bool
-    _M_search_from_first()
-    { return _M_main_loop<false>(); }
-
-  private:
-    template<bool __match_mode>
-      bool
-      _M_main_loop();
-
-    void
-    _M_e_closure();
-
-    void
-    _M_move();
-
-    bool
-    _M_match_less_than(_StateIdT __u, _StateIdT __v) const;
-
-    bool
-    _M_includes_some() const;
-
-    std::map<_StateIdT, std::unique_ptr<_Results>>     _M_current;
-  };
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace std
-
-#include <bits/regex_grep_matcher.tcc>
Index: include/bits/regex_grep_matcher.tcc
===================================================================
--- include/bits/regex_grep_matcher.tcc	(revision 201492)
+++ include/bits/regex_grep_matcher.tcc	(working copy)
@@ -1,243 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_grep_matcher.tcc
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-#include <regex>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  // TODO: This is too slow. Try to compile the NFA to a DFA.
-  template<bool __match_mode>
-    bool _DFSMatcher::
-    _M_dfs(_StateIdT __i)
-    {
-      if (__i == _S_invalid_state_id)
-        // This is not that certain. Need deeper investigate.
-        return false;
-      const auto& __state = (*_M_nfa)[__i];
-      bool __ret = false;
-      switch (__state._M_opcode)
-        {
-        case _S_opcode_alternative:
-          // Greedy mode by default. For non-greedy mode,
-          // swap _M_alt and _M_next.
-          // TODO: Add greedy mode option.
-          __ret = _M_dfs<__match_mode>(__state._M_alt)
-            || _M_dfs<__match_mode>(__state._M_next);
-          break;
-        case _S_opcode_subexpr_begin:
-          __state._M_tagger(_M_str_cur, _M_results);
-          __ret = _M_dfs<__match_mode>(__state._M_next);
-          break;
-        case _S_opcode_subexpr_end:
-          __state._M_tagger(_M_str_cur, _M_results);
-          __ret = _M_dfs<__match_mode>(__state._M_next);
-          _M_results._M_set_matched(__state._M_subexpr, __ret);
-          break;
-        case _S_opcode_match:
-          if (!_M_str_cur._M_at_end() && __state._M_matches(_M_str_cur))
-            {
-              _M_str_cur._M_next();
-              __ret = _M_dfs<__match_mode>(__state._M_next);
-              _M_str_cur._M_prev();
-            }
-          break;
-        case _S_opcode_accept:
-          if (__match_mode)
-            __ret = _M_str_cur._M_at_end();
-          else
-            __ret = true;
-          break;
-        default:
-          _GLIBCXX_DEBUG_ASSERT(false);
-        }
-      return __ret;
-    }
-
-  template<bool __match_mode>
-    bool _BFSMatcher::
-    _M_main_loop()
-    {
-      while (!_M_str_cur._M_at_end())
-        {
-          if (!__match_mode)
-            if (_M_includes_some())
-              return true;
-          _M_move();
-          _M_str_cur._M_next();
-          _M_e_closure();
-        }
-      return _M_includes_some();
-    }
-
-  // The SPFA approach.
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  void _BFSMatcher::
-  _M_e_closure()
-  {
-    std::queue<_StateIdT> __q;
-    std::vector<bool> __in_q(_M_nfa->size(), false);
-    for (auto& __it : _M_current)
-      {
-        __in_q[__it.first] = true;
-        __q.push(__it.first);
-      }
-    while (!__q.empty())
-      {
-        auto __u = __q.front();
-        __q.pop();
-        __in_q[__u] = false;
-        const auto& __state = (*_M_nfa)[__u];
-
-        // Can be implemented using method, but there're too much arguments.
-        auto __add_visited_state = [&](_StateIdT __v)
-        {
-          if (__v == _S_invalid_state_id)
-            return;
-          if (_M_match_less_than(__u, __v))
-            {
-              _M_current[__v] = _M_current[__u]->_M_clone();
-              // if a state is updated, it's outgoing neighbors should be
-              // reconsidered too. Push them to the queue.
-              if (!__in_q[__v])
-                {
-                  __in_q[__v] = true;
-                  __q.push(__v);
-                }
-            }
-        };
-
-        switch (__state._M_opcode)
-          {
-            case _S_opcode_alternative:
-              __add_visited_state(__state._M_next);
-              __add_visited_state(__state._M_alt);
-              break;
-            case _S_opcode_subexpr_begin:
-              __state._M_tagger(_M_str_cur, *_M_current[__u]);
-              __add_visited_state(__state._M_next);
-              break;
-            case _S_opcode_subexpr_end:
-              __state._M_tagger(_M_str_cur, *_M_current[__u]);
-              _M_current[__u]->_M_set_matched(__state._M_subexpr, true);
-              __add_visited_state(__state._M_next);
-              break;
-            case _S_opcode_match:
-              break;
-            case _S_opcode_accept:
-              __add_visited_state(__state._M_next);
-              break;
-            default:
-              _GLIBCXX_DEBUG_ASSERT(false);
-          }
-      }
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  void _BFSMatcher::
-  _M_move()
-  {
-    decltype(_M_current) __next;
-    for (auto& __it : _M_current)
-      {
-        const auto& __state = (*_M_nfa)[__it.first];
-        if (__state._M_opcode == _S_opcode_match
-            && __state._M_matches(_M_str_cur))
-          if (_M_match_less_than(__it.first, __state._M_next)
-              && __state._M_next != _S_invalid_state_id)
-            __next[__state._M_next] = __it.second->_M_clone();
-      }
-    _M_current = move(__next);
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  bool _BFSMatcher::
-  _M_match_less_than(_StateIdT __u, _StateIdT __v) const
-  {
-    if (_M_current.count(__u) == 0)
-      return false;
-    if (_M_current.count(__v) > 0)
-      return true;
-    // TODO: Greedy and Non-greedy support
-    return true;
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  bool _BFSMatcher::
-  _M_includes_some() const
-  {
-    auto& __s = _M_nfa->_M_final_states();
-    auto& __t = _M_current;
-    if (__s.size() > 0 && __t.size() > 0)
-      {
-	auto __first = __s.begin();
-	auto __second = __t.begin();
-	while (__first != __s.end() && __second != __t.end())
-	  {
-	    if (*__first < __second->first)
-	      ++__first;
-	    else if (__second->first < *__first)
-	      ++__second;
-	    else
-              {
-                _M_results._M_assign(*__second->second);
-                return true;
-              }
-	  }
-      }
-    return false;
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  std::unique_ptr<_Grep_matcher> _Nfa::
-  _M_get_matcher(_PatternCursor&                   __p,
-                 _Results&                         __r,
-                 const _AutomatonPtr&              __a,
-                 regex_constants::match_flag_type  __flags)
-  {
-    if (_M_has_back_ref)
-      return unique_ptr<_Grep_matcher>(
-        new _DFSMatcher(__p, __r, __a, __flags));
-    else
-      return unique_ptr<_Grep_matcher>(
-        new _BFSMatcher(__p, __r, __a, __flags));
-  }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
Index: include/bits/regex_nfa.h
===================================================================
--- include/bits/regex_nfa.h	(revision 201492)
+++ include/bits/regex_nfa.h	(working copy)
@@ -1,491 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_nfa.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   * @addtogroup regex-detail
-   * @{
-   */
-
-  /// Provides a generic facade for a templated match_results.
-  struct _Results
-  {
-    virtual
-    ~_Results()
-    { }
-    virtual void _M_set_pos(int __i, int __j, const _PatternCursor& __p) = 0;
-    virtual void _M_set_matched(int __i, bool __is_matched) = 0;
-    virtual std::unique_ptr<_Results> _M_clone() const = 0;
-    virtual void _M_assign(const _Results& __rhs) = 0;
-  };
-
-  class _Grep_matcher;
-  class _Automaton;
-
-  /// Generic shared pointer to an automaton.
-  typedef std::shared_ptr<_Automaton> _AutomatonPtr;
-
-  /// Base class for, um, automata.  Could be an NFA or a DFA.  Your choice.
-  class _Automaton
-  {
-  public:
-    typedef unsigned int _SizeT;
-
-  public:
-    virtual
-    ~_Automaton() { }
-
-    virtual _SizeT
-    _M_sub_count() const = 0;
-
-    virtual std::unique_ptr<_Grep_matcher>
-    _M_get_matcher(_PatternCursor&                   __p,
-                   _Results&                         __r,
-                   const _AutomatonPtr&              __automaton,
-                   regex_constants::match_flag_type  __flags) = 0;
-
-#ifdef _GLIBCXX_DEBUG
-    virtual std::ostream&
-    _M_dot(std::ostream& __ostr) const = 0;
-#endif
-  };
-
-  /// Operation codes that define the type of transitions within the base NFA
-  /// that represents the regular expression.
-  enum _Opcode
-  {
-      _S_opcode_unknown       =   0,
-      _S_opcode_alternative   =   1,
-      _S_opcode_subexpr_begin =   4,
-      _S_opcode_subexpr_end   =   5,
-      _S_opcode_match         = 100,
-      _S_opcode_accept        = 255
-  };
-
-  /// Tags current state (for subexpr begin/end).
-  typedef std::function<void (const _PatternCursor&, _Results&)> _Tagger;
-
-  /// Start state tag.
-  template<typename _FwdIterT, typename _TraitsT>
-    struct _StartTagger
-    {
-      explicit
-      _StartTagger(int __i)
-      : _M_index(__i)
-      { }
-
-      void
-      operator()(const _PatternCursor& __pc, _Results& __r)
-      { __r._M_set_pos(_M_index, 0, __pc); }
-
-      int       _M_index;
-    };
-
-  /// End state tag.
-  template<typename _FwdIterT, typename _TraitsT>
-    struct _EndTagger
-    {
-      explicit
-      _EndTagger(int __i)
-      : _M_index(__i)
-      { }
-
-      void
-      operator()(const _PatternCursor& __pc, _Results& __r)
-      { __r._M_set_pos(_M_index, 1, __pc); }
-
-      int       _M_index;
-    };
-
-  // TODO For now we use an all-in-one comparator. In the future there may be
-  // optimizations based on regex_traits::translate and regex_transform.
-  template<typename _InIterT, typename _TraitsT>
-    struct _Comparator
-    {
-      typedef regex_constants::syntax_option_type _FlagT;
-      typedef typename _TraitsT::char_type        _CharT;
-      typedef std::basic_string<_CharT>           _StringT;
-
-      _Comparator(_FlagT __flags, const _TraitsT& __traits)
-      : _M_flags(__flags), _M_traits(__traits)
-      { }
-
-      bool
-      _M_equ(_CharT __a, _CharT __b) const;
-
-      bool
-      _M_le(_CharT __a, _CharT __b) const;
-
-      _FlagT                              _M_flags;
-      _TraitsT                            _M_traits;
-    };
-
-  /// Indicates if current state matches cursor current.
-  typedef std::function<bool (const _PatternCursor&)> _Matcher;
-
-  /// Matches any character
-  inline bool
-  _AnyMatcher(const _PatternCursor&)
-  { return true; }
-
-  /// Matches a single character
-  template<typename _InIterT, typename _TraitsT>
-    struct _CharMatcher
-    : public _Comparator<_InIterT, _TraitsT>
-    {
-      typedef _Comparator<_InIterT, _TraitsT>     _BaseT;
-      typedef typename _TraitsT::char_type        _CharT;
-      typedef regex_constants::syntax_option_type _FlagT;
-
-      explicit
-      _CharMatcher(_CharT __c, _FlagT __flags, const _TraitsT& __t)
-      : _BaseT(__flags, __t), _M_c(__c)
-      { }
-
-      bool
-      operator()(const _PatternCursor& __pc) const
-      {
-	typedef const _SpecializedCursor<_InIterT>& _CursorT;
-	_CursorT __c = static_cast<_CursorT>(__pc);
-        return this->_M_equ(__c._M_current(), _M_c);
-      }
-
-      _CharT       _M_c;
-    };
-
-  /// Matches a character range (bracket expression)
-  template<typename _InIterT, typename _TraitsT>
-    struct _BracketMatcher
-    : public _Comparator<_InIterT, _TraitsT>
-    {
-      typedef _Comparator<_InIterT, _TraitsT>     _BaseT;
-      typedef typename _TraitsT::char_class_type  _CharClassT;
-      typedef regex_constants::syntax_option_type _FlagT;
-      typedef typename _TraitsT::char_type        _CharT;
-      typedef std::basic_string<_CharT>           _StringT;
-
-      explicit
-      _BracketMatcher(bool __is_non_matching,
-                    _FlagT __flags,
-                    const _TraitsT& __t)
-      : _BaseT(__flags, __t), _M_flags(__flags), _M_traits(__t),
-      _M_is_non_matching(__is_non_matching), _M_class_set(0)
-      { }
-
-      bool
-      operator()(const _PatternCursor& __pc) const;
-
-      void
-      _M_add_char(_CharT __c)
-      { _M_char_set.push_back(__c); }
-
-      void
-      _M_add_collating_element(const _StringT& __s)
-      {
-        auto __st = _M_traits.lookup_collatename(&*__s.begin(), &*__s.end());
-        if (__st.empty())
-          __throw_regex_error(regex_constants::error_collate);
-        // TODO: digraph
-        _M_char_set.push_back(__st[0]);
-      }
-
-      void
-      _M_add_equivalence_class(const _StringT& __s)
-      {
-        _M_add_character_class(
-          _M_traits.transform_primary(&*__s.begin(), &*__s.end()));
-      }
-
-      void
-      _M_add_character_class(const _StringT& __s)
-      {
-        auto __st = _M_traits.lookup_classname(
-          &*__s.begin(), &*__s.end(), (_M_flags & regex_constants::icase));
-        if (__st == 0)
-          __throw_regex_error(regex_constants::error_ctype);
-        _M_class_set |= __st;
-      }
-
-      void
-      _M_make_range(_CharT __l, _CharT __r)
-      {
-        if (!this->_M_le(__l, __r))
-          __throw_regex_error(regex_constants::error_range);
-        _M_range_set.push_back(make_pair(__l, __r));
-      }
-
-      _FlagT                              _M_flags;
-      _TraitsT                            _M_traits;
-      bool                                _M_is_non_matching;
-      std::vector<_CharT>                 _M_char_set;
-      std::vector<pair<_CharT, _CharT>>   _M_range_set;
-      _CharClassT                         _M_class_set;
-    };
-
-  /// Identifies a state in the NFA.
-  typedef int _StateIdT;
-
-  /// The special case in which a state identifier is not an index.
-  static const _StateIdT _S_invalid_state_id  = -1;
-
-
-  /**
-   * @brief struct _State
-   *
-   * An individual state in an NFA
-   *
-   * In this case a "state" is an entry in the NFA definition coupled
-   * with its outgoing transition(s).  All states have a single outgoing
-   * transition, except for accepting states (which have no outgoing
-   * transitions) and alt states, which have two outgoing transitions.
-   */
-  struct _State
-  {
-    typedef int  _OpcodeT;
-
-    _OpcodeT     _M_opcode;    // type of outgoing transition
-    _StateIdT    _M_next;      // outgoing transition
-    _StateIdT    _M_alt;       // for _S_opcode_alternative
-    unsigned int _M_subexpr;   // for _S_opcode_subexpr_*
-    _Tagger      _M_tagger;    // for _S_opcode_subexpr_*
-    _Matcher     _M_matches;   // for _S_opcode_match
-
-    explicit _State(_OpcodeT __opcode)
-    : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
-    { }
-
-    _State(const _Matcher& __m)
-    : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id), _M_matches(__m)
-    { }
-
-    _State(_OpcodeT __opcode, unsigned int __s, const _Tagger& __t)
-    : _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__s),
-      _M_tagger(__t)
-    { }
-
-    _State(_StateIdT __next, _StateIdT __alt)
-    : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
-    { }
-
-#ifdef _GLIBCXX_DEBUG
-    std::ostream&
-    _M_print(std::ostream& ostr) const;
-
-    // Prints graphviz dot commands for state.
-    std::ostream&
-    _M_dot(std::ostream& __ostr, _StateIdT __id) const;
-#endif
-  };
-
-  
-  /// The Grep Matcher works on sets of states.  Here are sets of states.
-  typedef std::set<_StateIdT> _StateSet;
-
-  /**
-   * @brief struct _Nfa
-   *
-   * A collection of all states making up an NFA.
-   *
-   * An NFA is a 4-tuple M = (K, S, s, F), where
-   *    K is a finite set of states,
-   *    S is the alphabet of the NFA,
-   *    s is the initial state,
-   *    F is a set of final (accepting) states.
-   *
-   * This NFA class is templated on S, a type that will hold values of the
-   * underlying alphabet (without regard to semantics of that alphabet).  The
-   * other elements of the tuple are generated during construction of the NFA
-   * and are available through accessor member functions.
-   */
-  class _Nfa
-  : public _Automaton, public std::vector<_State>
-  {
-  public:
-    typedef _State                              _StateT;
-    typedef unsigned int                        _SizeT;
-    typedef regex_constants::syntax_option_type _FlagT;
-
-    _Nfa(_FlagT __f)
-    : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
-    // TODO: BFS by default. Your choice. Need to be set by the compiler.
-    _M_has_back_ref(false)
-    { }
-
-    ~_Nfa()
-    { }
-
-    _FlagT
-    _M_options() const
-    { return _M_flags; }
-
-    _StateIdT
-    _M_start() const
-    { return _M_start_state; }
-
-    const _StateSet&
-    _M_final_states() const
-    { return _M_accepting_states; }
-
-    _SizeT
-    _M_sub_count() const
-    { return _M_subexpr_count; }
-
-    _StateIdT
-    _M_insert_accept()
-    {
-      this->push_back(_StateT(_S_opcode_accept));
-      _M_accepting_states.insert(this->size()-1);
-      return this->size()-1;
-    }
-
-    _StateIdT
-    _M_insert_alt(_StateIdT __next, _StateIdT __alt)
-    {
-      this->push_back(_StateT(__next, __alt));
-      return this->size()-1;
-    }
-
-    _StateIdT
-    _M_insert_matcher(_Matcher __m)
-    {
-      this->push_back(_StateT(__m));
-      return this->size()-1;
-    }
-
-    _StateIdT
-    _M_insert_subexpr_begin(const _Tagger& __t)
-    {
-      this->push_back(_StateT(_S_opcode_subexpr_begin, _M_subexpr_count++,
-			      __t));
-      return this->size()-1;
-    }
-
-    _StateIdT 
-    _M_insert_subexpr_end(unsigned int __i, const _Tagger& __t)
-    {
-      this->push_back(_StateT(_S_opcode_subexpr_end, __i, __t));
-      return this->size()-1;
-    }
-
-    void
-    _M_set_back_ref(bool __b)
-    { _M_has_back_ref = __b; }
-
-    std::unique_ptr<_Grep_matcher>
-    _M_get_matcher(_PatternCursor&                   __p,
-                   _Results&                         __r,
-                   const _AutomatonPtr&              __automaton,
-                   regex_constants::match_flag_type  __flags);
-
-#ifdef _GLIBCXX_DEBUG
-    std::ostream&
-    _M_dot(std::ostream& __ostr) const;
-#endif
-
-  private:
-    _FlagT     _M_flags;
-    _StateIdT  _M_start_state;
-    _StateSet  _M_accepting_states;
-    _SizeT     _M_subexpr_count;
-    bool       _M_has_back_ref;
-  };
-
-  /// Describes a sequence of one or more %_State, its current start
-  /// and end(s).  This structure contains fragments of an NFA during
-  /// construction.
-  class _StateSeq
-  {
-  public:
-    // Constructs a single-node sequence
-    _StateSeq(_Nfa& __ss, _StateIdT __s, _StateIdT __e = _S_invalid_state_id)
-    : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
-    { }
-    // Constructs a split sequence from two other sequencces
-    _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
-    : _M_nfa(__e1._M_nfa),
-      _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
-      _M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
-    { }
-
-    // Constructs a split sequence from a single sequence
-    _StateSeq(const _StateSeq& __e, _StateIdT __id)
-    : _M_nfa(__e._M_nfa),
-      _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
-      _M_end1(__id), _M_end2(__e._M_end1)
-    { }
-
-    // Constructs a copy of a %_StateSeq
-    _StateSeq(const _StateSeq& __rhs)
-    : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
-      _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
-    { }
-
-
-    _StateSeq& operator=(const _StateSeq& __rhs);
-
-    _StateIdT
-    _M_front() const
-    { return _M_start; }
-
-    // Extends a sequence by one.
-    void
-    _M_push_back(_StateIdT __id);
-
-    // Extends and maybe joins a sequence.
-    void
-    _M_append(_StateIdT __id);
-
-    void
-    _M_append(_StateSeq& __rhs);
-
-    // Clones an entire sequence.
-    _StateIdT
-    _M_clone();
-
-  private:
-    _Nfa&     _M_nfa;
-    _StateIdT _M_start;
-    _StateIdT _M_end1;
-    _StateIdT _M_end2;
-
-  };
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace std
-
-#include <bits/regex_nfa.tcc>
-
Index: include/bits/regex_nfa.tcc
===================================================================
--- include/bits/regex_nfa.tcc	(revision 201492)
+++ include/bits/regex_nfa.tcc	(working copy)
@@ -1,232 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_nfa.tcc
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-#include <regex>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _InIterT, typename _TraitsT>
-    bool _BracketMatcher<_InIterT, _TraitsT>::
-    operator()(const _PatternCursor& __pc) const
-    {
-      typedef const _SpecializedCursor<_InIterT>& _CursorT;
-      _CursorT __c = static_cast<_CursorT>(__pc);
-      _CharT __ch = __c._M_current();
-      bool __ret = false;
-      for (auto __c : _M_char_set)
-        if (this->_M_equ(__c, __ch))
-          {
-            __ret = true;
-            break;
-          }
-      if (!__ret && _M_traits.isctype(__ch, _M_class_set))
-        __ret = true;
-      else
-        {
-          for (auto& __it : _M_range_set)
-            if (this->_M_le(__it.first, __ch) && this->_M_le(__ch, __it.second))
-              {
-                __ret = true;
-                break;
-              }
-        }
-      if (_M_is_non_matching)
-        __ret = !__ret;
-      return __ret;
-    }
-
-  template<typename _InIterT, typename _TraitsT>
-    bool _Comparator<_InIterT, _TraitsT>::
-    _M_equ(_CharT __a, _CharT __b) const
-    {
-      if (_M_flags & regex_constants::icase)
-        return _M_traits.translate_nocase(__a)
-          == _M_traits.translate_nocase(__b);
-      if (_M_flags & regex_constants::collate)
-        return _M_traits.translate(__a) == _M_traits.translate(__b);
-      return __a == __b;
-    }
-
-  template<typename _InIterT, typename _TraitsT>
-    bool _Comparator<_InIterT, _TraitsT>::
-    _M_le(_CharT __a, _CharT __b) const
-    {
-      _StringT __str1 = _StringT(1,
-                                 _M_flags & regex_constants::icase
-                                 ? _M_traits.translate_nocase(__a)
-                                 : _M_traits.translate(__a));
-      _StringT __str2 = _StringT(1,
-                                 _M_flags & regex_constants::icase
-                                 ? _M_traits.translate_nocase(__b)
-                                 : _M_traits.translate(__b));
-      return _M_traits.transform(__str1.begin(), __str1.end())
-        <= _M_traits.transform(__str2.begin(), __str2.end());
-    }
-
-#ifdef _GLIBCXX_DEBUG
-inline std::ostream& _State::
-_M_print(std::ostream& ostr) const
-{
-  switch (_M_opcode)
-  {
-    case _S_opcode_alternative:
-      ostr << "alt next=" << _M_next << " alt=" << _M_alt;
-      break;
-    case _S_opcode_subexpr_begin:
-      ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
-      break;
-    case _S_opcode_subexpr_end:
-      ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
-      break;
-    case _S_opcode_match:
-      ostr << "match next=" << _M_next;
-      break;
-    case _S_opcode_accept:
-      ostr << "accept next=" << _M_next;
-      break;
-    default:
-      ostr << "unknown next=" << _M_next;
-      break;
-  }
-  return ostr;
-}
-
-// Prints graphviz dot commands for state.
-inline std::ostream& _State::
-_M_dot(std::ostream& __ostr, _StateIdT __id) const
-{
-  switch (_M_opcode)
-  {
-    case _S_opcode_alternative:
-      __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" 
-             << __id << " -> " << _M_next
-             << " [label=\"epsilon\", tailport=\"s\"];\n"
-             << __id << " -> " << _M_alt 
-             << " [label=\"epsilon\", tailport=\"n\"];\n";
-      break;
-    case _S_opcode_subexpr_begin:
-      __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
-             << _M_subexpr << "\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
-      break;
-    case _S_opcode_subexpr_end:
-      __ostr << __id << " [label=\"" << __id << "\\nSEND "
-             << _M_subexpr << "\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
-      break;
-    case _S_opcode_match:
-      __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
-      break;
-    case _S_opcode_accept:
-      __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
-      break;
-    default:
-      __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"?\"];\n";
-      break;
-  }
-  return __ostr;
-}
-
-inline std::ostream& _Nfa::
-_M_dot(std::ostream& __ostr) const
-{
-  __ostr << "digraph _Nfa {\n"
-   << "  rankdir=LR;\n";
-  for (unsigned int __i = 0; __i < this->size(); ++__i)
-  { this->at(__i)._M_dot(__ostr, __i); }
-  __ostr << "}\n";
-  return __ostr;
-}
-#endif
-
-inline _StateSeq& _StateSeq::
-operator=(const _StateSeq& __rhs)
-{
-  _M_start = __rhs._M_start;
-  _M_end1  = __rhs._M_end1;
-  _M_end2  = __rhs._M_end2;
-  return *this;
-}
-
-inline void _StateSeq::
-_M_push_back(_StateIdT __id)
-{
-  if (_M_end1 != _S_invalid_state_id)
-    _M_nfa[_M_end1]._M_next = __id;
-  _M_end1 = __id;
-}
-
-inline void _StateSeq::
-_M_append(_StateIdT __id)
-{
-  if (_M_end2 != _S_invalid_state_id)
-  {
-    if (_M_end2 == _M_end1)
-      _M_nfa[_M_end2]._M_alt = __id;
-    else
-      _M_nfa[_M_end2]._M_next = __id;
-    _M_end2 = _S_invalid_state_id;
-  }
-  if (_M_end1 != _S_invalid_state_id)
-    _M_nfa[_M_end1]._M_next = __id;
-  _M_end1 = __id;
-}
-
-inline void _StateSeq::
-_M_append(_StateSeq& __rhs)
-{
-  if (_M_end2 != _S_invalid_state_id)
-  {
-    if (_M_end2 == _M_end1)
-      _M_nfa[_M_end2]._M_alt = __rhs._M_start;
-    else
-      _M_nfa[_M_end2]._M_next = __rhs._M_start;
-    _M_end2 = _S_invalid_state_id;
-  }
-  if (__rhs._M_end2 != _S_invalid_state_id)
-    _M_end2 = __rhs._M_end2;
-  if (_M_end1 != _S_invalid_state_id)
-    _M_nfa[_M_end1]._M_next = __rhs._M_start;
-  _M_end1 = __rhs._M_end1;
-}
-
-// @todo implement this function.
-inline _StateIdT _StateSeq::
-_M_clone()
-{ return 0; }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
Index: include/std/regex
===================================================================
--- include/std/regex	(revision 201492)
+++ include/std/regex	(working copy)
@@ -54,13 +54,11 @@
 #include <utility>
 #include <vector>
 
-#include <bits/range_access.h>
 #include <bits/regex_constants.h>
 #include <bits/regex_error.h>
-#include <bits/regex_cursor.h>
-#include <bits/regex_nfa.h>
+#include <bits/regex_automaton.h>
 #include <bits/regex_compiler.h>
-#include <bits/regex_grep_matcher.h>
+#include <bits/regex_executor.h>
 #include <bits/regex.h>
 
 #endif // C++11
Index: testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc
===================================================================
--- testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc	(revision 201492)
+++ testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc	(working copy)
@@ -38,12 +38,10 @@
              regex_constants::match_flag_type         __flags
                             = regex_constants::match_default)
   {
-    __detail::_AutomatonPtr __a = __re._M_get_automaton();
-    __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
-    __detail::_SpecializedCursor<_Bi_iter> __cs(__s, __e);
-    __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
-    VERIFY( dynamic_cast<__detail::_DFSMatcher *>(
-              &*__a->_M_get_matcher(__cs, __r, __a, __flags)) != nullptr );
+    VERIFY( (dynamic_cast
+             <__detail::_DFSExecutor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits>*>
+             (&*__detail::__get_executor(__s, __e, __m, __re, __flags))
+             != nullptr) );
   }
 
 void

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
       [not found] ` <52001184.5020707@oracle.com>
@ 2013-08-06  1:21   ` Tim Shen
       [not found]     ` <87txj35v5n.fsf@fencepost.gnu.org>
  0 siblings, 1 reply; 22+ messages in thread
From: Tim Shen @ 2013-08-06  1:21 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

On Tue, Aug 6, 2013 at 4:56 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:

> Why? Isn't a new file, thus 2010-2013 seems just fine.

It's an accident, sorry.

> +
> +  // TODO implement it.
> +  template<typename _BiIter>
> +    void
> +    _Scanner<_BiIter>::
> +    _M_eat_escape()
>
> The comment is quite mysterious! A lot of code is already there, and first
> blush isn't clear at all what is missing and what already works.

Um, What I mean is, it does some things but the support to escaping is
not complete;
I changed the comment to "TODO complete it."


-- 
Tim Shen

[-- Attachment #2: regex.patch --]
[-- Type: application/octet-stream, Size: 156740 bytes --]

Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 201491)
+++ include/Makefile.am	(working copy)
@@ -126,14 +126,14 @@
 	${bits_srcdir}/random.tcc \
 	${bits_srcdir}/range_access.h \
 	${bits_srcdir}/regex.h \
-	${bits_srcdir}/regex_compiler.h \
 	${bits_srcdir}/regex_constants.h \
-	${bits_srcdir}/regex_cursor.h \
 	${bits_srcdir}/regex_error.h \
-	${bits_srcdir}/regex_grep_matcher.h \
-	${bits_srcdir}/regex_grep_matcher.tcc \
-	${bits_srcdir}/regex_nfa.h \
-	${bits_srcdir}/regex_nfa.tcc \
+	${bits_srcdir}/regex_automaton.h \
+	${bits_srcdir}/regex_automaton.tcc \
+	${bits_srcdir}/regex_compiler.h \
+	${bits_srcdir}/regex_compiler.tcc \
+	${bits_srcdir}/regex_executor.h \
+	${bits_srcdir}/regex_executor.tcc \
 	${bits_srcdir}/stream_iterator.h \
 	${bits_srcdir}/streambuf_iterator.h \
 	${bits_srcdir}/shared_ptr.h \
Index: include/Makefile.in
===================================================================
--- include/Makefile.in	(revision 201491)
+++ include/Makefile.in	(working copy)
@@ -388,14 +388,14 @@
 	${bits_srcdir}/random.tcc \
 	${bits_srcdir}/range_access.h \
 	${bits_srcdir}/regex.h \
-	${bits_srcdir}/regex_compiler.h \
 	${bits_srcdir}/regex_constants.h \
-	${bits_srcdir}/regex_cursor.h \
 	${bits_srcdir}/regex_error.h \
-	${bits_srcdir}/regex_grep_matcher.h \
-	${bits_srcdir}/regex_grep_matcher.tcc \
-	${bits_srcdir}/regex_nfa.h \
-	${bits_srcdir}/regex_nfa.tcc \
+	${bits_srcdir}/regex_automaton.h \
+	${bits_srcdir}/regex_automaton.tcc \
+	${bits_srcdir}/regex_compiler.h \
+	${bits_srcdir}/regex_compiler.tcc \
+	${bits_srcdir}/regex_executor.h \
+	${bits_srcdir}/regex_executor.tcc \
 	${bits_srcdir}/stream_iterator.h \
 	${bits_srcdir}/streambuf_iterator.h \
 	${bits_srcdir}/shared_ptr.h \
Index: include/bits/regex.h
===================================================================
--- include/bits/regex.h	(revision 201491)
+++ include/bits/regex.h	(working copy)
@@ -40,7 +40,7 @@
   /**
    * @brief Class regex_traits. Describes aspects of a regular expression.
    *
-   * A regular expression traits class that satisfies the requirements of 
+   * A regular expression traits class that satisfies the requirements of
    * section [28.7].
    *
    * The class %regex is parameterized around a set of related types and
@@ -61,7 +61,8 @@
           _BaseType _M_base;
           unsigned char _M_extended;
           static constexpr unsigned char _S_under = 1 << 0;
-          // FIXME: _S_blank should be removed in the future, when locale's complete.
+          // FIXME: _S_blank should be removed in the future,
+          // when locale's complete.
           static constexpr unsigned char _S_blank = 1 << 1;
           static constexpr unsigned char _S_valid_mask = 0x3;
 
@@ -128,7 +129,7 @@
        * @brief Constructs a default traits object.
        */
       regex_traits() { }
-      
+
       /**
        * @brief Gives the length of a C-style string starting at @p __p.
        *
@@ -153,7 +154,7 @@
       char_type
       translate(char_type __c) const
       { return __c; }
-      
+
       /**
        * @brief Translates a character into a case-insensitive equivalent.
        *
@@ -165,12 +166,12 @@
        */
       char_type
       translate_nocase(char_type __c) const
-      { 
+      {
 	typedef std::ctype<char_type> __ctype_type;
 	const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-	return __fctyp.tolower(__c); 
+	return __fctyp.tolower(__c);
       }
-      
+
       /**
        * @brief Gets a sort key for a character sequence.
        *
@@ -209,7 +210,7 @@
        *
        * 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) 
+       * 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.
        *
@@ -239,7 +240,7 @@
        *
        * @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
@@ -312,13 +313,13 @@
        * @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.
        *
@@ -336,7 +337,7 @@
 	std::swap(_M_locale, __loc);
 	return __loc;
       }
-      
+
       /**
        * @brief Gets a copy of the current locale in use by the regex_traits
        * object.
@@ -344,7 +345,7 @@
       locale_type
       getloc() const
       { return _M_locale; }
-      
+
     protected:
       locale_type _M_locale;
     };
@@ -579,7 +580,8 @@
           if (__s == __it->first)
             {
               if (__icase
-                  && ((__it->second & (ctype_base::lower | ctype_base::upper)) != 0))
+                  && ((__it->second
+                       & (ctype_base::lower | ctype_base::upper)) != 0))
                 return ctype_base::alpha;
               return __it->second;
             }
@@ -594,7 +596,7 @@
     {
       typedef std::ctype<char_type> __ctype_type;
       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-      
+
       return __fctyp.is(__f._M_base, __c)
         // [[:w:]]
         || ((__f._M_extended & _RegexMask::_S_under)
@@ -662,9 +664,7 @@
        * character sequence.
        */
       basic_regex()
-      : _M_flags(ECMAScript),
-        _M_automaton(__detail::__compile<const _Ch_type*, _Rx_traits>(0, 0,
-                     _M_traits, _M_flags))
+      : _M_flags(ECMAScript), _M_automaton(nullptr)
       { }
 
       /**
@@ -680,9 +680,7 @@
        */
       explicit
       basic_regex(const _Ch_type* __p, flag_type __f = ECMAScript)
-      : _M_flags(__f),
-        _M_automaton(__detail::__compile(__p, __p + _Rx_traits::length(__p),
-        				_M_traits, _M_flags))
+      : basic_regex(__p, __p + _Rx_traits::length(__p), __f)
       { }
 
       /**
@@ -697,9 +695,9 @@
        *
        * @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_automaton(__detail::__compile(__p, __p + __len, _M_traits, _M_flags))
+      basic_regex(const _Ch_type* __p,
+                  std::size_t __len, flag_type __f = ECMAScript)
+      : basic_regex(__p, __p + __len, __f)
       { }
 
       /**
@@ -707,10 +705,7 @@
        *
        * @param __rhs A @p regex object.
        */
-      basic_regex(const basic_regex& __rhs)
-      : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
-        _M_automaton(__rhs._M_automaton)
-      { }
+      basic_regex(const basic_regex& __rhs) = default;
 
       /**
        * @brief Move-constructs a basic regular expression.
@@ -733,12 +728,10 @@
        */
       template<typename _Ch_traits, typename _Ch_alloc>
         explicit
-        basic_regex(const std::basic_string<_Ch_type, _Ch_traits, 
+        basic_regex(const std::basic_string<_Ch_type, _Ch_traits,
 					    _Ch_alloc>& __s,
 		    flag_type __f = ECMAScript)
-	: _M_flags(__f),
-	  _M_automaton(__detail::__compile(__s.begin(), __s.end(),
-	  				  _M_traits, _M_flags))
+	: basic_regex(__s.begin(), __s.end(), __f)
         { }
 
       /**
@@ -755,10 +748,11 @@
        *         expression.
        */
       template<typename _InputIterator>
-        basic_regex(_InputIterator __first, _InputIterator __last, 
+        basic_regex(_InputIterator __first, _InputIterator __last,
 		    flag_type __f = ECMAScript)
 	: _M_flags(__f),
-	  _M_automaton(__detail::__compile(__first, __last, _M_traits, _M_flags))
+          _M_automaton(__detail::_Compiler<_InputIterator, _Ch_type, _Rx_traits>
+                       (__first, __last, _M_traits, _M_flags)._M_get_nfa())
         { }
 
       /**
@@ -771,9 +765,7 @@
        */
       basic_regex(initializer_list<_Ch_type> __l,
 		  flag_type __f = ECMAScript)
-      : _M_flags(__f),
-        _M_automaton(__detail::__compile(__l.begin(), __l.end(),
-        				_M_traits, _M_flags))
+      : basic_regex(__l.begin(), __l.end(), __f)
       { }
 
       /**
@@ -781,7 +773,7 @@
        */
       ~basic_regex()
       { }
-      
+
       /**
        * @brief Assigns one regular expression to another.
        */
@@ -806,7 +798,7 @@
       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.
@@ -831,7 +823,7 @@
 	this->swap(__tmp);
 	return *this;
       }
-      
+
       /**
        * @brief The move-assignment operator.
        *
@@ -880,7 +872,7 @@
       { return this->assign(string_type(__p, __len), __flags); }
 
       /**
-       * @brief Assigns a new regular expression to a regex object from a 
+       * @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.
@@ -894,7 +886,7 @@
         basic_regex&
         assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
 	       flag_type __flags = ECMAScript)
-        { 
+        {
 	  basic_regex __tmp(__s, __flags);
 	  this->swap(__tmp);
 	  return *this;
@@ -942,7 +934,7 @@
       unsigned int
       mark_count() const
       { return _M_automaton->_M_sub_count() - 1; }
-      
+
       /**
        * @brief Gets the flags used to construct the regular expression
        * or in the last call to assign().
@@ -950,7 +942,7 @@
       flag_type
       flags() const
       { return _M_flags; }
-      
+
       // [7.8.5] locale
       /**
        * @brief Imbues the regular expression object with the given locale.
@@ -960,7 +952,7 @@
       locale_type
       imbue(locale_type __loc)
       { return _M_traits.imbue(__loc); }
-      
+
       /**
        * @brief Gets the locale currently imbued in the regular expression
        *        object.
@@ -968,7 +960,7 @@
       locale_type
       getloc() const
       { return _M_traits.getloc(); }
-      
+
       // [7.8.6] swap
       /**
        * @brief Swaps the contents of two regular expression objects.
@@ -988,17 +980,40 @@
       _M_dot(std::ostream& __ostr)
       { _M_automaton->_M_dot(__ostr); }
 #endif
-      
-      const __detail::_AutomatonPtr&
-      _M_get_automaton() const
-      { return _M_automaton; }
 
     protected:
-      flag_type              _M_flags;
-      _Rx_traits             _M_traits;
-      __detail::_AutomatonPtr _M_automaton;
+      typedef std::shared_ptr<__detail::_Automaton<_Ch_type, _Rx_traits>>
+        _AutomatonPtr;
+
+      template<typename _BiIter, typename _Alloc,
+        typename _CharT, typename _TraitsT>
+        friend std::unique_ptr<
+          __detail::_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+        __detail::__get_executor(_BiIter,
+                                 _BiIter,
+                                 match_results<_BiIter, _Alloc>&,
+                                 const basic_regex<_CharT, _TraitsT>&,
+                                 regex_constants::match_flag_type);
+
+      template<typename _B, typename _A, typename _C, typename _R>
+        friend bool
+        regex_match(_B, _B,
+                    match_results<_B, _A>&,
+                    const basic_regex<_C, _R>&,
+                    regex_constants::match_flag_type);
+
+      template<typename _B, typename _A, typename _C, typename _R>
+        friend bool
+        regex_search(_B, _B,
+                     match_results<_B, _A>&,
+                     const basic_regex<_C, _R>&,
+                     regex_constants::match_flag_type);
+
+      flag_type     _M_flags;
+      _Rx_traits    _M_traits;
+      _AutomatonPtr _M_automaton;
     };
-  
+
   /** @brief Standard regular expressions. */
   typedef basic_regex<char>    regex;
 
@@ -1046,7 +1061,7 @@
       typedef std::basic_string<value_type>             string_type;
 
       bool matched;
-      
+
       constexpr sub_match() : matched() { }
 
       /**
@@ -1072,7 +1087,7 @@
 	  ? string_type(this->first, this->second)
 	  : string_type();
       }
-      
+
       /**
        * @brief Gets the matching sequence as a string.
        *
@@ -1085,7 +1100,7 @@
 	  ? string_type(this->first, this->second)
 	  : string_type();
       }
-      
+
       /**
        * @brief Compares this and another matched sequence.
        *
@@ -1111,7 +1126,7 @@
       int
       compare(const string_type& __s) const
       { return this->str().compare(__s); }
-      
+
       /**
        * @brief Compares this sub_match to a C-style string.
        *
@@ -1125,8 +1140,8 @@
       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;
 
@@ -1142,7 +1157,7 @@
 #endif
 
   // [7.9.2] sub_match non-member operators
-  
+
   /**
    * @brief Tests the equivalence of two regular expression submatches.
    * @param __lhs First regular expression submatch.
@@ -1760,7 +1775,7 @@
 
       typedef std::basic_string<char_type>                 string_type;
       //@}
-  
+
     public:
       /**
        * @name 28.10.1 Construction, Copying, and Destruction
@@ -1815,7 +1830,7 @@
        */
       ~match_results()
       { }
-      
+
       //@}
 
       // 28.10.2, state:
@@ -1846,7 +1861,7 @@
       	size_type __size = _Base_type::size();
       	return (__size && _Base_type::operator[](0).matched) ? __size - 2 : 0;
       }
-      
+
       size_type
       max_size() const
       { return _Base_type::max_size(); }
@@ -1859,7 +1874,7 @@
       bool
       empty() const
       { return size() == 0; }
-      
+
       //@}
 
       /**
@@ -1911,7 +1926,7 @@
       string_type
       str(size_type __sub = 0) const
       { return (*this)[__sub].str(); }
-      
+
       /**
        * @brief Gets a %sub_match reference for the match or submatch.
        * @param __sub indicates the submatch.
@@ -1925,7 +1940,7 @@
        */
       const_reference
       operator[](size_type __sub) const
-      { 
+      {
       	_GLIBCXX_DEBUG_ASSERT( ready() );
       	return __sub < size()
 	       ?  _Base_type::operator[](__sub)
@@ -1972,7 +1987,7 @@
       const_iterator
       begin() const
       { return _Base_type::begin(); }
-      
+
       /**
        * @brief Gets an iterator to the start of the %sub_match collection.
        */
@@ -1986,7 +2001,7 @@
       const_iterator
       end() const
       { return !empty() ? _Base_type::end() - 2 : _Base_type::end(); }
-      
+
       /**
        * @brief Gets an iterator to one-past-the-end of the collection.
        */
@@ -2047,21 +2062,22 @@
        */
       string_type
       format(const char_type* __fmt,
-	     match_flag_type __flags = regex_constants::format_default) const
+             match_flag_type __flags = regex_constants::format_default) const
       {
         string_type __result;
         format(std::back_inserter(__result),
+               __fmt,
                __fmt + char_traits<char_type>::length(__fmt),
                __flags);
         return __result;
       }
 
-      //@} 
+      //@}
 
       /**
        * @name 10.5 Allocator
        */
-      //@{ 
+      //@{
 
       /**
        * @brief Gets a copy of the allocator.
@@ -2069,13 +2085,13 @@
       allocator_type
       get_allocator() const
       { return _Base_type::get_allocator(); }
-      
-      //@} 
 
+      //@}
+
       /**
        * @name 10.6 Swap
        */
-       //@{ 
+       //@{
 
       /**
        * @brief Swaps the contents of two match_results.
@@ -2083,12 +2099,33 @@
       void
       swap(match_results& __that)
       { _Base_type::swap(__that); }
-      //@} 
-      
+      //@}
+
     private:
-      friend class __detail::_SpecializedResults<_Bi_iter, _Alloc>;
+      template<typename, typename, typename, typename>
+        friend class __detail::_Executor;
+
+      template<typename, typename, typename, typename>
+        friend class __detail::_DFSExecutor;
+
+      template<typename, typename, typename, typename>
+        friend class __detail::_BFSExecutor;
+
+      template<typename _B, typename _A, typename _Ch_type, typename _Rx_traits>
+        friend bool
+        regex_match(_B, _B, match_results<_B, _A>&,
+                    const basic_regex<_Ch_type,
+                    _Rx_traits>&,
+                    regex_constants::match_flag_type);
+
+      template<typename _B, typename _A, typename _Ch_type, typename _Rx_traits>
+        friend bool
+        regex_search(_B, _B, match_results<_B, _A>&,
+                     const basic_regex<_Ch_type,
+                     _Rx_traits>&,
+                     regex_constants::match_flag_type);
     };
-  
+
   typedef match_results<const char*>             cmatch;
   typedef match_results<string::const_iterator>  smatch;
 #ifdef _GLIBCXX_USE_WCHAR_T
@@ -2179,11 +2216,22 @@
                 regex_constants::match_flag_type         __flags
                                = regex_constants::match_default)
     {
-      __detail::_AutomatonPtr __a = __re._M_get_automaton();
-      __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
-      __detail::_SpecializedCursor<_Bi_iter> __cs(__s, __e);
-      __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
-      return __a->_M_get_matcher(__cs, __r, __a, __flags)->_M_match();
+      if (__re._M_automaton == nullptr)
+        return false;
+      if (__detail::__get_executor(__s, __e, __m, __re, __flags)->_M_match())
+        {
+          for (auto __it : __m)
+            if (!__it.matched)
+              __it.first = __it.second = __e;
+          __m.at(__m.size()).matched = false;
+          __m.at(__m.size()).first = __s;
+          __m.at(__m.size()).second = __s;
+          __m.at(__m.size()+1).matched = false;
+          __m.at(__m.size()+1).first = __e;
+          __m.at(__m.size()+1).second = __e;
+          return true;
+        }
+      return false;
     }
 
   /**
@@ -2206,7 +2254,7 @@
 		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);
     }
@@ -2252,7 +2300,7 @@
 	   typename _Alloc, 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, 
+		match_results<typename basic_string<_Ch_type,
 		_Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m,
 		const basic_regex<_Ch_type, _Rx_traits>& __re,
 		regex_constants::match_flag_type __flags
@@ -2327,29 +2375,25 @@
                  regex_constants::match_flag_type __flags
                  = regex_constants::match_default)
     {
-      __detail::_AutomatonPtr __a = __re._M_get_automaton();
-      __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
-      __detail::_SpecializedCursor<_Bi_iter> __cs(__first, __last);
-      __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
+      if (__re._M_automaton == nullptr)
+        return false;
       for (auto __cur = __first; __cur != __last; ++__cur) // Any KMP-like algo?
-        {
-          __detail::_SpecializedCursor<_Bi_iter> __curs(__cur, __last);
-          auto __matcher = __a->_M_get_matcher(__curs, __r, __a, __flags);
-          if (__matcher->_M_search_from_first())
-            {
-              __r._M_set_range(__m.size(),
-                               __detail::_SpecializedCursor<_Bi_iter>
-                                 {__first, __m[0].first});
-              __r._M_set_range(__m.size()+1,
-                               __detail::_SpecializedCursor<_Bi_iter>
-                                 {__m[0].second, __last});
-              __r._M_set_matched(__m.size(),
-                                 __m.prefix().first != __m.prefix().second);
-              __r._M_set_matched(__m.size()+1,
-                                 __m.suffix().first != __m.suffix().second);
-              return true;
-            }
-        }
+        if (__detail::__get_executor(__cur, __last, __m, __re, __flags)
+              ->_M_search_from_first())
+          {
+            for (auto __it : __m)
+              if (!__it.matched)
+                __it.first = __it.second = __last;
+            __m.at(__m.size()).first = __first;
+            __m.at(__m.size()).second = __m[0].first;
+            __m.at(__m.size()+1).first = __m[0].second;
+            __m.at(__m.size()+1).second = __last;
+            __m.at(__m.size()).matched =
+              (__m.prefix().first != __m.prefix().second);
+            __m.at(__m.size()+1).matched =
+              (__m.suffix().first != __m.suffix().second);
+            return true;
+          }
       return false;
     }
 
@@ -2513,7 +2557,7 @@
 
   // std [28.12] Class template regex_iterator
   /**
-   * An iterator adaptor that will provide repeated calls of regex_search over 
+   * An iterator adaptor that will provide repeated calls of regex_search over
    * a range until no more matches remain.
    */
   template<typename _Bi_iter,
@@ -2536,7 +2580,7 @@
       regex_iterator()
       : _M_match()
       { }
-      
+
       /**
        * Constructs a %regex_iterator...
        * @param __a  [IN] The start of a text range to search.
@@ -2554,19 +2598,19 @@
        * Copy constructs a %regex_iterator.
        */
       regex_iterator(const regex_iterator& __rhs) = default;
-      
+
       /**
        * @brief Assigns one %regex_iterator to another.
        */
       regex_iterator&
       operator=(const regex_iterator& __rhs) = default;
-      
+
       /**
        * @brief Tests the equivalence of two regex iterators.
        */
       bool
       operator==(const regex_iterator& __rhs) const;
-      
+
       /**
        * @brief Tests the inequivalence of two regex iterators.
        */
@@ -2573,7 +2617,7 @@
       bool
       operator!=(const regex_iterator& __rhs) const
       { return !(*this == __rhs); }
-      
+
       /**
        * @brief Dereferences a %regex_iterator.
        */
@@ -2580,7 +2624,7 @@
       const value_type&
       operator*() const
       { return _M_match; }
-      
+
       /**
        * @brief Selects a %regex_iterator member.
        */
@@ -2587,13 +2631,13 @@
       const value_type*
       operator->() const
       { return &_M_match; }
-      
+
       /**
        * @brief Increments a %regex_iterator.
        */
       regex_iterator&
       operator++();
-      
+
       /**
        * @brief Postincrements a %regex_iterator.
        */
@@ -2604,7 +2648,7 @@
         ++(*this);
         return __tmp;
       }
-      
+
     private:
       _Bi_iter                         _M_begin;
       _Bi_iter                         _M_end;
@@ -2665,7 +2709,7 @@
         }
       return *this;
     }
-  
+
   typedef regex_iterator<const char*>             cregex_iterator;
   typedef regex_iterator<string::const_iterator>  sregex_iterator;
 #ifdef _GLIBCXX_USE_WCHAR_T
@@ -2693,11 +2737,11 @@
       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.
-       * 
+       *
        * 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.
@@ -2705,7 +2749,7 @@
       regex_token_iterator()
       : _M_position(), _M_result(nullptr), _M_suffix(), _M_n(0), _M_subs()
       { }
-      
+
       /**
        * Constructs a %regex_token_iterator...
        * @param __a          [IN] The start of the text to search.
@@ -2987,7 +3031,7 @@
   /** @brief Token iterator for standard wide-character strings. */
   typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #endif
-  
+
   //@} // group regex
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
Index: include/bits/regex_automaton.h
===================================================================
--- include/bits/regex_automaton.h	(revision 0)
+++ include/bits/regex_automaton.h	(working copy)
@@ -0,0 +1,274 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_automaton.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @defgroup regex-detail Base and Implementation Classes
+   *  @ingroup regex
+   *  @{
+   */
+
+  typedef int _StateIdT;
+  typedef std::set<_StateIdT> _StateSet;
+  static const _StateIdT _S_invalid_state_id  = -1;
+
+  template<typename _CharT>
+    using _Matcher = std::function<bool (_CharT)>;
+
+  /// Operation codes that define the type of transitions within the base NFA
+  /// that represents the regular expression.
+  enum _Opcode
+  {
+      _S_opcode_unknown       =   0,
+      _S_opcode_alternative   =   1,
+      _S_opcode_subexpr_begin =   4,
+      _S_opcode_subexpr_end   =   5,
+      _S_opcode_match         = 100,
+      _S_opcode_accept        = 255
+  };
+
+  template<typename _CharT, typename _TraitsT>
+    class _State
+    {
+    public:
+      typedef int                        _OpcodeT;
+      typedef _Matcher<_CharT>           _MatcherT;
+
+      _OpcodeT     _M_opcode;    // type of outgoing transition
+      _StateIdT    _M_next;      // outgoing transition
+      _StateIdT    _M_alt;       // for _S_opcode_alternative
+      unsigned int _M_subexpr;   // for _S_opcode_subexpr_*
+      _MatcherT    _M_matches;   // for _S_opcode_match
+
+      explicit _State(_OpcodeT __opcode)
+      : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
+      { }
+
+      _State(const _MatcherT& __m)
+      : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id),
+        _M_matches(__m)
+      { }
+
+      _State(_OpcodeT __opcode, unsigned __index)
+      : _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__index)
+      { }
+
+      _State(_StateIdT __next, _StateIdT __alt)
+      : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
+      { }
+
+#ifdef _GLIBCXX_DEBUG
+      std::ostream&
+      _M_print(std::ostream& ostr) const;
+
+      // Prints graphviz dot commands for state.
+      std::ostream&
+      _M_dot(std::ostream& __ostr, _StateIdT __id) const;
+#endif
+    };
+
+  /// Base class for, um, automata.  Could be an NFA or a DFA.  Your choice.
+  template<typename _CharT, typename _TraitsT>
+    class _Automaton
+    {
+    public:
+      typedef unsigned int _SizeT;
+
+    public:
+      virtual _SizeT
+      _M_sub_count() const = 0;
+
+#ifdef _GLIBCXX_DEBUG
+      virtual std::ostream&
+      _M_dot(std::ostream& __ostr) const = 0;
+#endif
+    };
+
+  template<typename _CharT, typename _TraitsT>
+    class _NFA
+    : public _Automaton<_CharT, _TraitsT>,
+      public std::vector<_State<_CharT, _TraitsT>>
+    {
+    public:
+      typedef _State<_CharT, _TraitsT>            _StateT;
+      typedef const _Matcher<_CharT>&             _MatcherT;
+      typedef unsigned int                        _SizeT;
+      typedef regex_constants::syntax_option_type _FlagT;
+
+      _NFA(_FlagT __f)
+      : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
+      _M_has_backref(false)
+      { }
+
+      _FlagT
+      _M_options() const
+      { return _M_flags; }
+
+      _StateIdT
+      _M_start() const
+      { return _M_start_state; }
+
+      const _StateSet&
+      _M_final_states() const
+      { return _M_accepting_states; }
+
+      _SizeT
+      _M_sub_count() const
+      { return _M_subexpr_count; }
+
+      _StateIdT
+      _M_insert_accept()
+      {
+        this->push_back(_StateT(_S_opcode_accept));
+        _M_accepting_states.insert(this->size()-1);
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_alt(_StateIdT __next, _StateIdT __alt)
+      {
+        this->push_back(_StateT(__next, __alt));
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_matcher(_MatcherT __m)
+      {
+        this->push_back(_StateT(__m));
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_subexpr_begin()
+      {
+        auto __id = _M_subexpr_count++;
+        _M_paren_stack.push(__id);
+        this->push_back(_StateT(_S_opcode_subexpr_begin, __id));
+        return this->size()-1;
+      }
+
+      _StateIdT
+      _M_insert_subexpr_end()
+      {
+        this->push_back(_StateT(_S_opcode_subexpr_end, _M_paren_stack.top()));
+        _M_paren_stack.pop();
+        return this->size()-1;
+      }
+
+      void
+      _M_set_backref(bool __b)
+      { _M_has_backref = __b; }
+
+#ifdef _GLIBCXX_DEBUG
+      std::ostream&
+      _M_dot(std::ostream& __ostr) const;
+#endif
+
+      _FlagT                   _M_flags;
+      _StateIdT                _M_start_state;
+      _StateSet                _M_accepting_states;
+      _SizeT                   _M_subexpr_count;
+      bool                     _M_has_backref;
+      std::stack<unsigned int> _M_paren_stack;
+    };
+
+  /// Describes a sequence of one or more %_State, its current start
+  /// and end(s).  This structure contains fragments of an NFA during
+  /// construction.
+  template<typename _CharT, typename _TraitsT>
+    class _StateSeq
+    {
+    public:
+      typedef _NFA<_CharT, _TraitsT> _RegexT;
+    public:
+      // Constructs a single-node sequence
+      _StateSeq(_RegexT& __ss, _StateIdT __s,
+                _StateIdT __e = _S_invalid_state_id)
+      : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
+      { }
+      // Constructs a split sequence from two other sequencces
+      _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
+      : _M_nfa(__e1._M_nfa),
+        _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
+        _M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
+      { }
+
+      // Constructs a split sequence from a single sequence
+      _StateSeq(const _StateSeq& __e, _StateIdT __id)
+      : _M_nfa(__e._M_nfa),
+        _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
+        _M_end1(__id), _M_end2(__e._M_end1)
+      { }
+
+      // Constructs a copy of a %_StateSeq
+      _StateSeq(const _StateSeq& __rhs)
+      : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
+        _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
+      { }
+
+      _StateSeq& operator=(const _StateSeq& __rhs);
+
+      _StateIdT
+      _M_front() const
+      { return _M_start; }
+
+      // Extends a sequence by one.
+      void
+      _M_push_back(_StateIdT __id);
+
+      // Extends and maybe joins a sequence.
+      void
+      _M_append(_StateIdT __id);
+
+      void
+      _M_append(_StateSeq& __rhs);
+
+      // Clones an entire sequence.
+      _StateIdT
+      _M_clone();
+
+    private:
+      _RegexT&  _M_nfa;
+      _StateIdT _M_start;
+      _StateIdT _M_end1;
+      _StateIdT _M_end2;
+    };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_automaton.tcc>
Index: include/bits/regex_automaton.tcc
===================================================================
--- include/bits/regex_automaton.tcc	(revision 0)
+++ include/bits/regex_automaton.tcc	(working copy)
@@ -0,0 +1,181 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_automaton.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#ifdef _GLIBCXX_DEBUG
+  template<typename _CharT, typename _TraitsT>
+    std::ostream& _State<_CharT, _TraitsT>::
+    _M_print(std::ostream& ostr) const
+    {
+      switch (_M_opcode)
+      {
+        case _S_opcode_alternative:
+          ostr << "alt next=" << _M_next << " alt=" << _M_alt;
+          break;
+        case _S_opcode_subexpr_begin:
+          ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
+          break;
+        case _S_opcode_subexpr_end:
+          ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
+          break;
+        case _S_opcode_match:
+          ostr << "match next=" << _M_next;
+          break;
+        case _S_opcode_accept:
+          ostr << "accept next=" << _M_next;
+          break;
+        default:
+          ostr << "unknown next=" << _M_next;
+          break;
+      }
+      return ostr;
+    }
+
+  // Prints graphviz dot commands for state.
+  template<typename _CharT, typename _TraitsT>
+    std::ostream& _State<_CharT, _TraitsT>::
+    _M_dot(std::ostream& __ostr, _StateIdT __id) const
+    {
+      switch (_M_opcode)
+      {
+        case _S_opcode_alternative:
+          __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n"
+                 << __id << " -> " << _M_next
+                 << " [label=\"epsilon\", tailport=\"s\"];\n"
+                 << __id << " -> " << _M_alt
+                 << " [label=\"epsilon\", tailport=\"n\"];\n";
+          break;
+        case _S_opcode_subexpr_begin:
+          __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
+                 << _M_subexpr << "\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
+          break;
+        case _S_opcode_subexpr_end:
+          __ostr << __id << " [label=\"" << __id << "\\nSEND "
+                 << _M_subexpr << "\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
+          break;
+        case _S_opcode_match:
+          __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
+          break;
+        case _S_opcode_accept:
+          __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
+          break;
+        default:
+          __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n"
+                 << __id << " -> " << _M_next << " [label=\"?\"];\n";
+          break;
+      }
+      return __ostr;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    std::ostream& _NFA<_CharT, _TraitsT>::
+    _M_dot(std::ostream& __ostr) const
+    {
+      __ostr << "digraph _Nfa {\n"
+       << "  rankdir=LR;\n";
+      for (unsigned int __i = 0; __i < this->size(); ++__i)
+      { this->at(__i)._M_dot(__ostr, __i); }
+      __ostr << "}\n";
+      return __ostr;
+    }
+#endif
+
+  template<typename _CharT, typename _TraitsT>
+    _StateSeq<_CharT, _TraitsT>& _StateSeq<_CharT, _TraitsT>::
+    operator=(const _StateSeq& __rhs)
+    {
+      _M_start = __rhs._M_start;
+      _M_end1  = __rhs._M_end1;
+      _M_end2  = __rhs._M_end2;
+      return *this;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    void _StateSeq<_CharT, _TraitsT>::
+    _M_push_back(_StateIdT __id)
+    {
+      if (_M_end1 != _S_invalid_state_id)
+        _M_nfa[_M_end1]._M_next = __id;
+      _M_end1 = __id;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    void _StateSeq<_CharT, _TraitsT>::
+    _M_append(_StateIdT __id)
+    {
+      if (_M_end2 != _S_invalid_state_id)
+      {
+        if (_M_end2 == _M_end1)
+          _M_nfa[_M_end2]._M_alt = __id;
+        else
+          _M_nfa[_M_end2]._M_next = __id;
+        _M_end2 = _S_invalid_state_id;
+      }
+      if (_M_end1 != _S_invalid_state_id)
+        _M_nfa[_M_end1]._M_next = __id;
+      _M_end1 = __id;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    void _StateSeq<_CharT, _TraitsT>::
+    _M_append(_StateSeq& __rhs)
+    {
+      if (_M_end2 != _S_invalid_state_id)
+      {
+        if (_M_end2 == _M_end1)
+          _M_nfa[_M_end2]._M_alt = __rhs._M_start;
+        else
+          _M_nfa[_M_end2]._M_next = __rhs._M_start;
+        _M_end2 = _S_invalid_state_id;
+      }
+      if (__rhs._M_end2 != _S_invalid_state_id)
+        _M_end2 = __rhs._M_end2;
+      if (_M_end1 != _S_invalid_state_id)
+        _M_nfa[_M_end1]._M_next = __rhs._M_start;
+      _M_end1 = __rhs._M_end1;
+    }
+
+  // @todo implement this function.
+  template<typename _CharT, typename _TraitsT>
+    _StateIdT _StateSeq<_CharT, _TraitsT>::
+    _M_clone()
+    { return 0; }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
Index: include/bits/regex_compiler.h
===================================================================
--- include/bits/regex_compiler.h	(revision 201491)
+++ include/bits/regex_compiler.h	(working copy)
@@ -39,17 +39,90 @@
    * @{
    */
 
-  /// Base class for scanner.
-  struct _Scanner_base
-  {
-    typedef unsigned int _StateT;
+  /// Matches a character range (bracket expression)
+  template<typename _CharT, typename _TraitsT>
+    struct _BracketMatcher
+    {
+      typedef typename _TraitsT::char_class_type  _CharClassT;
+      typedef typename _TraitsT::string_type      _StringT;
+      typedef regex_constants::syntax_option_type _FlagT;
 
-    static constexpr _StateT _S_state_in_brace    = 1 << 0;
-    static constexpr _StateT _S_state_in_bracket  = 1 << 1;
+      explicit
+      _BracketMatcher(bool __is_non_matching,
+                      const _TraitsT& __t,
+                      _FlagT __flags)
+      : _M_is_non_matching(__is_non_matching), _M_traits(__t),
+        _M_flags(__flags), _M_class_set(0)
+      { }
 
-    virtual ~_Scanner_base() { };
-  };
+      bool
+      operator()(_CharT) const;
 
+      void
+      _M_add_char(_CharT __c)
+      {
+        if (_M_flags & regex_constants::collate)
+          if (_M_is_icase())
+            _M_char_set.push_back(_M_traits.translate_nocase(__c));
+          else
+            _M_char_set.push_back(_M_traits.translate(__c));
+        else
+          _M_char_set.push_back(__c);
+      }
+
+      void
+      _M_add_collating_element(const _StringT& __s)
+      {
+        auto __st = _M_traits.lookup_collatename(&*__s.begin(), &*__s.end());
+        if (__st.empty())
+          __throw_regex_error(regex_constants::error_collate);
+        // TODO: digraph
+        _M_char_set.push_back(__st[0]);
+      }
+
+      void
+      _M_add_equivalence_class(const _StringT& __s)
+      {
+        _M_add_character_class(
+          _M_traits.transform_primary(&*__s.begin(), &*__s.end()));
+      }
+
+      void
+      _M_add_character_class(const _StringT& __s)
+      {
+        auto __st = _M_traits.
+          lookup_classname(&*__s.begin(), &*__s.end(), _M_is_icase());
+        if (__st == 0)
+          __throw_regex_error(regex_constants::error_ctype);
+        _M_class_set |= __st;
+      }
+
+      void
+      _M_make_range(_CharT __l, _CharT __r)
+      { _M_range_set.push_back(make_pair(_M_get_str(__l), _M_get_str(__r))); }
+
+      bool
+      _M_is_icase() const
+      { return _M_flags & regex_constants::icase; }
+
+      _StringT
+      _M_get_str(_CharT __c) const
+      {
+        auto __s = _StringT(1,
+                            _M_is_icase()
+                            ? _M_traits.translate_nocase(__c)
+                            : _M_traits.translate(__c));
+        return _M_traits.transform(__s.begin(), __s.end());
+      }
+
+      _TraitsT                              _M_traits;
+      _FlagT                                _M_flags;
+      bool                                  _M_is_non_matching;
+      std::vector<_CharT>                   _M_char_set;
+      std::vector<pair<_StringT, _StringT>> _M_range_set;
+      _CharClassT                           _M_class_set;
+    };
+
   /**
    * @brief struct _Scanner. Scans an input range for regex tokens.
    *
@@ -60,12 +133,12 @@
    * constructor: different regular expression grammars will interpret
    * the same input pattern in syntactically different ways.
    */
-  template<typename _InputIterator>
-    class _Scanner: public _Scanner_base
+  template<typename _InputIter>
+    class _Scanner
     {
     public:
-      typedef _InputIterator                                        _IteratorT;
-      typedef typename std::iterator_traits<_IteratorT>::value_type _CharT;
+      typedef unsigned int                                          _StateT;
+      typedef typename std::iterator_traits<_InputIter>::value_type _CharT;
       typedef std::basic_string<_CharT>                             _StringT;
       typedef regex_constants::syntax_option_type                   _FlagT;
       typedef const std::ctype<_CharT>                              _CtypeT;
@@ -103,8 +176,8 @@
 	_S_token_unknown
       };
 
-      _Scanner(_IteratorT __begin, _IteratorT __end, _FlagT __flags,
-	       std::locale __loc)
+      _Scanner(_InputIter __begin, _InputIter __end,
+               _FlagT __flags, std::locale __loc)
       : _M_current(__begin) , _M_end(__end) , _M_flags(__flags),
         _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_state(0)
       { _M_advance(); }
@@ -144,8 +217,10 @@
       void
       _M_eat_collsymbol();
 
-      _IteratorT  _M_current;
-      _IteratorT  _M_end;
+      static constexpr _StateT _S_state_in_brace    = 1 << 0;
+      static constexpr _StateT _S_state_in_bracket  = 1 << 1;
+      _InputIter  _M_current;
+      _InputIter  _M_end;
       _FlagT      _M_flags;
       _CtypeT&    _M_ctype;
       _TokenT     _M_curToken;
@@ -153,520 +228,28 @@
       _StateT     _M_state;
     };
 
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_advance()
-    {
-      if (_M_current == _M_end)
-	{
-	  _M_curToken = _S_token_eof;
-	  return;
-	}
-
-      _CharT __c = *_M_current;
-      if (_M_state & _S_state_in_bracket)
-	{
-	  _M_scan_in_bracket();
-	  return;
-	}
-      if (_M_state & _S_state_in_brace)
-	{
-	  _M_scan_in_brace();
-	  return;
-	}
-#if 0
-      // TODO: re-enable line anchors when _M_assertion is implemented.
-      // See PR libstdc++/47724
-      else if (_M_state & _S_state_at_start && __c == _M_ctype.widen('^'))
-	{
-	  _M_curToken = _S_token_line_begin;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('$'))
-	{
-	  _M_curToken = _S_token_line_end;
-	  ++_M_current;
-	  return;
-	}
-#endif
-      else if (__c == _M_ctype.widen('.'))
-	{
-	  _M_curToken = _S_token_anychar;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('*'))
-	{
-	  _M_curToken = _S_token_closure0;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('+'))
-	{
-	  _M_curToken = _S_token_closure1;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('|'))
-	{
-	  _M_curToken = _S_token_or;
-	  ++_M_current;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('['))
-	{
-          if (*++_M_current == _M_ctype.widen('^'))
-            {
-              _M_curToken = _S_token_bracket_inverse_begin;
-              ++_M_current;
-            }
-          else
-            _M_curToken = _S_token_bracket_begin;
-	  _M_state |= _S_state_in_bracket;
-	  return;
-	}
-      else if (__c == _M_ctype.widen('\\'))
-	{
-	  _M_eat_escape();
-	  return;
-	}
-      else if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	{
-	  if (__c == _M_ctype.widen('('))
-	    {
-	      _M_curToken = _S_token_subexpr_begin;
-	      ++_M_current;
-	      return;
-	    }
-	  else if (__c == _M_ctype.widen(')'))
-	    {
-	      _M_curToken = _S_token_subexpr_end;
-	      ++_M_current;
-	      return;
-	    }
-	  else if (__c == _M_ctype.widen('{'))
-	    {
-	      _M_curToken = _S_token_interval_begin;
-	      _M_state |= _S_state_in_brace;
-	      ++_M_current;
-	      return;
-	    }
-	}
-
-      _M_curToken = _S_token_ord_char;
-      _M_curValue.assign(1, __c);
-      ++_M_current;
-    }
-
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_scan_in_brace()
-    {
-      if (_M_ctype.is(_CtypeT::digit, *_M_current))
-	{
-	  _M_curToken = _S_token_dup_count;
-	  _M_curValue.assign(1, *_M_current);
-	  ++_M_current;
-	  while (_M_current != _M_end
-		 && _M_ctype.is(_CtypeT::digit, *_M_current))
-	    {
-	      _M_curValue += *_M_current;
-	      ++_M_current;
-	    }
-	  return;
-	}
-      else if (*_M_current == _M_ctype.widen(','))
-	{
-	  _M_curToken = _S_token_comma;
-	  ++_M_current;
-	  return;
-	}
-      if (_M_flags & (regex_constants::basic | regex_constants::grep))
-	{
-	  if (*_M_current == _M_ctype.widen('\\'))
-	    _M_eat_escape();
-	}
-      else 
-	{
-	  if (*_M_current == _M_ctype.widen('}'))
-	    {
-	      _M_curToken = _S_token_interval_end;
-	      _M_state &= ~_S_state_in_brace;
-	      ++_M_current;
-	      return;
-	    }
-	}
-    }
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_scan_in_bracket()
-    {
-      if (*_M_current == _M_ctype.widen('['))
-	{
-	  ++_M_current;
-	  if (_M_current == _M_end)
-	    {
-	      _M_curToken = _S_token_eof;
-	      return;
-	    }
-
-	  if (*_M_current == _M_ctype.widen('.'))
-	    {
-	      _M_curToken = _S_token_collsymbol;
-	      _M_eat_collsymbol();
-	      return;
-	    }
-	  else if (*_M_current == _M_ctype.widen(':'))
-	    {
-	      _M_curToken = _S_token_char_class_name;
-	      _M_eat_charclass();
-	      return;
-	    }
-	  else if (*_M_current == _M_ctype.widen('='))
-	    {
-	      _M_curToken = _S_token_equiv_class_name;
-	      _M_eat_equivclass();
-	      return;
-	    }
-	}
-      else if (*_M_current == _M_ctype.widen('-'))
-	{
-	  _M_curToken = _S_token_dash;
-	  ++_M_current;
-	  return;
-	}
-      else if (*_M_current == _M_ctype.widen(']'))
-	{
-          _M_curToken = _S_token_bracket_end;
-          _M_state &= ~_S_state_in_bracket;
-          ++_M_current;
-          return;
-	}
-      else if (*_M_current == _M_ctype.widen('\\'))
-        {
-	  _M_eat_escape();
-	  return;
-        }
-      _M_curToken = _S_token_collelem_single;
-      _M_curValue.assign(1, *_M_current);
-      ++_M_current;
-    }
-
-  // TODO implement it.
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_escape()
-    {
-      ++_M_current;
-      if (_M_current == _M_end)
-	{
-	  _M_curToken = _S_token_eof;
-	  return;
-	}
-      _CharT __c = *_M_current;
-      ++_M_current;
-
-      if (__c == _M_ctype.widen('('))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    _M_curToken = _S_token_subexpr_begin;
-	}
-      else if (__c == _M_ctype.widen(')'))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    _M_curToken = _S_token_subexpr_end;
-	}
-      else if (__c == _M_ctype.widen('{'))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    {
-	      _M_curToken = _S_token_interval_begin;
-	      _M_state |= _S_state_in_brace;
-	    }
-	}
-      else if (__c == _M_ctype.widen('}'))
-	{
-	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
-	    {
-	      _M_curToken = _S_token_ord_char;
-	      _M_curValue.assign(1, __c);
-	    }
-	  else
-	    {
-	      if (!(_M_state && _S_state_in_brace))
-		__throw_regex_error(regex_constants::error_badbrace);
-	      _M_state &= ~_S_state_in_brace;
-	      _M_curToken = _S_token_interval_end;
-	    }
-	}
-      else if (__c == _M_ctype.widen('x'))
-	{
-	  ++_M_current;
-	  if (_M_current == _M_end)
-	    {
-	      _M_curToken = _S_token_eof;
-	      return;
-	    }
-	  if (_M_ctype.is(_CtypeT::digit, *_M_current))
-	    {
-	      _M_curValue.assign(1, *_M_current);
-	      ++_M_current;
-	      if (_M_current == _M_end)
-		{
-		  _M_curToken = _S_token_eof;
-		  return;
-		}
-	      if (_M_ctype.is(_CtypeT::digit, *_M_current))
-		{
-		  _M_curValue += *_M_current;
-		  ++_M_current;
-		  return;
-		}
-	    }
-	}
-      else if (__c == _M_ctype.widen('^')
-	       || __c == _M_ctype.widen('.')
-	       || __c == _M_ctype.widen('*')
-	       || __c == _M_ctype.widen('$')
-	       || __c == _M_ctype.widen('\\'))
-	{
-	  _M_curToken = _S_token_ord_char;
-	  _M_curValue.assign(1, __c);
-	}
-      else if (_M_ctype.is(_CtypeT::digit, __c))
-	{
-	  _M_curToken = _S_token_backref;
-	  _M_curValue.assign(1, __c);
-	}
-      else if (_M_state & _S_state_in_bracket)
-        {
-          if (__c == _M_ctype.widen('-')
-              || __c == _M_ctype.widen('[')
-              || __c == _M_ctype.widen(']'))
-            {
-              _M_curToken = _S_token_ord_char;
-              _M_curValue.assign(1, __c);
-            }
-          else if ((_M_flags & regex_constants::ECMAScript)
-                   && __c == _M_ctype.widen('b'))
-            {
-              _M_curToken = _S_token_ord_char;
-              _M_curValue.assign(1, _M_ctype.widen(' '));
-            }
-          else
-            __throw_regex_error(regex_constants::error_escape);
-        }
-      else
-	__throw_regex_error(regex_constants::error_escape);
-    }
-
-  // Eats a character class or throwns an exception.
-  // current point to ':' delimiter on entry, char after ']' on return
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_charclass()
-    {
-      ++_M_current; // skip ':'
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_ctype);
-      for (_M_curValue.clear();
-	   _M_current != _M_end && *_M_current != _M_ctype.widen(':');
-	   ++_M_current)
-	_M_curValue += *_M_current;
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_ctype);
-      ++_M_current; // skip ':'
-      if (*_M_current != _M_ctype.widen(']'))
-	__throw_regex_error(regex_constants::error_ctype);
-      ++_M_current; // skip ']'
-    }
-
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_equivclass()
-    {
-      ++_M_current; // skip '='
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      for (_M_curValue.clear();
-	   _M_current != _M_end && *_M_current != _M_ctype.widen('=');
-	   ++_M_current)
-	_M_curValue += *_M_current;
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip '='
-      if (*_M_current != _M_ctype.widen(']'))
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip ']'
-    }
-
-
-  template<typename _InputIterator>
-    void
-    _Scanner<_InputIterator>::
-    _M_eat_collsymbol()
-    {
-      ++_M_current; // skip '.'
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      for (_M_curValue.clear();
-	   _M_current != _M_end && *_M_current != _M_ctype.widen('.');
-	   ++_M_current)
-	_M_curValue += *_M_current;
-      if (_M_current == _M_end)
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip '.'
-      if (*_M_current != _M_ctype.widen(']'))
-	__throw_regex_error(regex_constants::error_collate);
-      ++_M_current; // skip ']'
-    }
-
-#ifdef _GLIBCXX_DEBUG
-  template<typename _InputIterator>
-    std::ostream&
-    _Scanner<_InputIterator>::
-    _M_print(std::ostream& ostr)
-    {
-      switch (_M_curToken)
-      {
-	case _S_token_anychar:
-	  ostr << "any-character\n";
-	  break;
-	case _S_token_backref:
-	  ostr << "backref\n";
-	  break;
-	case _S_token_bracket_begin:
-	  ostr << "bracket-begin\n";
-	  break;
-	case _S_token_bracket_inverse_begin:
-          ostr << "bracket-inverse-begin\n";
-          break;
-	case _S_token_bracket_end:
-	  ostr << "bracket-end\n";
-	  break;
-	case _S_token_char_class_name:
-	  ostr << "char-class-name \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_closure0:
-	  ostr << "closure0\n";
-	  break;
-	case _S_token_closure1:
-	  ostr << "closure1\n";
-	  break;
-	case _S_token_collelem_multi:
-	  ostr << "coll-elem-multi \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_collelem_single:
-	  ostr << "coll-elem-single \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_collsymbol:
-	  ostr << "collsymbol \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_comma:
-	  ostr << "comma\n";
-	  break;
-	case _S_token_dash:
-	  ostr << "dash\n";
-	  break;
-	case _S_token_dup_count:
-	  ostr << "dup count: " << _M_curValue << "\n";
-	  break;
-	case _S_token_eof:
-	  ostr << "EOF\n";
-	  break;
-	case _S_token_equiv_class_name:
-	  ostr << "equiv-class-name \"" << _M_curValue << "\"\n";
-	  break;
-	case _S_token_interval_begin:
-	  ostr << "interval begin\n";
-	  break;
-	case _S_token_interval_end:
-	  ostr << "interval end\n";
-	  break;
-	case _S_token_line_begin:
-	  ostr << "line begin\n";
-	  break;
-	case _S_token_line_end:
-	  ostr << "line end\n";
-	  break;
-	case _S_token_opt:
-	  ostr << "opt\n";
-	  break;
-	case _S_token_or:
-	  ostr << "or\n";
-	  break;
-	case _S_token_ord_char:
-	  ostr << "ordinary character: \"" << _M_value() << "\"\n";
-	  break;
-	case _S_token_subexpr_begin:
-	  ostr << "subexpr begin\n";
-	  break;
-	case _S_token_subexpr_end:
-	  ostr << "subexpr end\n";
-	  break;
-	case _S_token_word_begin:
-	  ostr << "word begin\n";
-	  break;
-	case _S_token_word_end:
-	  ostr << "word end\n";
-	  break;
-	case _S_token_unknown:
-	  ostr << "-- unknown token --\n";
-	  break;
-        default:
-          _GLIBCXX_DEBUG_ASSERT(false);
-      }
-      return ostr;
-    }
-#endif
-
   /// Builds an NFA from an input iterator interval.
-  template<typename _InIter, typename _TraitsT>
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
     class _Compiler
     {
     public:
-      typedef _InIter                                            _IterT;
-      typedef typename std::iterator_traits<_InIter>::value_type _CharT;
-      typedef std::basic_string<_CharT>                          _StringT;
-      typedef regex_constants::syntax_option_type                _FlagT;
+      typedef typename _TraitsT::string_type      _StringT;
+      typedef _NFA<_CharT, _TraitsT>              _RegexT;
+      typedef regex_constants::syntax_option_type _FlagT;
 
-      _Compiler(const _InIter& __b, const _InIter& __e,
-		_TraitsT& __traits, _FlagT __flags);
+      _Compiler(_InputIter __b, _InputIter __e,
+                const _TraitsT& __traits, _FlagT __flags);
 
-      const _Nfa&
-      _M_nfa() const
-      { return _M_state_store; }
+      std::shared_ptr<_RegexT>
+      _M_get_nfa() const
+      { return std::shared_ptr<_RegexT>(new _RegexT(_M_state_store)); }
 
     private:
-      typedef _Scanner<_InIter>                              _ScannerT;
-      typedef typename _ScannerT::_TokenT                    _TokenT;
-      typedef std::stack<_StateSeq, std::vector<_StateSeq> > _StackT;
-      typedef _BracketMatcher<_InIter, _TraitsT>             _BMatcherT;
+      typedef _Scanner<_InputIter>                            _ScannerT;
+      typedef typename _ScannerT::_TokenT                     _TokenT;
+      typedef _StateSeq<_CharT, _TraitsT>                     _StateSeqT;
+      typedef std::stack<_StateSeqT, std::vector<_StateSeqT>> _StackT;
+      typedef _BracketMatcher<_CharT, _TraitsT>               _BMatcherT;
 
       // accepts a specific token or returns false.
       bool
@@ -720,345 +303,17 @@
       int
       _M_cur_int_value(int __radix);
 
-      _TraitsT&      _M_traits;
-      _ScannerT      _M_scanner;
-      _StringT       _M_cur_value;
-      _Nfa           _M_state_store;
-      _StackT        _M_stack;
-      _FlagT         _M_flags;
+      const _TraitsT& _M_traits;
+      _ScannerT       _M_scanner;
+      _StringT        _M_cur_value;
+      _RegexT         _M_state_store;
+      _StackT         _M_stack;
+      _FlagT          _M_flags;
     };
 
-  template<typename _InIter, typename _TraitsT>
-    _Compiler<_InIter, _TraitsT>::
-    _Compiler(const _InIter& __b, const _InIter& __e, _TraitsT& __traits,
-	      _Compiler<_InIter, _TraitsT>::_FlagT __flags)
-    : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()),
-      _M_state_store(__flags), _M_flags(__flags)
-    {
-      typedef _StartTagger<_InIter, _TraitsT> _Start;
-      typedef _EndTagger<_InIter, _TraitsT> _End;
-
-      _StateSeq __r(_M_state_store,
-      		    _M_state_store._M_insert_subexpr_begin(_Start(0)));
-      _M_disjunction();
-      if (!_M_stack.empty())
-	{
-	  __r._M_append(_M_stack.top());
-	  _M_stack.pop();
-	}
-      __r._M_append(_M_state_store._M_insert_subexpr_end(0, _End(0)));
-      __r._M_append(_M_state_store._M_insert_accept());
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_match_token(_Compiler<_InIter, _TraitsT>::_TokenT token)
-    { 
-      if (token == _M_scanner._M_token())
-	{
-          _M_cur_value = _M_scanner._M_value();
-          _M_scanner._M_advance();
-	  return true;
-	}
-      return false;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_disjunction()
-    {
-      this->_M_alternative();
-      if (_M_match_token(_ScannerT::_S_token_or))
-	{
-	  _StateSeq __alt1 = _M_stack.top(); _M_stack.pop();
-	  this->_M_disjunction();
-	  _StateSeq __alt2 = _M_stack.top(); _M_stack.pop();
-	  _M_stack.push(_StateSeq(__alt1, __alt2));
-	}
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_alternative()
-    {
-      if (this->_M_term())
-	{
-	  _StateSeq __re = _M_stack.top(); _M_stack.pop();
-	  this->_M_alternative();
-	  if (!_M_stack.empty())
-	    {
-	      __re._M_append(_M_stack.top());
-	      _M_stack.pop();
-	    }
-	  _M_stack.push(__re);
-	}
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_term()
-    {
-      if (this->_M_assertion())
-	return true;
-      if (this->_M_atom())
-	{
-	  this->_M_quantifier();
-	  return true;
-	}
-      return false;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_assertion()
-    {
-      if (_M_match_token(_ScannerT::_S_token_line_begin))
-	{
-	  // __m.push(_Matcher::_S_opcode_line_begin);
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_line_end))
-	{
-	  // __m.push(_Matcher::_S_opcode_line_end);
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_word_begin))
-	{
-	  // __m.push(_Matcher::_S_opcode_word_begin);
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_word_end))
-	{
-	  // __m.push(_Matcher::_S_opcode_word_end);
-	  return true;
-	}
-      return false;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_quantifier()
-    {
-      if (_M_match_token(_ScannerT::_S_token_closure0))
-	{
-	  if (_M_stack.empty())
-	    __throw_regex_error(regex_constants::error_badrepeat);
-	  _StateSeq __r(_M_stack.top(), -1);
-	  __r._M_append(__r._M_front());
-	  _M_stack.pop();
-	  _M_stack.push(__r);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_closure1))
-	{
-	  if (_M_stack.empty())
-	    __throw_regex_error(regex_constants::error_badrepeat);
-	  _StateSeq __r(_M_state_store,
-			_M_state_store.
-			_M_insert_alt(_S_invalid_state_id,
-				      _M_stack.top()._M_front()));
-	  _M_stack.top()._M_append(__r);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_opt))
-	{
-	  if (_M_stack.empty())
-	  __throw_regex_error(regex_constants::error_badrepeat);
-	  _StateSeq __r(_M_stack.top(), -1);
-	  _M_stack.pop();
-	  _M_stack.push(__r);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_interval_begin))
-	{
-	  if (_M_stack.empty())
-	    __throw_regex_error(regex_constants::error_badrepeat);
-	  if (!_M_match_token(_ScannerT::_S_token_dup_count))
-	    __throw_regex_error(regex_constants::error_badbrace);
-	  _StateSeq __r(_M_stack.top());
-	  int __min_rep = _M_cur_int_value(10);
-	  for (int __i = 1; __i < __min_rep; ++__i)
-	    _M_stack.top()._M_append(__r._M_clone()); 
-	  if (_M_match_token(_ScannerT::_S_token_comma))
-	    if (_M_match_token(_ScannerT::_S_token_dup_count))
-	      {
-		int __n = _M_cur_int_value(10) - __min_rep;
-		if (__n < 0)
-		  __throw_regex_error(regex_constants::error_badbrace);
-		for (int __i = 0; __i < __n; ++__i)
-		  {
-		    _StateSeq __r(_M_state_store,
-				  _M_state_store.
-				  _M_insert_alt(_S_invalid_state_id,
-						_M_stack.top()._M_front()));
-		    _M_stack.top()._M_append(__r);
-		  }
-	      }
-	    else
-	      {
-		_StateSeq __r(_M_stack.top(), -1);
-		__r._M_push_back(__r._M_front());
-		_M_stack.pop();
-		_M_stack.push(__r);
-	      }
-	  if (!_M_match_token(_ScannerT::_S_token_interval_end))
-	    __throw_regex_error(regex_constants::error_brace);
-	  return;
-	}
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_atom()
-    {
-      typedef _CharMatcher<_InIter, _TraitsT> _CMatcher;
-      typedef _StartTagger<_InIter, _TraitsT> _Start;
-      typedef _EndTagger<_InIter, _TraitsT> _End;
-
-      if (_M_match_token(_ScannerT::_S_token_anychar))
-	{
-	  _M_stack.push(_StateSeq(_M_state_store,
-                                  _M_state_store._M_insert_matcher
-                                  (_AnyMatcher)));
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_ord_char))
-	{
-	  _M_stack.push(_StateSeq(_M_state_store,
-                                  _M_state_store._M_insert_matcher
-                                  (_CMatcher(_M_cur_value[0], _M_flags, _M_traits))));
-	  return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_backref))
-	{
-	  // __m.push(_Matcher::_S_opcode_ordchar, _M_cur_value);
-          _M_state_store._M_set_back_ref(true);
-	  //return true;
-	}
-      if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
-	{
-	  int __mark = _M_state_store._M_sub_count();
-	  _StateSeq __r(_M_state_store,
-			_M_state_store.
-			_M_insert_subexpr_begin(_Start(__mark)));
-	  this->_M_disjunction();
-	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
-	    __throw_regex_error(regex_constants::error_paren);
-	  if (!_M_stack.empty())
-	    {
-	      __r._M_append(_M_stack.top());
-	      _M_stack.pop();
-	    }
-	  __r._M_append(_M_state_store._M_insert_subexpr_end
-			(__mark, _End(__mark)));
-	  _M_stack.push(__r);
-	  return true;
-	}
-      return _M_bracket_expression();
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool
-    _Compiler<_InIter, _TraitsT>::
-    _M_bracket_expression()
-    {
-      bool __inverse =
-        _M_match_token(_ScannerT::_S_token_bracket_inverse_begin);
-      if (!(__inverse || _M_match_token(_ScannerT::_S_token_bracket_begin)))
-        return false;
-      _BMatcherT __matcher( __inverse, _M_flags, _M_traits);
-      // special case: only if  _not_ chr first after
-      // '[' or '[^' or if ECMAscript
-      if (!_M_bracket_list(__matcher) // list is empty
-          && !(_M_flags & regex_constants::ECMAScript))
-        __throw_regex_error(regex_constants::error_brack);
-      _M_stack.push(_StateSeq(_M_state_store,
-                              _M_state_store._M_insert_matcher(__matcher)));
-      return true;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    bool // list is non-empty
-    _Compiler<_InIter, _TraitsT>::
-    _M_bracket_list(_BMatcherT& __matcher)
-    {
-      if (_M_match_token(_ScannerT::_S_token_bracket_end))
-        return false;
-      _M_expression_term(__matcher);
-      _M_bracket_list(__matcher);
-      return true;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    void
-    _Compiler<_InIter, _TraitsT>::
-    _M_expression_term(_BMatcherT& __matcher)
-    {
-      if (_M_match_token(_ScannerT::_S_token_collsymbol))
-	{
-	  __matcher._M_add_collating_element(_M_cur_value);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
-	{
-	  __matcher._M_add_equivalence_class(_M_cur_value);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_char_class_name))
-	{
-	  __matcher._M_add_character_class(_M_cur_value);
-	  return;
-	}
-      if (_M_match_token(_ScannerT::_S_token_collelem_single)) // [a
-        {
-          auto __ch = _M_cur_value[0];
-          if (_M_match_token(_ScannerT::_S_token_dash)) // [a-
-            {
-              // If the dash is the last character in the bracket expression,
-              // it is not special.
-              if (_M_scanner._M_token() == _ScannerT::_S_token_bracket_end)
-                __matcher._M_add_char(_M_cur_value[0]); // [a-] <=> [a\-]
-              else // [a-z]
-                {
-                  if (!_M_match_token(_ScannerT::_S_token_collelem_single))
-                    __throw_regex_error(regex_constants::error_range);
-                  __matcher._M_make_range(__ch, _M_cur_value[0]);
-                }
-            }
-          else // [a]
-            __matcher._M_add_char(__ch);
-          return;
-        }
-      __throw_regex_error(regex_constants::error_brack);
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    int
-    _Compiler<_InIter, _TraitsT>::
-    _M_cur_int_value(int __radix)
-    {
-      int __v = 0;
-      for (typename _StringT::size_type __i = 0;
-	   __i < _M_cur_value.length(); ++__i)
-	__v =__v * __radix + _M_traits.value(_M_cur_value[__i], __radix);
-      return __v;
-    }
-
-  template<typename _InIter, typename _TraitsT>
-    _AutomatonPtr
-    __compile(const _InIter& __b, const _InIter& __e, _TraitsT& __t,
-	      regex_constants::syntax_option_type __f)
-    { return _AutomatonPtr(new _Nfa(_Compiler<_InIter, _TraitsT>(__b, __e, __t,
-                                        __f)._M_nfa())); }
-
  //@} regex-detail
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace __detail
 } // namespace std
+
+#include <bits/regex_compiler.tcc>
Index: include/bits/regex_compiler.tcc
===================================================================
--- include/bits/regex_compiler.tcc	(revision 0)
+++ include/bits/regex_compiler.tcc	(working copy)
@@ -0,0 +1,896 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_compiler.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_advance()
+    {
+      if (_M_current == _M_end)
+	{
+	  _M_curToken = _S_token_eof;
+	  return;
+	}
+
+      _CharT __c = *_M_current;
+      if (_M_state & _S_state_in_bracket)
+	{
+	  _M_scan_in_bracket();
+	  return;
+	}
+      if (_M_state & _S_state_in_brace)
+	{
+	  _M_scan_in_brace();
+	  return;
+	}
+#if 0
+      // TODO: re-enable line anchors when _M_assertion is implemented.
+      // See PR libstdc++/47724
+      else if (_M_state & _S_state_at_start && __c == _M_ctype.widen('^'))
+	{
+	  _M_curToken = _S_token_line_begin;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('$'))
+	{
+	  _M_curToken = _S_token_line_end;
+	  ++_M_current;
+	  return;
+	}
+#endif
+      else if (__c == _M_ctype.widen('.'))
+	{
+	  _M_curToken = _S_token_anychar;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('*'))
+	{
+	  _M_curToken = _S_token_closure0;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('+'))
+	{
+	  _M_curToken = _S_token_closure1;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('|'))
+	{
+	  _M_curToken = _S_token_or;
+	  ++_M_current;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('['))
+	{
+          if (*++_M_current == _M_ctype.widen('^'))
+            {
+              _M_curToken = _S_token_bracket_inverse_begin;
+              ++_M_current;
+            }
+          else
+            _M_curToken = _S_token_bracket_begin;
+	  _M_state |= _S_state_in_bracket;
+	  return;
+	}
+      else if (__c == _M_ctype.widen('\\'))
+	{
+	  _M_eat_escape();
+	  return;
+	}
+      else if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	{
+	  if (__c == _M_ctype.widen('('))
+	    {
+	      _M_curToken = _S_token_subexpr_begin;
+	      ++_M_current;
+	      return;
+	    }
+	  else if (__c == _M_ctype.widen(')'))
+	    {
+	      _M_curToken = _S_token_subexpr_end;
+	      ++_M_current;
+	      return;
+	    }
+	  else if (__c == _M_ctype.widen('{'))
+	    {
+	      _M_curToken = _S_token_interval_begin;
+	      _M_state |= _S_state_in_brace;
+	      ++_M_current;
+	      return;
+	    }
+	}
+
+      _M_curToken = _S_token_ord_char;
+      _M_curValue.assign(1, __c);
+      ++_M_current;
+    }
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_scan_in_brace()
+    {
+      if (_M_ctype.is(_CtypeT::digit, *_M_current))
+	{
+	  _M_curToken = _S_token_dup_count;
+	  _M_curValue.assign(1, *_M_current);
+	  ++_M_current;
+	  while (_M_current != _M_end
+		 && _M_ctype.is(_CtypeT::digit, *_M_current))
+	    {
+	      _M_curValue += *_M_current;
+	      ++_M_current;
+	    }
+	  return;
+	}
+      else if (*_M_current == _M_ctype.widen(','))
+	{
+	  _M_curToken = _S_token_comma;
+	  ++_M_current;
+	  return;
+	}
+      if (_M_flags & (regex_constants::basic | regex_constants::grep))
+	{
+	  if (*_M_current == _M_ctype.widen('\\'))
+	    _M_eat_escape();
+	}
+      else
+	{
+	  if (*_M_current == _M_ctype.widen('}'))
+	    {
+	      _M_curToken = _S_token_interval_end;
+	      _M_state &= ~_S_state_in_brace;
+	      ++_M_current;
+	      return;
+	    }
+	}
+    }
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_scan_in_bracket()
+    {
+      if (*_M_current == _M_ctype.widen('['))
+	{
+	  ++_M_current;
+	  if (_M_current == _M_end)
+	    {
+	      _M_curToken = _S_token_eof;
+	      return;
+	    }
+
+	  if (*_M_current == _M_ctype.widen('.'))
+	    {
+	      _M_curToken = _S_token_collsymbol;
+	      _M_eat_collsymbol();
+	      return;
+	    }
+	  else if (*_M_current == _M_ctype.widen(':'))
+	    {
+	      _M_curToken = _S_token_char_class_name;
+	      _M_eat_charclass();
+	      return;
+	    }
+	  else if (*_M_current == _M_ctype.widen('='))
+	    {
+	      _M_curToken = _S_token_equiv_class_name;
+	      _M_eat_equivclass();
+	      return;
+	    }
+	}
+      else if (*_M_current == _M_ctype.widen('-'))
+	{
+	  _M_curToken = _S_token_dash;
+	  ++_M_current;
+	  return;
+	}
+      else if (*_M_current == _M_ctype.widen(']'))
+	{
+          _M_curToken = _S_token_bracket_end;
+          _M_state &= ~_S_state_in_bracket;
+          ++_M_current;
+          return;
+	}
+      else if (*_M_current == _M_ctype.widen('\\'))
+        {
+	  _M_eat_escape();
+	  return;
+        }
+      _M_curToken = _S_token_collelem_single;
+      _M_curValue.assign(1, *_M_current);
+      ++_M_current;
+    }
+
+  // TODO Complete it.
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_escape()
+    {
+      ++_M_current;
+      if (_M_current == _M_end)
+	{
+	  _M_curToken = _S_token_eof;
+	  return;
+	}
+      _CharT __c = *_M_current;
+      ++_M_current;
+
+      if (__c == _M_ctype.widen('('))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    _M_curToken = _S_token_subexpr_begin;
+	}
+      else if (__c == _M_ctype.widen(')'))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    _M_curToken = _S_token_subexpr_end;
+	}
+      else if (__c == _M_ctype.widen('{'))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    {
+	      _M_curToken = _S_token_interval_begin;
+	      _M_state |= _S_state_in_brace;
+	    }
+	}
+      else if (__c == _M_ctype.widen('}'))
+	{
+	  if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
+	    {
+	      _M_curToken = _S_token_ord_char;
+	      _M_curValue.assign(1, __c);
+	    }
+	  else
+	    {
+	      if (!(_M_state && _S_state_in_brace))
+		__throw_regex_error(regex_constants::error_badbrace);
+	      _M_state &= ~_S_state_in_brace;
+	      _M_curToken = _S_token_interval_end;
+	    }
+	}
+      else if (__c == _M_ctype.widen('x'))
+	{
+	  ++_M_current;
+	  if (_M_current == _M_end)
+	    {
+	      _M_curToken = _S_token_eof;
+	      return;
+	    }
+	  if (_M_ctype.is(_CtypeT::digit, *_M_current))
+	    {
+	      _M_curValue.assign(1, *_M_current);
+	      ++_M_current;
+	      if (_M_current == _M_end)
+		{
+		  _M_curToken = _S_token_eof;
+		  return;
+		}
+	      if (_M_ctype.is(_CtypeT::digit, *_M_current))
+		{
+		  _M_curValue += *_M_current;
+		  ++_M_current;
+		  return;
+		}
+	    }
+	}
+      else if (__c == _M_ctype.widen('^')
+	       || __c == _M_ctype.widen('.')
+	       || __c == _M_ctype.widen('*')
+	       || __c == _M_ctype.widen('$')
+	       || __c == _M_ctype.widen('\\'))
+	{
+	  _M_curToken = _S_token_ord_char;
+	  _M_curValue.assign(1, __c);
+	}
+      else if (_M_ctype.is(_CtypeT::digit, __c))
+	{
+	  _M_curToken = _S_token_backref;
+	  _M_curValue.assign(1, __c);
+	}
+      else if (_M_state & _S_state_in_bracket)
+        {
+          if (__c == _M_ctype.widen('-')
+              || __c == _M_ctype.widen('[')
+              || __c == _M_ctype.widen(']'))
+            {
+              _M_curToken = _S_token_ord_char;
+              _M_curValue.assign(1, __c);
+            }
+          else if ((_M_flags & regex_constants::ECMAScript)
+                   && __c == _M_ctype.widen('b'))
+            {
+              _M_curToken = _S_token_ord_char;
+              _M_curValue.assign(1, _M_ctype.widen(' '));
+            }
+          else
+            __throw_regex_error(regex_constants::error_escape);
+        }
+      else
+	__throw_regex_error(regex_constants::error_escape);
+    }
+
+  // Eats a character class or throwns an exception.
+  // current point to ':' delimiter on entry, char after ']' on return
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_charclass()
+    {
+      ++_M_current; // skip ':'
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_ctype);
+      for (_M_curValue.clear();
+	   _M_current != _M_end && *_M_current != _M_ctype.widen(':');
+	   ++_M_current)
+	_M_curValue += *_M_current;
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_ctype);
+      ++_M_current; // skip ':'
+      if (*_M_current != _M_ctype.widen(']'))
+	__throw_regex_error(regex_constants::error_ctype);
+      ++_M_current; // skip ']'
+    }
+
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_equivclass()
+    {
+      ++_M_current; // skip '='
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      for (_M_curValue.clear();
+	   _M_current != _M_end && *_M_current != _M_ctype.widen('=');
+	   ++_M_current)
+	_M_curValue += *_M_current;
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip '='
+      if (*_M_current != _M_ctype.widen(']'))
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip ']'
+    }
+
+
+  template<typename _BiIter>
+    void
+    _Scanner<_BiIter>::
+    _M_eat_collsymbol()
+    {
+      ++_M_current; // skip '.'
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      for (_M_curValue.clear();
+	   _M_current != _M_end && *_M_current != _M_ctype.widen('.');
+	   ++_M_current)
+	_M_curValue += *_M_current;
+      if (_M_current == _M_end)
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip '.'
+      if (*_M_current != _M_ctype.widen(']'))
+	__throw_regex_error(regex_constants::error_collate);
+      ++_M_current; // skip ']'
+    }
+
+#ifdef _GLIBCXX_DEBUG
+  template<typename _BiIter>
+    std::ostream&
+    _Scanner<_BiIter>::
+    _M_print(std::ostream& ostr)
+    {
+      switch (_M_curToken)
+      {
+	case _S_token_anychar:
+	  ostr << "any-character\n";
+	  break;
+	case _S_token_backref:
+	  ostr << "backref\n";
+	  break;
+	case _S_token_bracket_begin:
+	  ostr << "bracket-begin\n";
+	  break;
+	case _S_token_bracket_inverse_begin:
+          ostr << "bracket-inverse-begin\n";
+          break;
+	case _S_token_bracket_end:
+	  ostr << "bracket-end\n";
+	  break;
+	case _S_token_char_class_name:
+	  ostr << "char-class-name \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_closure0:
+	  ostr << "closure0\n";
+	  break;
+	case _S_token_closure1:
+	  ostr << "closure1\n";
+	  break;
+	case _S_token_collelem_multi:
+	  ostr << "coll-elem-multi \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_collelem_single:
+	  ostr << "coll-elem-single \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_collsymbol:
+	  ostr << "collsymbol \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_comma:
+	  ostr << "comma\n";
+	  break;
+	case _S_token_dash:
+	  ostr << "dash\n";
+	  break;
+	case _S_token_dup_count:
+	  ostr << "dup count: " << _M_curValue << "\n";
+	  break;
+	case _S_token_eof:
+	  ostr << "EOF\n";
+	  break;
+	case _S_token_equiv_class_name:
+	  ostr << "equiv-class-name \"" << _M_curValue << "\"\n";
+	  break;
+	case _S_token_interval_begin:
+	  ostr << "interval begin\n";
+	  break;
+	case _S_token_interval_end:
+	  ostr << "interval end\n";
+	  break;
+	case _S_token_line_begin:
+	  ostr << "line begin\n";
+	  break;
+	case _S_token_line_end:
+	  ostr << "line end\n";
+	  break;
+	case _S_token_opt:
+	  ostr << "opt\n";
+	  break;
+	case _S_token_or:
+	  ostr << "or\n";
+	  break;
+	case _S_token_ord_char:
+	  ostr << "ordinary character: \"" << _M_value() << "\"\n";
+	  break;
+	case _S_token_subexpr_begin:
+	  ostr << "subexpr begin\n";
+	  break;
+	case _S_token_subexpr_end:
+	  ostr << "subexpr end\n";
+	  break;
+	case _S_token_word_begin:
+	  ostr << "word begin\n";
+	  break;
+	case _S_token_word_end:
+	  ostr << "word end\n";
+	  break;
+	case _S_token_unknown:
+	  ostr << "-- unknown token --\n";
+	  break;
+        default:
+          _GLIBCXX_DEBUG_ASSERT(false);
+      }
+      return ostr;
+    }
+#endif
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _Compiler(_InputIter __b, _InputIter __e,
+              const _TraitsT& __traits, _FlagT __flags)
+    : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()),
+      _M_state_store(__flags), _M_flags(__flags)
+    {
+      _StateSeqT __r(_M_state_store,
+      		    _M_state_store._M_insert_subexpr_begin());
+      _M_disjunction();
+      if (!_M_stack.empty())
+	{
+	  __r._M_append(_M_stack.top());
+	  _M_stack.pop();
+	}
+      __r._M_append(_M_state_store._M_insert_subexpr_end());
+      __r._M_append(_M_state_store._M_insert_accept());
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_match_token(_Compiler<_InputIter, _CharT, _TraitsT>::_TokenT token)
+    {
+      if (token == _M_scanner._M_token())
+	{
+          _M_cur_value = _M_scanner._M_value();
+          _M_scanner._M_advance();
+	  return true;
+	}
+      return false;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_disjunction()
+    {
+      this->_M_alternative();
+      if (_M_match_token(_ScannerT::_S_token_or))
+	{
+	  _StateSeqT __alt1 = _M_stack.top(); _M_stack.pop();
+	  this->_M_disjunction();
+	  _StateSeqT __alt2 = _M_stack.top(); _M_stack.pop();
+	  _M_stack.push(_StateSeqT(__alt1, __alt2));
+	}
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_alternative()
+    {
+      if (this->_M_term())
+	{
+	  _StateSeqT __re = _M_stack.top(); _M_stack.pop();
+	  this->_M_alternative();
+	  if (!_M_stack.empty())
+	    {
+	      __re._M_append(_M_stack.top());
+	      _M_stack.pop();
+	    }
+	  _M_stack.push(__re);
+	}
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_term()
+    {
+      if (this->_M_assertion())
+	return true;
+      if (this->_M_atom())
+	{
+	  this->_M_quantifier();
+	  return true;
+	}
+      return false;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_assertion()
+    {
+      if (_M_match_token(_ScannerT::_S_token_line_begin))
+	{
+	  // __m.push(_Matcher::_S_opcode_line_begin);
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_line_end))
+	{
+	  // __m.push(_Matcher::_S_opcode_line_end);
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_word_begin))
+	{
+	  // __m.push(_Matcher::_S_opcode_word_begin);
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_word_end))
+	{
+	  // __m.push(_Matcher::_S_opcode_word_end);
+	  return true;
+	}
+      return false;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_quantifier()
+    {
+      if (_M_match_token(_ScannerT::_S_token_closure0))
+	{
+	  if (_M_stack.empty())
+	    __throw_regex_error(regex_constants::error_badrepeat);
+	  _StateSeqT __r(_M_stack.top(), -1);
+	  __r._M_append(__r._M_front());
+	  _M_stack.pop();
+	  _M_stack.push(__r);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_closure1))
+	{
+	  if (_M_stack.empty())
+	    __throw_regex_error(regex_constants::error_badrepeat);
+	  _StateSeqT __r(_M_state_store,
+			_M_state_store.
+			_M_insert_alt(_S_invalid_state_id,
+				      _M_stack.top()._M_front()));
+	  _M_stack.top()._M_append(__r);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_opt))
+	{
+	  if (_M_stack.empty())
+	  __throw_regex_error(regex_constants::error_badrepeat);
+	  _StateSeqT __r(_M_stack.top(), -1);
+	  _M_stack.pop();
+	  _M_stack.push(__r);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_interval_begin))
+	{
+	  if (_M_stack.empty())
+	    __throw_regex_error(regex_constants::error_badrepeat);
+	  if (!_M_match_token(_ScannerT::_S_token_dup_count))
+	    __throw_regex_error(regex_constants::error_badbrace);
+	  _StateSeqT __r(_M_stack.top());
+	  int __min_rep = _M_cur_int_value(10);
+	  for (int __i = 1; __i < __min_rep; ++__i)
+	    _M_stack.top()._M_append(__r._M_clone());
+	  if (_M_match_token(_ScannerT::_S_token_comma))
+	    if (_M_match_token(_ScannerT::_S_token_dup_count))
+	      {
+		int __n = _M_cur_int_value(10) - __min_rep;
+		if (__n < 0)
+		  __throw_regex_error(regex_constants::error_badbrace);
+		for (int __i = 0; __i < __n; ++__i)
+		  {
+		    _StateSeqT __r(_M_state_store,
+				  _M_state_store.
+				  _M_insert_alt(_S_invalid_state_id,
+						_M_stack.top()._M_front()));
+		    _M_stack.top()._M_append(__r);
+		  }
+	      }
+	    else
+	      {
+		_StateSeqT __r(_M_stack.top(), -1);
+		__r._M_push_back(__r._M_front());
+		_M_stack.pop();
+		_M_stack.push(__r);
+	      }
+	  if (!_M_match_token(_ScannerT::_S_token_interval_end))
+	    __throw_regex_error(regex_constants::error_brace);
+	  return;
+	}
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_atom()
+    {
+      if (_M_match_token(_ScannerT::_S_token_anychar))
+	{
+          const static auto&
+          __any_matcher = [](_CharT) -> bool
+          { return true; };
+
+	  _M_stack.push(_StateSeqT(_M_state_store,
+                                  _M_state_store._M_insert_matcher
+                                  (__any_matcher)));
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_ord_char))
+	{
+          auto __c = _M_cur_value[0];
+          __detail::_Matcher<_CharT> f;
+          if (_M_flags & regex_constants::icase)
+            {
+              auto __traits = this->_M_traits;
+              __c = __traits.translate_nocase(__c);
+              f = [__traits, __c](_CharT __ch) -> bool
+              { return __traits.translate_nocase(__ch) == __c; };
+            }
+          else
+            f = [__c](_CharT __ch) -> bool
+            { return __ch == __c; };
+
+	  _M_stack.push(_StateSeqT(_M_state_store,
+                                   _M_state_store._M_insert_matcher(f)));
+	  return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_backref))
+	{
+	  // __m.push(_Matcher::_S_opcode_ordchar, _M_cur_value);
+          _M_state_store._M_set_backref(true);
+	  //return true;
+	}
+      if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
+	{
+	  int __mark = _M_state_store._M_sub_count();
+	  _StateSeqT __r(_M_state_store,
+			_M_state_store.
+			_M_insert_subexpr_begin());
+	  this->_M_disjunction();
+	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
+	    __throw_regex_error(regex_constants::error_paren);
+	  if (!_M_stack.empty())
+	    {
+	      __r._M_append(_M_stack.top());
+	      _M_stack.pop();
+	    }
+	  __r._M_append(_M_state_store._M_insert_subexpr_end());
+	  _M_stack.push(__r);
+	  return true;
+	}
+      return _M_bracket_expression();
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_bracket_expression()
+    {
+      bool __inverse =
+        _M_match_token(_ScannerT::_S_token_bracket_inverse_begin);
+      if (!(__inverse || _M_match_token(_ScannerT::_S_token_bracket_begin)))
+        return false;
+      _BMatcherT __matcher( __inverse, _M_traits, _M_flags);
+      // special case: only if  _not_ chr first after
+      // '[' or '[^' or if ECMAscript
+      if (!_M_bracket_list(__matcher) // list is empty
+          && !(_M_flags & regex_constants::ECMAScript))
+        __throw_regex_error(regex_constants::error_brack);
+      _M_stack.push(_StateSeqT(_M_state_store,
+                              _M_state_store._M_insert_matcher(__matcher)));
+      return true;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    bool // list is non-empty
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_bracket_list(_BMatcherT& __matcher)
+    {
+      if (_M_match_token(_ScannerT::_S_token_bracket_end))
+        return false;
+      _M_expression_term(__matcher);
+      _M_bracket_list(__matcher);
+      return true;
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    void
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_expression_term(_BMatcherT& __matcher)
+    {
+      if (_M_match_token(_ScannerT::_S_token_collsymbol))
+	{
+	  __matcher._M_add_collating_element(_M_cur_value);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
+	{
+	  __matcher._M_add_equivalence_class(_M_cur_value);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_char_class_name))
+	{
+	  __matcher._M_add_character_class(_M_cur_value);
+	  return;
+	}
+      if (_M_match_token(_ScannerT::_S_token_collelem_single)) // [a
+        {
+          auto __ch = _M_cur_value[0];
+          if (_M_match_token(_ScannerT::_S_token_dash)) // [a-
+            {
+              // If the dash is the last character in the bracket expression,
+              // it is not special.
+              if (_M_scanner._M_token() == _ScannerT::_S_token_bracket_end)
+                __matcher._M_add_char(_M_cur_value[0]); // [a-] <=> [a\-]
+              else // [a-z]
+                {
+                  if (!_M_match_token(_ScannerT::_S_token_collelem_single))
+                    __throw_regex_error(regex_constants::error_range);
+                  __matcher._M_make_range(__ch, _M_cur_value[0]);
+                }
+            }
+          else // [a]
+            __matcher._M_add_char(__ch);
+          return;
+        }
+      __throw_regex_error(regex_constants::error_brack);
+    }
+
+  template<typename _InputIter, typename _CharT, typename _TraitsT>
+    int
+    _Compiler<_InputIter, _CharT, _TraitsT>::
+    _M_cur_int_value(int __radix)
+    {
+      int __v = 0;
+      for (typename _StringT::size_type __i = 0;
+	   __i < _M_cur_value.length(); ++__i)
+	__v =__v * __radix + _M_traits.value(_M_cur_value[__i], __radix);
+      return __v;
+    }
+
+  template<typename _CharT, typename _TraitsT>
+    bool _BracketMatcher<_CharT, _TraitsT>::
+    operator()(_CharT __ch) const
+    {
+      auto __oldch = __ch;
+      if (_M_flags & regex_constants::collate)
+        if (_M_is_icase())
+          __ch = _M_traits.translate_nocase(__ch);
+        else
+          __ch = _M_traits.translate(__ch);
+
+      bool __ret = false;
+      for (auto __c : _M_char_set)
+        if (__c == __ch)
+          {
+            __ret = true;
+            break;
+          }
+      if (!__ret && _M_traits.isctype(__oldch, _M_class_set))
+        __ret = true;
+      else
+        {
+          _StringT __s = _M_get_str(__ch);
+          for (auto& __it : _M_range_set)
+            if (__it.first <= __s && __s <= __it.second)
+              {
+                __ret = true;
+                break;
+              }
+        }
+      if (_M_is_non_matching)
+        __ret = !__ret;
+      return __ret;
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
Index: include/bits/regex_constants.h
===================================================================
--- include/bits/regex_constants.h	(revision 201491)
+++ include/bits/regex_constants.h	(working copy)
@@ -79,7 +79,7 @@
    */
   typedef unsigned int syntax_option_type;
 
-  /** 
+  /**
    * Specifies that the matching of regular expressions against a character
    * sequence shall be performed without regard to case.
    */
@@ -139,7 +139,7 @@
    * 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).  
+   * and \\ddd (where ddd is one, two, or three octal digits).
    */
   constexpr syntax_option_type awk        = 1 << _S_awk;
 
@@ -154,7 +154,7 @@
   /**
    * 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 
+   * IEEE Std 1003.1-2001.  This option is identical to syntax_option_type
    * extended, except that newlines are treated as whitespace.
    */
   constexpr syntax_option_type egrep      = 1 << _S_egrep;
@@ -215,35 +215,35 @@
    * expression shall not match [last, last).
    */
   constexpr match_flag_type match_not_eol     = 1 << _S_not_eol;
-   
+
   /**
    * The expression \\b is not matched against the sub-sequence
    * [first,first).
    */
   constexpr match_flag_type match_not_bow     = 1 << _S_not_bow;
-   
+
   /**
    * The expression \\b should not be matched against the sub-sequence
    * [last,last).
    */
   constexpr match_flag_type match_not_eow     = 1 << _S_not_eow;
-   
+
   /**
    * If more than one match is possible then any match is an acceptable
    * result.
    */
   constexpr match_flag_type match_any         = 1 << _S_any;
-   
+
   /**
    * The expression does not match an empty sequence.
    */
   constexpr match_flag_type match_not_null    = 1 << _S_not_null;
-   
+
   /**
    * The expression only matches a sub-sequence that begins at first .
    */
   constexpr 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
@@ -260,7 +260,7 @@
    * 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.
Index: include/bits/regex_cursor.h
===================================================================
--- include/bits/regex_cursor.h	(revision 201491)
+++ include/bits/regex_cursor.h	(working copy)
@@ -1,105 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_cursor.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   *  @defgroup regex-detail Base and Implementation Classes
-   *  @ingroup regex
-   *  @{
-   */
-
-  /// ABC for pattern matching
-  struct _PatternCursor
-  {
-    virtual ~_PatternCursor() { };
-    virtual void _M_next() = 0;
-    virtual void _M_prev() = 0;
-    virtual bool _M_at_end() const = 0;
-  };
-
-  /// Provides a cursor into the specific target string.
-  template<typename _FwdIterT>
-    class _SpecializedCursor
-    : public _PatternCursor
-    {
-    public:
-      _SpecializedCursor(const _FwdIterT& __b, const _FwdIterT __e)
-      : _M_b(__b), _M_c(__b), _M_e(__e)
-      { }
-
-      typename std::iterator_traits<_FwdIterT>::value_type
-      _M_current() const
-      { return *_M_c; }
-
-      void
-      _M_next()
-      { ++_M_c; }
-
-      void
-      _M_prev()
-      { --_M_c; }
-
-      _FwdIterT
-      _M_pos() const
-      { return _M_c; }
-
-      const _FwdIterT&
-      _M_begin() const
-      { return _M_b; }
-
-      const _FwdIterT&
-      _M_end() const
-      { return _M_e; }
-
-      bool
-      _M_at_end() const
-      { return _M_c == _M_e; }
-
-    private:
-      _FwdIterT _M_b;
-      _FwdIterT _M_c;
-      _FwdIterT _M_e;
-    };
-
-  // Helper function to create a cursor specialized for an iterator class.
-  template<typename _FwdIterT>
-    inline _SpecializedCursor<_FwdIterT>
-    __cursor(const _FwdIterT& __b, const _FwdIterT __e)
-    { return _SpecializedCursor<_FwdIterT>(__b, __e); }
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
Index: include/bits/regex_error.h
===================================================================
--- include/bits/regex_error.h	(revision 201491)
+++ include/bits/regex_error.h	(working copy)
@@ -45,7 +45,7 @@
    * @name 5.3 Error Types
    */
   //@{
- 
+
   enum error_type
     {
       _S_error_collate,
Index: include/bits/regex_executor.h
===================================================================
--- include/bits/regex_executor.h	(revision 0)
+++ include/bits/regex_executor.h	(working copy)
@@ -0,0 +1,199 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_executor.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template<typename, typename>
+    class basic_regex;
+
+  template<typename, typename>
+    class match_results;
+_GLIBCXX_END_NAMESPACE_VERSION
+
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @addtogroup regex-detail
+   * @{
+   */
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    class _Executor
+    {
+    public:
+      typedef match_results<_BiIter, _Alloc>   _ResultsT;
+      typedef regex_constants::match_flag_type _FlagT;
+
+      virtual
+      ~_Executor()
+      { }
+
+      // Set matched when string exactly match the pattern.
+      virtual bool
+      _M_match() = 0;
+
+      // Set matched when some prefix of the string matches the pattern.
+      virtual bool
+      _M_search_from_first() = 0;
+
+    protected:
+      typedef typename _NFA<_CharT, _TraitsT>::_SizeT _SizeT;
+      _Executor(_BiIter    __begin,
+                _BiIter    __end,
+                _ResultsT& __results,
+                _FlagT     __flags,
+                _SizeT     __size)
+      : _M_current(__begin), _M_end(__end),
+        _M_results(__results), _M_flags(__flags)
+      {
+        __results.resize(__size + 2);
+        for (auto __it : __results)
+          __it.matched = false;
+      }
+
+      _BiIter   _M_current;
+      _BiIter   _M_end;
+      _ResultsT& _M_results;
+      _FlagT    _M_flags;
+    };
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    class _DFSExecutor
+    : public _Executor<_BiIter, _Alloc, _CharT, _TraitsT>
+    {
+    public:
+      typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT;
+      typedef _NFA<_CharT, _TraitsT>                       _RegexT;
+      typedef typename _BaseT::_ResultsT                    _ResultsT;
+      typedef regex_constants::match_flag_type             _FlagT;
+
+      _DFSExecutor(_BiIter        __begin,
+                   _BiIter        __end,
+                   _ResultsT&      __results,
+                   const _RegexT& __nfa,
+                   _FlagT         __flags)
+      : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
+        _M_nfa(__nfa)
+      { }
+
+      bool
+      _M_match()
+      { return _M_dfs<true>(_M_nfa._M_start()); }
+
+      bool
+      _M_search_from_first()
+      { return _M_dfs<false>(_M_nfa._M_start()); }
+
+    private:
+      template<bool __match_mode>
+        bool
+        _M_dfs(_StateIdT __i);
+
+      const _RegexT& _M_nfa;
+    };
+
+  // It's essentially a variant of Single-Source-Shortest-Path problem, where,
+  // the matching results is the final distance and should be minimized.
+  // Instead of using Dijkstra Algorithm, I pick up the queue-optimizaed
+  // (BFS-like) Bellman-Ford algorithm,
+  // SPFA(http://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm).
+  //
+  // Every entry of _M_covered saves the solution(grouping status) for every
+  // matching head. When states transfer, solutions will be compared and
+  // deduplicated(based on which greedy mode we have).
+  //
+  // Time complexity: O(_M_str_cur.size() * _M_nfa.size())
+  // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count())
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    class _BFSExecutor
+    : public _Executor<_BiIter, _Alloc, _CharT, _TraitsT>
+    {
+    public:
+      typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT;
+      typedef _NFA<_CharT, _TraitsT>                       _RegexT;
+      typedef typename _BaseT::_ResultsT                   _ResultsT;
+      typedef std::unique_ptr<_ResultsT>                   _ResultsPtr;
+      typedef regex_constants::match_flag_type             _FlagT;
+
+      _BFSExecutor(_BiIter        __begin,
+                   _BiIter        __end,
+                   _ResultsT&      __results,
+                   const _RegexT& __nfa,
+                   _FlagT         __flags)
+      : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
+        _M_nfa(__nfa)
+      {
+        if (_M_nfa._M_start() != _S_invalid_state_id)
+          _M_covered[_M_nfa._M_start()] =
+            _ResultsPtr(new _ResultsT(this->_M_results));
+        _M_e_closure();
+      }
+
+      bool
+      _M_match()
+      { return _M_main_loop<true>(); }
+
+      bool
+      _M_search_from_first()
+      { return _M_main_loop<false>(); }
+
+    private:
+      template<bool __match_mode>
+        bool
+        _M_main_loop();
+
+      void
+      _M_e_closure();
+
+      void
+      _M_move();
+
+      bool
+      _M_match_less_than(_StateIdT __u, _StateIdT __v) const;
+
+      bool
+      _M_includes_some() const;
+
+      std::map<_StateIdT, _ResultsPtr>     _M_covered;
+      const _RegexT& _M_nfa;
+    };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_executor.tcc>
Index: include/bits/regex_executor.tcc
===================================================================
--- include/bits/regex_executor.tcc	(revision 0)
+++ include/bits/regex_executor.tcc	(working copy)
@@ -0,0 +1,252 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 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 bits/regex_executor.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // TODO: This is too slow. Try to compile the NFA to a DFA.
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+  template<bool __match_mode>
+    bool _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_dfs(_StateIdT __i)
+    {
+      auto& __current = this->_M_current;
+      auto& __end = this->_M_end;
+      auto& __results = this->_M_results;
+      if (__i == _S_invalid_state_id)
+        // This is not that certain. Need deeper investigate.
+        return false;
+      const auto& __state = _M_nfa[__i];
+      bool __ret = false;
+      switch (__state._M_opcode)
+        {
+        case _S_opcode_alternative:
+          // Greedy mode by default. For non-greedy mode,
+          // swap _M_alt and _M_next.
+          // TODO: Add greedy mode option.
+          __ret = _M_dfs<__match_mode>(__state._M_alt)
+            || _M_dfs<__match_mode>(__state._M_next);
+          break;
+        case _S_opcode_subexpr_begin:
+          __results.at(__state._M_subexpr).first = __current;
+          __ret = _M_dfs<__match_mode>(__state._M_next);
+          break;
+        case _S_opcode_subexpr_end:
+          __ret = _M_dfs<__match_mode>(__state._M_next);
+          __results.at(__state._M_subexpr).second = __current;
+          __results.at(__state._M_subexpr).matched = __ret;
+          break;
+        case _S_opcode_match:
+          if (__current != __end && __state._M_matches(*__current))
+            {
+              ++__current;
+              __ret = _M_dfs<__match_mode>(__state._M_next);
+              --__current;
+            }
+          break;
+        case _S_opcode_accept:
+          if (__match_mode)
+            __ret = __current == __end;
+          else
+            __ret = true;
+          break;
+        default:
+          _GLIBCXX_DEBUG_ASSERT(false);
+        }
+      return __ret;
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+  template<bool __match_mode>
+    bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_main_loop()
+    {
+      while (this->_M_current != this->_M_end)
+        {
+          if (!__match_mode)
+            if (_M_includes_some())
+              return true;
+          _M_move();
+          ++this->_M_current;
+          _M_e_closure();
+        }
+      return _M_includes_some();
+    }
+
+  // The SPFA approach.
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_e_closure()
+    {
+      auto& __current = this->_M_current;
+      std::queue<_StateIdT> __q;
+      std::vector<bool> __in_q(_M_nfa.size(), false);
+      for (auto& __it : _M_covered)
+        {
+          __in_q[__it.first] = true;
+          __q.push(__it.first);
+        }
+      while (!__q.empty())
+        {
+          auto __u = __q.front();
+          __q.pop();
+          __in_q[__u] = false;
+          const auto& __state = _M_nfa[__u];
+
+          // Can be implemented using method, but there're too much arguments.
+          auto __add_visited_state = [&](_StateIdT __v)
+          {
+            if (__v == _S_invalid_state_id)
+              return;
+            if (_M_match_less_than(__u, __v))
+              {
+                _M_covered[__v] = _ResultsPtr(new _ResultsT(*_M_covered[__u]));
+                // if a state is updated, it's outgoing neighbors should be
+                // reconsidered too. Push them to the queue.
+                if (!__in_q[__v])
+                  {
+                    __in_q[__v] = true;
+                    __q.push(__v);
+                  }
+              }
+          };
+
+          switch (__state._M_opcode)
+            {
+              case _S_opcode_alternative:
+                __add_visited_state(__state._M_next);
+                __add_visited_state(__state._M_alt);
+                break;
+              case _S_opcode_subexpr_begin:
+                _M_covered[__u]->at(__state._M_subexpr).first = __current;
+                __add_visited_state(__state._M_next);
+                break;
+              case _S_opcode_subexpr_end:
+                _M_covered[__u]->at(__state._M_subexpr).second = __current;
+                _M_covered[__u]->at(__state._M_subexpr).matched = true;
+                __add_visited_state(__state._M_next);
+                break;
+              case _S_opcode_match:
+                break;
+              case _S_opcode_accept:
+                __add_visited_state(__state._M_next);
+                break;
+              default:
+                _GLIBCXX_DEBUG_ASSERT(false);
+            }
+        }
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_move()
+    {
+      decltype(_M_covered) __next;
+      for (auto& __it : _M_covered)
+        {
+          const auto& __state = _M_nfa[__it.first];
+          if (__state._M_opcode == _S_opcode_match
+              && __state._M_matches(*this->_M_current))
+            if (_M_match_less_than(__it.first, __state._M_next)
+                && __state._M_next != _S_invalid_state_id)
+              __next[__state._M_next] = move(__it.second);
+        }
+      _M_covered = move(__next);
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_match_less_than(_StateIdT __u, _StateIdT __v) const
+    {
+      if (_M_covered.count(__u) == 0)
+        return false;
+      if (_M_covered.count(__v) > 0)
+        return true;
+      // TODO: Greedy and Non-greedy support
+      return true;
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+    _M_includes_some() const
+    {
+      auto& __s = _M_nfa._M_final_states();
+      auto& __t = _M_covered;
+      if (__s.size() > 0 && __t.size() > 0)
+        {
+          auto __first = __s.begin();
+          auto __second = __t.begin();
+          while (__first != __s.end() && __second != __t.end())
+            {
+              if (*__first < __second->first)
+                ++__first;
+              else if (__second->first < *__first)
+                ++__second;
+              else
+                {
+                  this->_M_results = *__second->second;
+                  return true;
+                }
+            }
+        }
+      return false;
+    }
+
+  template<typename _BiIter, typename _Alloc,
+    typename _CharT, typename _TraitsT>
+    std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+    __get_executor(_BiIter __b,
+                   _BiIter __e,
+                   match_results<_BiIter, _Alloc>& __m,
+                   const basic_regex<_CharT, _TraitsT>& __re,
+                   regex_constants::match_flag_type __flags)
+    {
+      typedef std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+        _ExecutorPtr;
+      typedef _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _DFSExecutorT;
+      auto __p = std::static_pointer_cast<_NFA<_CharT, _TraitsT>>
+        (__re._M_automaton);
+      if (__p->_M_has_backref)
+        return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p, __flags));
+      return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p, __flags));
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
Index: include/bits/regex_grep_matcher.h
===================================================================
--- include/bits/regex_grep_matcher.h	(revision 201491)
+++ include/bits/regex_grep_matcher.h	(working copy)
@@ -1,260 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_grep_matcher.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _BiIter>
-    class sub_match;
-
-  template<typename _Bi_iter, typename _Allocator>
-    class match_results;
-
-_GLIBCXX_END_NAMESPACE_VERSION
-  
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   *  @defgroup regex-detail Base and Implementation Classes
-   *  @ingroup regex
-   *  @{
-   */
-
-  /// A _Results facade specialized for wrapping a templated match_results.
-  template<typename _FwdIterT, typename _Alloc>
-    class _SpecializedResults
-    : public _Results
-    {
-    public:
-      _SpecializedResults(const _Automaton::_SizeT __size,
-			  const _SpecializedCursor<_FwdIterT>& __cursor,
-			  match_results<_FwdIterT, _Alloc>& __m);
-
-      ~_SpecializedResults()
-      {
-        if (_M_managed)
-          delete &_M_results;
-      }
-
-    private:
-      _SpecializedResults(const _SpecializedResults& __rhs)
-      : _M_results(*new match_results<_FwdIterT, _Alloc>(__rhs._M_results)),
-      _M_managed(true)
-      { }
-
-    public:
-      void
-      _M_set_pos(int __i, int __j, const _PatternCursor& __pc);
-
-      void
-      _M_set_range(int __i, const _PatternCursor& __pc)
-      {
-        typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
-        _CursorT __c = static_cast<_CursorT>(__pc);
-        _M_results.at(__i).first = __c._M_begin();
-        _M_results.at(__i).second = __c._M_end();
-      }
-
-      void
-      _M_set_matched(int __i, bool __is_matched)
-      { _M_results.at(__i).matched = __is_matched; }
-
-      std::unique_ptr<_Results>
-      _M_clone() const
-      { return unique_ptr<_Results>(new _SpecializedResults(*this)); }
-
-      void
-      _M_assign(const _Results& __rhs)
-      {
-        auto __r = static_cast<const _SpecializedResults*>(&__rhs);
-        _M_results = __r->_M_results;
-      }
-
-    private:
-      match_results<_FwdIterT, _Alloc>& _M_results;
-      bool                              _M_managed;
-    };
-
-  template<typename _FwdIterT, typename _Alloc>
-    _SpecializedResults<_FwdIterT, _Alloc>::
-    _SpecializedResults(const _Automaton::_SizeT __size,
-    			const _SpecializedCursor<_FwdIterT>& __cursor,
-                        match_results<_FwdIterT, _Alloc>& __m)
-    : _M_results(__m), _M_managed(false)
-    {
-      _M_results.clear();
-      _M_results.reserve(__size + 2);
-      _M_results.resize(__size);
-      typename match_results<_FwdIterT, _Alloc>::value_type __sm;
-      __sm.first = __sm.second = __cursor._M_begin();
-      _M_results.push_back(__sm);
-      __sm.first = __sm.second = __cursor._M_end();
-      _M_results.push_back(__sm);
-    }
-
-  template<typename _FwdIterT, typename _Alloc>
-    void
-    _SpecializedResults<_FwdIterT, _Alloc>::
-    _M_set_pos(int __i, int __j, const _PatternCursor& __pc)
-    { 
-      typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
-      _CursorT __c = static_cast<_CursorT>(__pc);
-      if (__j == 0)
-        _M_results.at(__i).first = __c._M_pos();
-      else
-        _M_results.at(__i).second = __c._M_pos();
-    }
-
-  /// Executes a regular expression NFA/DFA over a range using a
-  /// variant of the parallel execution algorithm featured in the grep
-  /// utility, modified to use Laurikari tags.
-  class _Grep_matcher
-  {
-  public:
-    _Grep_matcher(_PatternCursor&                   __p,
-                  _Results&                         __r,
-                  const _AutomatonPtr&              __automaton,
-                  regex_constants::match_flag_type  __flags)
-    : _M_nfa(static_pointer_cast<_Nfa>(__automaton)),
-      _M_str_cur(__p), _M_results(__r)
-    { }
-
-    virtual
-    ~_Grep_matcher()
-    { }
-
-    // Set matched when string exactly match the pattern.
-    virtual bool
-    _M_match() = 0;
-
-    // Set matched when some prefix of the string matches the pattern.
-    virtual bool
-    _M_search_from_first() = 0;
-
-  protected:
-    const std::shared_ptr<_Nfa>        _M_nfa;
-    _PatternCursor&                    _M_str_cur;
-    _Results&                          _M_results;
-  };
-
-  // Time complexity: exponential
-  // Space complexity: O(_M_str_cur.size())
-  // _M_dfs() take a state, along with current string cursor(_M_str_cur),
-  // trying to match current state with current character.
-  // Only _S_opcode_match will consume a character.
-  class _DFSMatcher
-  : public _Grep_matcher
-  {
-  public:
-    _DFSMatcher(_PatternCursor&                   __p,
-                _Results&                         __r,
-                const _AutomatonPtr&              __automaton,
-                regex_constants::match_flag_type  __flags)
-    : _Grep_matcher(__p, __r, __automaton, __flags)
-    { }
-
-    bool
-    _M_match()
-    { return _M_dfs<true>(_M_nfa->_M_start()); }
-
-    bool
-    _M_search_from_first()
-    { return _M_dfs<false>(_M_nfa->_M_start()); }
-
-  private:
-    template<bool __match_mode>
-      bool
-      _M_dfs(_StateIdT __i);
-  };
-
-  // It's essentially a variant of Single-Source-Shortest-Path problem, where,
-  // the matching results is the final distance and should be minimized.
-  // Instead of using Dijkstra Algorithm, I pick up the queue-optimizaed
-  // (BFS-like) Bellman-Ford algorithm,
-  // SPFA(http://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm).
-  //
-  // Every entry of _M_current saves the solution(grouping status) for every
-  // matching head. When states transfer, solutions will be compared and
-  // deduplicated(based on which greedy mode we have).
-  //
-  // Time complexity: O(_M_str_cur.size() * _M_nfa.size())
-  // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count())
-  class _BFSMatcher
-  : public _Grep_matcher
-  {
-  public:
-    _BFSMatcher(_PatternCursor&                   __p,
-                _Results&                         __r,
-                const _AutomatonPtr&              __automaton,
-                regex_constants::match_flag_type  __flags)
-    : _Grep_matcher(__p, __r, __automaton, __flags)
-    {
-      if (_M_nfa->_M_start() != _S_invalid_state_id)
-        _M_current[_M_nfa->_M_start()] = _M_results._M_clone();
-      _M_e_closure();
-    }
-
-    bool
-    _M_match()
-    { return _M_main_loop<true>(); }
-
-    bool
-    _M_search_from_first()
-    { return _M_main_loop<false>(); }
-
-  private:
-    template<bool __match_mode>
-      bool
-      _M_main_loop();
-
-    void
-    _M_e_closure();
-
-    void
-    _M_move();
-
-    bool
-    _M_match_less_than(_StateIdT __u, _StateIdT __v) const;
-
-    bool
-    _M_includes_some() const;
-
-    std::map<_StateIdT, std::unique_ptr<_Results>>     _M_current;
-  };
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace std
-
-#include <bits/regex_grep_matcher.tcc>
Index: include/bits/regex_grep_matcher.tcc
===================================================================
--- include/bits/regex_grep_matcher.tcc	(revision 201491)
+++ include/bits/regex_grep_matcher.tcc	(working copy)
@@ -1,243 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_grep_matcher.tcc
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-#include <regex>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  // TODO: This is too slow. Try to compile the NFA to a DFA.
-  template<bool __match_mode>
-    bool _DFSMatcher::
-    _M_dfs(_StateIdT __i)
-    {
-      if (__i == _S_invalid_state_id)
-        // This is not that certain. Need deeper investigate.
-        return false;
-      const auto& __state = (*_M_nfa)[__i];
-      bool __ret = false;
-      switch (__state._M_opcode)
-        {
-        case _S_opcode_alternative:
-          // Greedy mode by default. For non-greedy mode,
-          // swap _M_alt and _M_next.
-          // TODO: Add greedy mode option.
-          __ret = _M_dfs<__match_mode>(__state._M_alt)
-            || _M_dfs<__match_mode>(__state._M_next);
-          break;
-        case _S_opcode_subexpr_begin:
-          __state._M_tagger(_M_str_cur, _M_results);
-          __ret = _M_dfs<__match_mode>(__state._M_next);
-          break;
-        case _S_opcode_subexpr_end:
-          __state._M_tagger(_M_str_cur, _M_results);
-          __ret = _M_dfs<__match_mode>(__state._M_next);
-          _M_results._M_set_matched(__state._M_subexpr, __ret);
-          break;
-        case _S_opcode_match:
-          if (!_M_str_cur._M_at_end() && __state._M_matches(_M_str_cur))
-            {
-              _M_str_cur._M_next();
-              __ret = _M_dfs<__match_mode>(__state._M_next);
-              _M_str_cur._M_prev();
-            }
-          break;
-        case _S_opcode_accept:
-          if (__match_mode)
-            __ret = _M_str_cur._M_at_end();
-          else
-            __ret = true;
-          break;
-        default:
-          _GLIBCXX_DEBUG_ASSERT(false);
-        }
-      return __ret;
-    }
-
-  template<bool __match_mode>
-    bool _BFSMatcher::
-    _M_main_loop()
-    {
-      while (!_M_str_cur._M_at_end())
-        {
-          if (!__match_mode)
-            if (_M_includes_some())
-              return true;
-          _M_move();
-          _M_str_cur._M_next();
-          _M_e_closure();
-        }
-      return _M_includes_some();
-    }
-
-  // The SPFA approach.
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  void _BFSMatcher::
-  _M_e_closure()
-  {
-    std::queue<_StateIdT> __q;
-    std::vector<bool> __in_q(_M_nfa->size(), false);
-    for (auto& __it : _M_current)
-      {
-        __in_q[__it.first] = true;
-        __q.push(__it.first);
-      }
-    while (!__q.empty())
-      {
-        auto __u = __q.front();
-        __q.pop();
-        __in_q[__u] = false;
-        const auto& __state = (*_M_nfa)[__u];
-
-        // Can be implemented using method, but there're too much arguments.
-        auto __add_visited_state = [&](_StateIdT __v)
-        {
-          if (__v == _S_invalid_state_id)
-            return;
-          if (_M_match_less_than(__u, __v))
-            {
-              _M_current[__v] = _M_current[__u]->_M_clone();
-              // if a state is updated, it's outgoing neighbors should be
-              // reconsidered too. Push them to the queue.
-              if (!__in_q[__v])
-                {
-                  __in_q[__v] = true;
-                  __q.push(__v);
-                }
-            }
-        };
-
-        switch (__state._M_opcode)
-          {
-            case _S_opcode_alternative:
-              __add_visited_state(__state._M_next);
-              __add_visited_state(__state._M_alt);
-              break;
-            case _S_opcode_subexpr_begin:
-              __state._M_tagger(_M_str_cur, *_M_current[__u]);
-              __add_visited_state(__state._M_next);
-              break;
-            case _S_opcode_subexpr_end:
-              __state._M_tagger(_M_str_cur, *_M_current[__u]);
-              _M_current[__u]->_M_set_matched(__state._M_subexpr, true);
-              __add_visited_state(__state._M_next);
-              break;
-            case _S_opcode_match:
-              break;
-            case _S_opcode_accept:
-              __add_visited_state(__state._M_next);
-              break;
-            default:
-              _GLIBCXX_DEBUG_ASSERT(false);
-          }
-      }
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  void _BFSMatcher::
-  _M_move()
-  {
-    decltype(_M_current) __next;
-    for (auto& __it : _M_current)
-      {
-        const auto& __state = (*_M_nfa)[__it.first];
-        if (__state._M_opcode == _S_opcode_match
-            && __state._M_matches(_M_str_cur))
-          if (_M_match_less_than(__it.first, __state._M_next)
-              && __state._M_next != _S_invalid_state_id)
-            __next[__state._M_next] = __it.second->_M_clone();
-      }
-    _M_current = move(__next);
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  bool _BFSMatcher::
-  _M_match_less_than(_StateIdT __u, _StateIdT __v) const
-  {
-    if (_M_current.count(__u) == 0)
-      return false;
-    if (_M_current.count(__v) > 0)
-      return true;
-    // TODO: Greedy and Non-greedy support
-    return true;
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  bool _BFSMatcher::
-  _M_includes_some() const
-  {
-    auto& __s = _M_nfa->_M_final_states();
-    auto& __t = _M_current;
-    if (__s.size() > 0 && __t.size() > 0)
-      {
-	auto __first = __s.begin();
-	auto __second = __t.begin();
-	while (__first != __s.end() && __second != __t.end())
-	  {
-	    if (*__first < __second->first)
-	      ++__first;
-	    else if (__second->first < *__first)
-	      ++__second;
-	    else
-              {
-                _M_results._M_assign(*__second->second);
-                return true;
-              }
-	  }
-      }
-    return false;
-  }
-
-  // FIXME: move it to src/c++11 when it's stable, and make it not inlined.
-  inline
-  std::unique_ptr<_Grep_matcher> _Nfa::
-  _M_get_matcher(_PatternCursor&                   __p,
-                 _Results&                         __r,
-                 const _AutomatonPtr&              __a,
-                 regex_constants::match_flag_type  __flags)
-  {
-    if (_M_has_back_ref)
-      return unique_ptr<_Grep_matcher>(
-        new _DFSMatcher(__p, __r, __a, __flags));
-    else
-      return unique_ptr<_Grep_matcher>(
-        new _BFSMatcher(__p, __r, __a, __flags));
-  }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
Index: include/bits/regex_nfa.h
===================================================================
--- include/bits/regex_nfa.h	(revision 201491)
+++ include/bits/regex_nfa.h	(working copy)
@@ -1,491 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_nfa.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   * @addtogroup regex-detail
-   * @{
-   */
-
-  /// Provides a generic facade for a templated match_results.
-  struct _Results
-  {
-    virtual
-    ~_Results()
-    { }
-    virtual void _M_set_pos(int __i, int __j, const _PatternCursor& __p) = 0;
-    virtual void _M_set_matched(int __i, bool __is_matched) = 0;
-    virtual std::unique_ptr<_Results> _M_clone() const = 0;
-    virtual void _M_assign(const _Results& __rhs) = 0;
-  };
-
-  class _Grep_matcher;
-  class _Automaton;
-
-  /// Generic shared pointer to an automaton.
-  typedef std::shared_ptr<_Automaton> _AutomatonPtr;
-
-  /// Base class for, um, automata.  Could be an NFA or a DFA.  Your choice.
-  class _Automaton
-  {
-  public:
-    typedef unsigned int _SizeT;
-
-  public:
-    virtual
-    ~_Automaton() { }
-
-    virtual _SizeT
-    _M_sub_count() const = 0;
-
-    virtual std::unique_ptr<_Grep_matcher>
-    _M_get_matcher(_PatternCursor&                   __p,
-                   _Results&                         __r,
-                   const _AutomatonPtr&              __automaton,
-                   regex_constants::match_flag_type  __flags) = 0;
-
-#ifdef _GLIBCXX_DEBUG
-    virtual std::ostream&
-    _M_dot(std::ostream& __ostr) const = 0;
-#endif
-  };
-
-  /// Operation codes that define the type of transitions within the base NFA
-  /// that represents the regular expression.
-  enum _Opcode
-  {
-      _S_opcode_unknown       =   0,
-      _S_opcode_alternative   =   1,
-      _S_opcode_subexpr_begin =   4,
-      _S_opcode_subexpr_end   =   5,
-      _S_opcode_match         = 100,
-      _S_opcode_accept        = 255
-  };
-
-  /// Tags current state (for subexpr begin/end).
-  typedef std::function<void (const _PatternCursor&, _Results&)> _Tagger;
-
-  /// Start state tag.
-  template<typename _FwdIterT, typename _TraitsT>
-    struct _StartTagger
-    {
-      explicit
-      _StartTagger(int __i)
-      : _M_index(__i)
-      { }
-
-      void
-      operator()(const _PatternCursor& __pc, _Results& __r)
-      { __r._M_set_pos(_M_index, 0, __pc); }
-
-      int       _M_index;
-    };
-
-  /// End state tag.
-  template<typename _FwdIterT, typename _TraitsT>
-    struct _EndTagger
-    {
-      explicit
-      _EndTagger(int __i)
-      : _M_index(__i)
-      { }
-
-      void
-      operator()(const _PatternCursor& __pc, _Results& __r)
-      { __r._M_set_pos(_M_index, 1, __pc); }
-
-      int       _M_index;
-    };
-
-  // TODO For now we use an all-in-one comparator. In the future there may be
-  // optimizations based on regex_traits::translate and regex_transform.
-  template<typename _InIterT, typename _TraitsT>
-    struct _Comparator
-    {
-      typedef regex_constants::syntax_option_type _FlagT;
-      typedef typename _TraitsT::char_type        _CharT;
-      typedef std::basic_string<_CharT>           _StringT;
-
-      _Comparator(_FlagT __flags, const _TraitsT& __traits)
-      : _M_flags(__flags), _M_traits(__traits)
-      { }
-
-      bool
-      _M_equ(_CharT __a, _CharT __b) const;
-
-      bool
-      _M_le(_CharT __a, _CharT __b) const;
-
-      _FlagT                              _M_flags;
-      _TraitsT                            _M_traits;
-    };
-
-  /// Indicates if current state matches cursor current.
-  typedef std::function<bool (const _PatternCursor&)> _Matcher;
-
-  /// Matches any character
-  inline bool
-  _AnyMatcher(const _PatternCursor&)
-  { return true; }
-
-  /// Matches a single character
-  template<typename _InIterT, typename _TraitsT>
-    struct _CharMatcher
-    : public _Comparator<_InIterT, _TraitsT>
-    {
-      typedef _Comparator<_InIterT, _TraitsT>     _BaseT;
-      typedef typename _TraitsT::char_type        _CharT;
-      typedef regex_constants::syntax_option_type _FlagT;
-
-      explicit
-      _CharMatcher(_CharT __c, _FlagT __flags, const _TraitsT& __t)
-      : _BaseT(__flags, __t), _M_c(__c)
-      { }
-
-      bool
-      operator()(const _PatternCursor& __pc) const
-      {
-	typedef const _SpecializedCursor<_InIterT>& _CursorT;
-	_CursorT __c = static_cast<_CursorT>(__pc);
-        return this->_M_equ(__c._M_current(), _M_c);
-      }
-
-      _CharT       _M_c;
-    };
-
-  /// Matches a character range (bracket expression)
-  template<typename _InIterT, typename _TraitsT>
-    struct _BracketMatcher
-    : public _Comparator<_InIterT, _TraitsT>
-    {
-      typedef _Comparator<_InIterT, _TraitsT>     _BaseT;
-      typedef typename _TraitsT::char_class_type  _CharClassT;
-      typedef regex_constants::syntax_option_type _FlagT;
-      typedef typename _TraitsT::char_type        _CharT;
-      typedef std::basic_string<_CharT>           _StringT;
-
-      explicit
-      _BracketMatcher(bool __is_non_matching,
-                    _FlagT __flags,
-                    const _TraitsT& __t)
-      : _BaseT(__flags, __t), _M_flags(__flags), _M_traits(__t),
-      _M_is_non_matching(__is_non_matching), _M_class_set(0)
-      { }
-
-      bool
-      operator()(const _PatternCursor& __pc) const;
-
-      void
-      _M_add_char(_CharT __c)
-      { _M_char_set.push_back(__c); }
-
-      void
-      _M_add_collating_element(const _StringT& __s)
-      {
-        auto __st = _M_traits.lookup_collatename(&*__s.begin(), &*__s.end());
-        if (__st.empty())
-          __throw_regex_error(regex_constants::error_collate);
-        // TODO: digraph
-        _M_char_set.push_back(__st[0]);
-      }
-
-      void
-      _M_add_equivalence_class(const _StringT& __s)
-      {
-        _M_add_character_class(
-          _M_traits.transform_primary(&*__s.begin(), &*__s.end()));
-      }
-
-      void
-      _M_add_character_class(const _StringT& __s)
-      {
-        auto __st = _M_traits.lookup_classname(
-          &*__s.begin(), &*__s.end(), (_M_flags & regex_constants::icase));
-        if (__st == 0)
-          __throw_regex_error(regex_constants::error_ctype);
-        _M_class_set |= __st;
-      }
-
-      void
-      _M_make_range(_CharT __l, _CharT __r)
-      {
-        if (!this->_M_le(__l, __r))
-          __throw_regex_error(regex_constants::error_range);
-        _M_range_set.push_back(make_pair(__l, __r));
-      }
-
-      _FlagT                              _M_flags;
-      _TraitsT                            _M_traits;
-      bool                                _M_is_non_matching;
-      std::vector<_CharT>                 _M_char_set;
-      std::vector<pair<_CharT, _CharT>>   _M_range_set;
-      _CharClassT                         _M_class_set;
-    };
-
-  /// Identifies a state in the NFA.
-  typedef int _StateIdT;
-
-  /// The special case in which a state identifier is not an index.
-  static const _StateIdT _S_invalid_state_id  = -1;
-
-
-  /**
-   * @brief struct _State
-   *
-   * An individual state in an NFA
-   *
-   * In this case a "state" is an entry in the NFA definition coupled
-   * with its outgoing transition(s).  All states have a single outgoing
-   * transition, except for accepting states (which have no outgoing
-   * transitions) and alt states, which have two outgoing transitions.
-   */
-  struct _State
-  {
-    typedef int  _OpcodeT;
-
-    _OpcodeT     _M_opcode;    // type of outgoing transition
-    _StateIdT    _M_next;      // outgoing transition
-    _StateIdT    _M_alt;       // for _S_opcode_alternative
-    unsigned int _M_subexpr;   // for _S_opcode_subexpr_*
-    _Tagger      _M_tagger;    // for _S_opcode_subexpr_*
-    _Matcher     _M_matches;   // for _S_opcode_match
-
-    explicit _State(_OpcodeT __opcode)
-    : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
-    { }
-
-    _State(const _Matcher& __m)
-    : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id), _M_matches(__m)
-    { }
-
-    _State(_OpcodeT __opcode, unsigned int __s, const _Tagger& __t)
-    : _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__s),
-      _M_tagger(__t)
-    { }
-
-    _State(_StateIdT __next, _StateIdT __alt)
-    : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
-    { }
-
-#ifdef _GLIBCXX_DEBUG
-    std::ostream&
-    _M_print(std::ostream& ostr) const;
-
-    // Prints graphviz dot commands for state.
-    std::ostream&
-    _M_dot(std::ostream& __ostr, _StateIdT __id) const;
-#endif
-  };
-
-  
-  /// The Grep Matcher works on sets of states.  Here are sets of states.
-  typedef std::set<_StateIdT> _StateSet;
-
-  /**
-   * @brief struct _Nfa
-   *
-   * A collection of all states making up an NFA.
-   *
-   * An NFA is a 4-tuple M = (K, S, s, F), where
-   *    K is a finite set of states,
-   *    S is the alphabet of the NFA,
-   *    s is the initial state,
-   *    F is a set of final (accepting) states.
-   *
-   * This NFA class is templated on S, a type that will hold values of the
-   * underlying alphabet (without regard to semantics of that alphabet).  The
-   * other elements of the tuple are generated during construction of the NFA
-   * and are available through accessor member functions.
-   */
-  class _Nfa
-  : public _Automaton, public std::vector<_State>
-  {
-  public:
-    typedef _State                              _StateT;
-    typedef unsigned int                        _SizeT;
-    typedef regex_constants::syntax_option_type _FlagT;
-
-    _Nfa(_FlagT __f)
-    : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
-    // TODO: BFS by default. Your choice. Need to be set by the compiler.
-    _M_has_back_ref(false)
-    { }
-
-    ~_Nfa()
-    { }
-
-    _FlagT
-    _M_options() const
-    { return _M_flags; }
-
-    _StateIdT
-    _M_start() const
-    { return _M_start_state; }
-
-    const _StateSet&
-    _M_final_states() const
-    { return _M_accepting_states; }
-
-    _SizeT
-    _M_sub_count() const
-    { return _M_subexpr_count; }
-
-    _StateIdT
-    _M_insert_accept()
-    {
-      this->push_back(_StateT(_S_opcode_accept));
-      _M_accepting_states.insert(this->size()-1);
-      return this->size()-1;
-    }
-
-    _StateIdT
-    _M_insert_alt(_StateIdT __next, _StateIdT __alt)
-    {
-      this->push_back(_StateT(__next, __alt));
-      return this->size()-1;
-    }
-
-    _StateIdT
-    _M_insert_matcher(_Matcher __m)
-    {
-      this->push_back(_StateT(__m));
-      return this->size()-1;
-    }
-
-    _StateIdT
-    _M_insert_subexpr_begin(const _Tagger& __t)
-    {
-      this->push_back(_StateT(_S_opcode_subexpr_begin, _M_subexpr_count++,
-			      __t));
-      return this->size()-1;
-    }
-
-    _StateIdT 
-    _M_insert_subexpr_end(unsigned int __i, const _Tagger& __t)
-    {
-      this->push_back(_StateT(_S_opcode_subexpr_end, __i, __t));
-      return this->size()-1;
-    }
-
-    void
-    _M_set_back_ref(bool __b)
-    { _M_has_back_ref = __b; }
-
-    std::unique_ptr<_Grep_matcher>
-    _M_get_matcher(_PatternCursor&                   __p,
-                   _Results&                         __r,
-                   const _AutomatonPtr&              __automaton,
-                   regex_constants::match_flag_type  __flags);
-
-#ifdef _GLIBCXX_DEBUG
-    std::ostream&
-    _M_dot(std::ostream& __ostr) const;
-#endif
-
-  private:
-    _FlagT     _M_flags;
-    _StateIdT  _M_start_state;
-    _StateSet  _M_accepting_states;
-    _SizeT     _M_subexpr_count;
-    bool       _M_has_back_ref;
-  };
-
-  /// Describes a sequence of one or more %_State, its current start
-  /// and end(s).  This structure contains fragments of an NFA during
-  /// construction.
-  class _StateSeq
-  {
-  public:
-    // Constructs a single-node sequence
-    _StateSeq(_Nfa& __ss, _StateIdT __s, _StateIdT __e = _S_invalid_state_id)
-    : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
-    { }
-    // Constructs a split sequence from two other sequencces
-    _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
-    : _M_nfa(__e1._M_nfa),
-      _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
-      _M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
-    { }
-
-    // Constructs a split sequence from a single sequence
-    _StateSeq(const _StateSeq& __e, _StateIdT __id)
-    : _M_nfa(__e._M_nfa),
-      _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
-      _M_end1(__id), _M_end2(__e._M_end1)
-    { }
-
-    // Constructs a copy of a %_StateSeq
-    _StateSeq(const _StateSeq& __rhs)
-    : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
-      _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
-    { }
-
-
-    _StateSeq& operator=(const _StateSeq& __rhs);
-
-    _StateIdT
-    _M_front() const
-    { return _M_start; }
-
-    // Extends a sequence by one.
-    void
-    _M_push_back(_StateIdT __id);
-
-    // Extends and maybe joins a sequence.
-    void
-    _M_append(_StateIdT __id);
-
-    void
-    _M_append(_StateSeq& __rhs);
-
-    // Clones an entire sequence.
-    _StateIdT
-    _M_clone();
-
-  private:
-    _Nfa&     _M_nfa;
-    _StateIdT _M_start;
-    _StateIdT _M_end1;
-    _StateIdT _M_end2;
-
-  };
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace std
-
-#include <bits/regex_nfa.tcc>
-
Index: include/bits/regex_nfa.tcc
===================================================================
--- include/bits/regex_nfa.tcc	(revision 201491)
+++ include/bits/regex_nfa.tcc	(working copy)
@@ -1,232 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 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 bits/regex_nfa.tcc
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{regex}
- */
-#include <regex>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _InIterT, typename _TraitsT>
-    bool _BracketMatcher<_InIterT, _TraitsT>::
-    operator()(const _PatternCursor& __pc) const
-    {
-      typedef const _SpecializedCursor<_InIterT>& _CursorT;
-      _CursorT __c = static_cast<_CursorT>(__pc);
-      _CharT __ch = __c._M_current();
-      bool __ret = false;
-      for (auto __c : _M_char_set)
-        if (this->_M_equ(__c, __ch))
-          {
-            __ret = true;
-            break;
-          }
-      if (!__ret && _M_traits.isctype(__ch, _M_class_set))
-        __ret = true;
-      else
-        {
-          for (auto& __it : _M_range_set)
-            if (this->_M_le(__it.first, __ch) && this->_M_le(__ch, __it.second))
-              {
-                __ret = true;
-                break;
-              }
-        }
-      if (_M_is_non_matching)
-        __ret = !__ret;
-      return __ret;
-    }
-
-  template<typename _InIterT, typename _TraitsT>
-    bool _Comparator<_InIterT, _TraitsT>::
-    _M_equ(_CharT __a, _CharT __b) const
-    {
-      if (_M_flags & regex_constants::icase)
-        return _M_traits.translate_nocase(__a)
-          == _M_traits.translate_nocase(__b);
-      if (_M_flags & regex_constants::collate)
-        return _M_traits.translate(__a) == _M_traits.translate(__b);
-      return __a == __b;
-    }
-
-  template<typename _InIterT, typename _TraitsT>
-    bool _Comparator<_InIterT, _TraitsT>::
-    _M_le(_CharT __a, _CharT __b) const
-    {
-      _StringT __str1 = _StringT(1,
-                                 _M_flags & regex_constants::icase
-                                 ? _M_traits.translate_nocase(__a)
-                                 : _M_traits.translate(__a));
-      _StringT __str2 = _StringT(1,
-                                 _M_flags & regex_constants::icase
-                                 ? _M_traits.translate_nocase(__b)
-                                 : _M_traits.translate(__b));
-      return _M_traits.transform(__str1.begin(), __str1.end())
-        <= _M_traits.transform(__str2.begin(), __str2.end());
-    }
-
-#ifdef _GLIBCXX_DEBUG
-inline std::ostream& _State::
-_M_print(std::ostream& ostr) const
-{
-  switch (_M_opcode)
-  {
-    case _S_opcode_alternative:
-      ostr << "alt next=" << _M_next << " alt=" << _M_alt;
-      break;
-    case _S_opcode_subexpr_begin:
-      ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
-      break;
-    case _S_opcode_subexpr_end:
-      ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
-      break;
-    case _S_opcode_match:
-      ostr << "match next=" << _M_next;
-      break;
-    case _S_opcode_accept:
-      ostr << "accept next=" << _M_next;
-      break;
-    default:
-      ostr << "unknown next=" << _M_next;
-      break;
-  }
-  return ostr;
-}
-
-// Prints graphviz dot commands for state.
-inline std::ostream& _State::
-_M_dot(std::ostream& __ostr, _StateIdT __id) const
-{
-  switch (_M_opcode)
-  {
-    case _S_opcode_alternative:
-      __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" 
-             << __id << " -> " << _M_next
-             << " [label=\"epsilon\", tailport=\"s\"];\n"
-             << __id << " -> " << _M_alt 
-             << " [label=\"epsilon\", tailport=\"n\"];\n";
-      break;
-    case _S_opcode_subexpr_begin:
-      __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
-             << _M_subexpr << "\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
-      break;
-    case _S_opcode_subexpr_end:
-      __ostr << __id << " [label=\"" << __id << "\\nSEND "
-             << _M_subexpr << "\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
-      break;
-    case _S_opcode_match:
-      __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
-      break;
-    case _S_opcode_accept:
-      __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
-      break;
-    default:
-      __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n" 
-             << __id << " -> " << _M_next << " [label=\"?\"];\n";
-      break;
-  }
-  return __ostr;
-}
-
-inline std::ostream& _Nfa::
-_M_dot(std::ostream& __ostr) const
-{
-  __ostr << "digraph _Nfa {\n"
-   << "  rankdir=LR;\n";
-  for (unsigned int __i = 0; __i < this->size(); ++__i)
-  { this->at(__i)._M_dot(__ostr, __i); }
-  __ostr << "}\n";
-  return __ostr;
-}
-#endif
-
-inline _StateSeq& _StateSeq::
-operator=(const _StateSeq& __rhs)
-{
-  _M_start = __rhs._M_start;
-  _M_end1  = __rhs._M_end1;
-  _M_end2  = __rhs._M_end2;
-  return *this;
-}
-
-inline void _StateSeq::
-_M_push_back(_StateIdT __id)
-{
-  if (_M_end1 != _S_invalid_state_id)
-    _M_nfa[_M_end1]._M_next = __id;
-  _M_end1 = __id;
-}
-
-inline void _StateSeq::
-_M_append(_StateIdT __id)
-{
-  if (_M_end2 != _S_invalid_state_id)
-  {
-    if (_M_end2 == _M_end1)
-      _M_nfa[_M_end2]._M_alt = __id;
-    else
-      _M_nfa[_M_end2]._M_next = __id;
-    _M_end2 = _S_invalid_state_id;
-  }
-  if (_M_end1 != _S_invalid_state_id)
-    _M_nfa[_M_end1]._M_next = __id;
-  _M_end1 = __id;
-}
-
-inline void _StateSeq::
-_M_append(_StateSeq& __rhs)
-{
-  if (_M_end2 != _S_invalid_state_id)
-  {
-    if (_M_end2 == _M_end1)
-      _M_nfa[_M_end2]._M_alt = __rhs._M_start;
-    else
-      _M_nfa[_M_end2]._M_next = __rhs._M_start;
-    _M_end2 = _S_invalid_state_id;
-  }
-  if (__rhs._M_end2 != _S_invalid_state_id)
-    _M_end2 = __rhs._M_end2;
-  if (_M_end1 != _S_invalid_state_id)
-    _M_nfa[_M_end1]._M_next = __rhs._M_start;
-  _M_end1 = __rhs._M_end1;
-}
-
-// @todo implement this function.
-inline _StateIdT _StateSeq::
-_M_clone()
-{ return 0; }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
Index: include/std/regex
===================================================================
--- include/std/regex	(revision 201491)
+++ include/std/regex	(working copy)
@@ -54,13 +54,11 @@
 #include <utility>
 #include <vector>
 
-#include <bits/range_access.h>
 #include <bits/regex_constants.h>
 #include <bits/regex_error.h>
-#include <bits/regex_cursor.h>
-#include <bits/regex_nfa.h>
+#include <bits/regex_automaton.h>
 #include <bits/regex_compiler.h>
-#include <bits/regex_grep_matcher.h>
+#include <bits/regex_executor.h>
 #include <bits/regex.h>
 
 #endif // C++11
Index: testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc
===================================================================
--- testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc	(revision 201491)
+++ testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc	(working copy)
@@ -38,12 +38,10 @@
              regex_constants::match_flag_type         __flags
                             = regex_constants::match_default)
   {
-    __detail::_AutomatonPtr __a = __re._M_get_automaton();
-    __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
-    __detail::_SpecializedCursor<_Bi_iter> __cs(__s, __e);
-    __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
-    VERIFY( dynamic_cast<__detail::_DFSMatcher *>(
-              &*__a->_M_get_matcher(__cs, __r, __a, __flags)) != nullptr );
+    VERIFY( (dynamic_cast
+             <__detail::_DFSExecutor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits>*>
+             (&*__detail::__get_executor(__s, __e, __m, __re, __flags))
+             != nullptr) );
   }
 
 void

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
       [not found]           ` <52011EA2.3070703@oracle.com>
@ 2013-08-08  0:18             ` Tim Shen
  0 siblings, 0 replies; 22+ messages in thread
From: Tim Shen @ 2013-08-08  0:18 UTC (permalink / raw)
  To: libstdc++, gcc-patches

On Wed, Aug 7, 2013 at 12:04 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> By the way, your last patch is fine with me, I like the new *.tcc a lot.
> Just allow a day or so for further comments..

Committed.


-- 
Tim Shen

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-05 17:05 [Patch] Whole regex refactoring and current status Tim Shen
       [not found] ` <52001184.5020707@oracle.com>
@ 2013-08-08 10:01 ` Rainer Orth
  2013-08-08 10:25   ` Kyrylo Tkachov
  2013-08-08 10:26   ` Paolo Carlini
  1 sibling, 2 replies; 22+ messages in thread
From: Rainer Orth @ 2013-08-08 10:01 UTC (permalink / raw)
  To: Tim Shen; +Cc: libstdc++, gcc-patches

Tim Shen <timshen91@gmail.com> writes:

> As metioned in this[1] email, I here propose a refactored version of
> regex, and show the status:

This patch broke Solaris bootstrap:

In file included from /usr/include/ctype.h:18:0,
                 from /var/gcc/regression/trunk/10-gcc-gas/build/i386-pc-solaris2.10/libstdc++-v3/include/cctype:42,
                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/include/precompiled/stdc++.h:35:
/var/gcc/regression/trunk/10-gcc-gas/build/i386-pc-solaris2.10/libstdc++-v3/include/bits/regex.h:998:25: error: expected nested-name-specifier before numeric constant
       template<typename _B, typename _A, typename _C, typename _R>
                         ^

and several more instances.  This happens because <iso/ctype_iso.h> (via
<ctype.h>) has:

#define	_B	0x00000040	/* Blank */
#define	_C	0x00000020	/* Control character */

This is already documented:

http://gcc.gnu.org/onlinedocs/libstdc++/manual/source_code_style.html#coding_style.bad_identifiers

Please fix.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [Patch] Whole regex refactoring and current status
  2013-08-08 10:01 ` Rainer Orth
@ 2013-08-08 10:25   ` Kyrylo Tkachov
  2013-08-08 10:26   ` Paolo Carlini
  1 sibling, 0 replies; 22+ messages in thread
From: Kyrylo Tkachov @ 2013-08-08 10:25 UTC (permalink / raw)
  To: 'Rainer Orth', Tim Shen; +Cc: libstdc++, gcc-patches



> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Rainer Orth
> Sent: 08 August 2013 11:02
> To: Tim Shen
> Cc: libstdc++; gcc-patches
> Subject: Re: [Patch] Whole regex refactoring and current status
> 
> Tim Shen <timshen91@gmail.com> writes:
> 
> > As metioned in this[1] email, I here propose a refactored version of
> > regex, and show the status:
> 
> This patch broke Solaris bootstrap:
> 
> In file included from /usr/include/ctype.h:18:0,
>                  from /var/gcc/regression/trunk/10-gcc-gas/build/i386-pc-
> solaris2.10/libstdc++-v3/include/cctype:42,
>                  from /vol/gcc/src/hg/trunk/local/libstdc++-
> v3/include/precompiled/stdc++.h:35:
> /var/gcc/regression/trunk/10-gcc-gas/build/i386-pc-solaris2.10/libstdc++-
> v3/include/bits/regex.h:998:25: error: expected nested-name-specifier
> before numeric constant
>        template<typename _B, typename _A, typename _C, typename _R>
>                          ^
> 
> and several more instances.  This happens because <iso/ctype_iso.h> (via
> <ctype.h>) has:
> 
> #define	_B	0x00000040	/* Blank */
> #define	_C	0x00000020	/* Control character */
> 
> This is already documented:
> 
> http://gcc.gnu.org/onlinedocs/libstdc++/manual/source_code_style.html#cod
> ing_style.bad_identifiers

We're also seeing the same error for ARM builds.

Kyrill




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 10:01 ` Rainer Orth
  2013-08-08 10:25   ` Kyrylo Tkachov
@ 2013-08-08 10:26   ` Paolo Carlini
  2013-08-08 12:48     ` Rainer Orth
  1 sibling, 1 reply; 22+ messages in thread
From: Paolo Carlini @ 2013-08-08 10:26 UTC (permalink / raw)
  To: Rainer Orth, Tim Shen; +Cc: libstdc++, gcc-patches



Hi,

>This is already documented:
>
>http://gcc.gnu.org/onlinedocs/libstdc++/manual/source_code_style.html#coding_style.bad_identifiers

Indeed. As a simple to remember rule never use single underscore + single uppercase. Usually we add a p, like _Cp, etc. Plenty of examples everywhere. At the moment I can't do the search&replace, any such patch is preapproved though.

Thanks,
Paolo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 10:26   ` Paolo Carlini
@ 2013-08-08 12:48     ` Rainer Orth
  2013-08-08 12:53       ` Paolo Carlini
  2013-08-08 13:20       ` Kyrylo Tkachov
  0 siblings, 2 replies; 22+ messages in thread
From: Rainer Orth @ 2013-08-08 12:48 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Tim Shen, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 725 bytes --]

Hi Paolo,

>>This is already documented:
>>
>>http://gcc.gnu.org/onlinedocs/libstdc++/manual/source_code_style.html#coding_style.bad_identifiers
>
> Indeed. As a simple to remember rule never use single underscore + single
> uppercase. Usually we add a p, like _Cp, etc. Plenty of examples
> everywhere. At the moment I can't do the search&replace, any such patch is
> preapproved though.

I wasn't certain about the right convention.  The following patch
allowed bootstrap to finish on i386-pc-solaris2.10 and
x86_64-unknown-linux-gnu.  I'll commit the patch once Solaris testing
has finished.

2013-08-08  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* include/bits/regex.h: Replace _A, _B, _C, _R by _Ap, _Bp,
	_Cp, _Rp.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: regex.patch --]
[-- Type: text/x-patch, Size: 2399 bytes --]

diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -995,18 +995,18 @@ namespace std _GLIBCXX_VISIBILITY(defaul
                                  const basic_regex<_CharT, _TraitsT>&,
                                  regex_constants::match_flag_type);
 
-      template<typename _B, typename _A, typename _C, typename _R>
+      template<typename _Bp, typename _Ap, typename _Cp, typename _Rp>
         friend bool
-        regex_match(_B, _B,
-                    match_results<_B, _A>&,
-                    const basic_regex<_C, _R>&,
+        regex_match(_Bp, _Bp,
+                    match_results<_Bp, _Ap>&,
+                    const basic_regex<_Cp, _Rp>&,
                     regex_constants::match_flag_type);
 
-      template<typename _B, typename _A, typename _C, typename _R>
+      template<typename _Bp, typename _Ap, typename _Cp, typename _Rp>
         friend bool
-        regex_search(_B, _B,
-                     match_results<_B, _A>&,
-                     const basic_regex<_C, _R>&,
+        regex_search(_Bp, _Bp,
+                     match_results<_Bp, _Ap>&,
+                     const basic_regex<_Cp, _Rp>&,
                      regex_constants::match_flag_type);
 
       flag_type     _M_flags;
@@ -2111,16 +2111,16 @@ namespace std _GLIBCXX_VISIBILITY(defaul
       template<typename, typename, typename, typename>
         friend class __detail::_BFSExecutor;
 
-      template<typename _B, typename _A, typename _Ch_type, typename _Rx_traits>
+      template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits>
         friend bool
-        regex_match(_B, _B, match_results<_B, _A>&,
+        regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&,
                     const basic_regex<_Ch_type,
                     _Rx_traits>&,
                     regex_constants::match_flag_type);
 
-      template<typename _B, typename _A, typename _Ch_type, typename _Rx_traits>
+      template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits>
         friend bool
-        regex_search(_B, _B, match_results<_B, _A>&,
+        regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&,
                      const basic_regex<_Ch_type,
                      _Rx_traits>&,
                      regex_constants::match_flag_type);

[-- Attachment #3: Type: text/plain, Size: 4327 bytes --]



However, I see many 32-bit testsuite failures, both on Solaris and
Linux:

Running target unix/-m32
FAIL: 28_regex/algorithms/regex_match/basic/string_01.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/basic/string_01.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/basic/string_range_00_03.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/basic/string_range_00_03.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/basic/string_range_01_03.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/basic/string_range_01_03.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/basic/string_range_02_03.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/basic/string_range_02_03.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/53622.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/53622.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/57173.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/57173.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/cstring_plus.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/cstring_plus.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/cstring_questionmark.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/cstring_questionmark.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/string_any.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/string_any.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/string_range_00_03.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/string_range_00_03.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/string_range_01_03.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/string_range_01_03.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_match/extended/string_range_02_03.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_match/extended/string_range_02_03.cc compilation failed to produce executable
FAIL: 28_regex/algorithms/regex_search/basic/string_01.cc (test for excess errors)
WARNING: 28_regex/algorithms/regex_search/basic/string_01.cc compilation failed to produce executable
FAIL: 28_regex/basic_regex/ctors/basic/cstring.cc (test for excess errors)
FAIL: 28_regex/basic_regex/ctors/basic/raw_string.cc (test for excess errors)
WARNING: 28_regex/basic_regex/ctors/basic/raw_string.cc compilation failed to produce executable
FAIL: 28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc (test for excess errors)
WARNING: 28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc compilation failed to produce executable
FAIL: 28_regex/basic_regex/ctors/char/cstring_awk.cc (test for excess errors)
FAIL: 28_regex/basic_regex/ctors/char/cstring_egrep.cc (test for excess errors)
FAIL: 28_regex/basic_regex/ctors/char/cstring_grep.cc (test for excess errors)
FAIL: 28_regex/basic_regex/ctors/extended/cstring.cc (test for excess errors)
FAIL: 28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc (test for excess errors)
WARNING: 28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc compilation failed to produce executable

E.g. the first one is

FAIL: 28_regex/algorithms/regex_match/basic/string_01.cc (test for excess errors)
Excess errors:
/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc:34:47: error: call of overloaded 'basic_regex(const char [8], const flag_type&)' is ambiguous

The other failures are similar.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 12:48     ` Rainer Orth
@ 2013-08-08 12:53       ` Paolo Carlini
  2013-08-08 14:04         ` Tim Shen
  2013-08-08 13:20       ` Kyrylo Tkachov
  1 sibling, 1 reply; 22+ messages in thread
From: Paolo Carlini @ 2013-08-08 12:53 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Tim Shen, libstdc++, gcc-patches



Hi,

>I wasn't certain about the right convention.  The following patch
>allowed bootstrap to finish on i386-pc-solaris2.10 and
>x86_64-unknown-linux-gnu.  I'll commit the patch once Solaris testing
>has finished.

Thanks a lot.

>E.g. the first one is
>
>FAIL: 28_regex/algorithms/regex_match/basic/string_01.cc (test for
>excess errors)
>Excess errors:
>/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc:34:47:
>error: call of overloaded 'basic_regex(const char [8], const
>flag_type&)' is ambiguous
>
>The other failures are similar.

Tim, please address this ASAP, otherwise we have to revert the whole thing.

Paolo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [Patch] Whole regex refactoring and current status
  2013-08-08 12:48     ` Rainer Orth
  2013-08-08 12:53       ` Paolo Carlini
@ 2013-08-08 13:20       ` Kyrylo Tkachov
  1 sibling, 0 replies; 22+ messages in thread
From: Kyrylo Tkachov @ 2013-08-08 13:20 UTC (permalink / raw)
  To: 'Rainer Orth', Paolo Carlini; +Cc: Tim Shen, libstdc++, gcc-patches


> Hi Paolo,
> 
> >>This is already documented:
> >>
> >>http://gcc.gnu.org/onlinedocs/libstdc++/manual/source_code_style.html#c
> oding_style.bad_identifiers
> >
> > Indeed. As a simple to remember rule never use single underscore +
> single
> > uppercase. Usually we add a p, like _Cp, etc. Plenty of examples
> > everywhere. At the moment I can't do the search&replace, any such patch
> is
> > preapproved though.
> 
> I wasn't certain about the right convention.  The following patch
> allowed bootstrap to finish on i386-pc-solaris2.10 and
> x86_64-unknown-linux-gnu.  I'll commit the patch once Solaris testing
> has finished.

I can confirm that this patch fixes the arm-none-eabi build as well.

Thanks,
Kyrill



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 12:53       ` Paolo Carlini
@ 2013-08-08 14:04         ` Tim Shen
  2013-08-08 14:23           ` Tim Shen
  0 siblings, 1 reply; 22+ messages in thread
From: Tim Shen @ 2013-08-08 14:04 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Rainer Orth, libstdc++, gcc-patches

On Thu, Aug 8, 2013 at 8:53 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Tim, please address this ASAP, otherwise we have to revert the whole thing.

I'm trying to reproduce the compilation failures.


-- 
Tim Shen

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 14:04         ` Tim Shen
@ 2013-08-08 14:23           ` Tim Shen
  2013-08-08 15:15             ` Paolo Carlini
  0 siblings, 1 reply; 22+ messages in thread
From: Tim Shen @ 2013-08-08 14:23 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Rainer Orth, libstdc++, gcc-patches

On Thu, Aug 8, 2013 at 10:04 PM, Tim Shen <timshen91@gmail.com> wrote:
> On Thu, Aug 8, 2013 at 8:53 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
>> Tim, please address this ASAP, otherwise we have to revert the whole thing.
>
> I'm trying to reproduce the compilation failures.

There's a typedef in regex_constants.h:

`typedef unsigned int syntax_option_type;`

Which is a little bit naive. It possibly conflicts with size_t under
i386 when overloading. I'm trying to change it to a bitset. Or is
there any better solution?


-- 
Tim Shen

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 14:23           ` Tim Shen
@ 2013-08-08 15:15             ` Paolo Carlini
  2013-08-08 15:21               ` Tim Shen
  2013-08-08 15:39               ` Andreas Schwab
  0 siblings, 2 replies; 22+ messages in thread
From: Paolo Carlini @ 2013-08-08 15:15 UTC (permalink / raw)
  To: Tim Shen; +Cc: Rainer Orth, libstdc++, gcc-patches



Hi,

>There's a typedef in regex_constants.h:
>
>`typedef unsigned int syntax_option_type;`
>
>Which is a little bit naive. It possibly conflicts with size_t under
>i386 when overloading. I'm trying to change it to a bitset. Or is
>there any better solution?

In my humble opinion involving the whole std::bitset container for a syntax option is way overkill. Do you really have to do overloading between size_t and that type? Or maybe you can use a type *smaller* than unsigned int.

Paolo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 15:15             ` Paolo Carlini
@ 2013-08-08 15:21               ` Tim Shen
  2013-08-08 16:12                 ` Paolo Carlini
  2013-08-08 15:39               ` Andreas Schwab
  1 sibling, 1 reply; 22+ messages in thread
From: Tim Shen @ 2013-08-08 15:21 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Rainer Orth, libstdc++, gcc-patches

On Thu, Aug 8, 2013 at 11:14 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> In my humble opinion involving the whole std::bitset container for a syntax option is way overkill. Do you really have to do overloading between size_t and that type? Or maybe you can use a type *smaller* than unsigned int.

The n3376 standard specified the following constructor:

...
explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
basic_regex(const charT* p, size_t len, flag_type f =
regex_constants::ECMAScript);
...

So flag_type shall not be the same as size_t. I don't know if when I
switch flag_type from unsigned int to, say, unsigned short, conflicts
will appear in 16bit archtectures.


-- 
Tim Shen

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 15:15             ` Paolo Carlini
  2013-08-08 15:21               ` Tim Shen
@ 2013-08-08 15:39               ` Andreas Schwab
  2013-08-08 16:15                 ` Paolo Carlini
  1 sibling, 1 reply; 22+ messages in thread
From: Andreas Schwab @ 2013-08-08 15:39 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Tim Shen, Rainer Orth, libstdc++, gcc-patches

Paolo Carlini <paolo.carlini@oracle.com> writes:

> In my humble opinion involving the whole std::bitset container for a
> syntax option is way overkill.

It's already used for match_flag_type anyway.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 15:21               ` Tim Shen
@ 2013-08-08 16:12                 ` Paolo Carlini
  0 siblings, 0 replies; 22+ messages in thread
From: Paolo Carlini @ 2013-08-08 16:12 UTC (permalink / raw)
  To: Tim Shen; +Cc: Rainer Orth, libstdc++, gcc-patches



Hi,

>So flag_type shall not be the same as size_t. I don't know if when I
>switch flag_type from unsigned int to, say, unsigned short, conflicts
>will appear in 16bit archtectures.

Well 16-bit archs aren't really supported these days, as long as the c++ runtime is concerned. Thus if unsigned short works let's go with it and move on. In any case, we don't have to make a super final decision, but breaking 32 bit is bad.

In general, I would recommend being careful with adding templated containers, remember that eventually we want to have a lot of code in *.cc files and instantiations will be a big big annoyance.

Paolo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 15:39               ` Andreas Schwab
@ 2013-08-08 16:15                 ` Paolo Carlini
  2013-08-08 16:51                   ` Tim Shen
  0 siblings, 1 reply; 22+ messages in thread
From: Paolo Carlini @ 2013-08-08 16:15 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Tim Shen, Rainer Orth, libstdc++, gcc-patches



Hi,

>> In my humble opinion involving the whole std::bitset container for a
>> syntax option is way overkill.
>
>It's already used for match_flag_type anyway.

Indeed, I noticed it a few days ago, and seemed overkill ;) Really, we already have implementation experience about these flags, eg in iostream, and I dont think we want std::bitset everywhere.

Paolo

Paolo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 16:15                 ` Paolo Carlini
@ 2013-08-08 16:51                   ` Tim Shen
  2013-08-08 17:25                     ` Paolo Carlini
  2013-08-09  5:09                     ` Tim Shen
  0 siblings, 2 replies; 22+ messages in thread
From: Tim Shen @ 2013-08-08 16:51 UTC (permalink / raw)
  To: libstdc++, gcc-patches; +Cc: Paolo Carlini, Andreas Schwab, Rainer Orth

[-- Attachment #1: Type: text/plain, Size: 479 bytes --]

On Fri, Aug 9, 2013 at 12:15 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Indeed, I noticed it a few days ago, and seemed overkill ;) Really, we already have implementation experience about these flags, eg in iostream, and I dont think we want std::bitset everywhere.

So here's the change. It's under testing now, but could took several
hours. If someone has a faster machine, please tell the result :)

As a simple test, `g++ -m32 test.cc` didn't fail.


-- 
Tim Shen

[-- Attachment #2: a.patch --]
[-- Type: application/octet-stream, Size: 501 bytes --]

Index: include/bits/regex_constants.h
===================================================================
--- include/bits/regex_constants.h	(revision 201603)
+++ include/bits/regex_constants.h	(working copy)
@@ -77,7 +77,7 @@
    * elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep
    * %set.
    */
-  typedef unsigned int syntax_option_type;
+  typedef unsigned short syntax_option_type;
 
   /**
    * Specifies that the matching of regular expressions against a character

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 16:51                   ` Tim Shen
@ 2013-08-08 17:25                     ` Paolo Carlini
  2013-08-09  5:09                     ` Tim Shen
  1 sibling, 0 replies; 22+ messages in thread
From: Paolo Carlini @ 2013-08-08 17:25 UTC (permalink / raw)
  To: Tim Shen; +Cc: libstdc++, gcc-patches, Andreas Schwab, Rainer Orth

On 08/08/2013 06:51 PM, Tim Shen wrote:
> On Fri, Aug 9, 2013 at 12:15 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
>> Indeed, I noticed it a few days ago, and seemed overkill ;) Really, we already have implementation experience about these flags, eg in iostream, and I dont think we want std::bitset everywhere.
> So here's the change. It's under testing now, but could took several
> hours. If someone has a faster machine, please tell the result :)
>
> As a simple test, `g++ -m32 test.cc` didn't fail.
Thanks!

Paolo.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-08 16:51                   ` Tim Shen
  2013-08-08 17:25                     ` Paolo Carlini
@ 2013-08-09  5:09                     ` Tim Shen
  2013-08-09  7:00                       ` Paolo Carlini
  1 sibling, 1 reply; 22+ messages in thread
From: Tim Shen @ 2013-08-09  5:09 UTC (permalink / raw)
  To: libstdc++, gcc-patches; +Cc: Paolo Carlini, Andreas Schwab, Rainer Orth

[-- Attachment #1: Type: text/plain, Size: 611 bytes --]

On Fri, Aug 9, 2013 at 12:51 AM, Tim Shen <timshen91@gmail.com> wrote:
> So here's the change. It's under testing now, but could took several
> hours. If someone has a faster machine, please tell the result :)

Unfortuantely using `unsigned int => unsigned short` cannot work.
Instead, I create a enum and do some operator overloadings.

This patch passed bootstrap and all tests under the configuration under x86_64:

--with-arch=corei7 --with-cpu=corei7 --prefix=/usr/local
--enable-clocale=gnu --with-system-zlib --enable-shared
--with-demangler-in-ld --with-fpmath=sse --enable-languages=c++


-- 
Tim Shen

[-- Attachment #2: a.patch --]
[-- Type: application/octet-stream, Size: 8747 bytes --]

Index: libstdc++-v3/include/bits/regex_constants.h
===================================================================
--- libstdc++-v3/include/bits/regex_constants.h	(revision 201603)
+++ libstdc++-v3/include/bits/regex_constants.h	(working copy)
@@ -77,88 +77,126 @@
    * elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep
    * %set.
    */
-  typedef unsigned int syntax_option_type;
+  enum syntax_option_type
+    {
+      /**
+       * Specifies that the matching of regular expressions against a character
+       * sequence shall be performed without regard to case.
+       */
+      icase      = 1 << _S_icase,
 
-  /**
-   * Specifies that the matching of regular expressions against a character
-   * sequence shall be performed without regard to case.
-   */
-  constexpr 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.
+       */
+      nosubs     = 1 << _S_nosubs,
 
-  /**
-   * 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.
-   */
-  constexpr 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.
+       */
+      optimize   = 1 << _S_optimize,
 
-  /**
-   * 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.
-   */
-  constexpr syntax_option_type optimize   = 1 << _S_optimize;
+      /**
+       * Specifies that character ranges of the form [a-b] should be locale
+       * sensitive.
+       */
+      collate    = 1 << _S_collate,
 
-  /**
-   * Specifies that character ranges of the form [a-b] should be locale
-   * sensitive.
-   */
-  constexpr 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 section [28.13].  This grammar is similar to that defined
+       * in the PERL scripting language but extended with elements found in the
+       * POSIX regular expression grammar.
+       */
+      ECMAScript = 1 << _S_ECMAScript,
 
-  /**
-   * 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 section [28.13].  This grammar is similar to that defined
-   * in the PERL scripting language but extended with elements found in the
-   * POSIX regular expression grammar.
-   */
-  constexpr 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].
+       */
+      basic      = 1 << _S_basic,
 
-  /**
-   * 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].
-   */
-  constexpr 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.
+       */
+      extended   = 1 << _S_extended,
 
-  /**
-   * 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.
-   */
-  constexpr 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).
+       */
+      awk        = 1 << _S_awk,
 
-  /**
-   * 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).
-   */
-  constexpr 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.
+       */
+      grep       = 1 << _S_grep,
 
-  /**
-   * 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.
-   */
-  constexpr 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.
+       */
+      egrep      = 1 << _S_egrep,
+    };
 
-  /**
-   * 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.
-   */
-  constexpr syntax_option_type egrep      = 1 << _S_egrep;
+  constexpr inline syntax_option_type
+  operator&(syntax_option_type __a, syntax_option_type __b)
+  {
+    return (syntax_option_type)(static_cast<unsigned int>(__a)
+                                & static_cast<unsigned int>(__b));
+  }
 
+  constexpr inline syntax_option_type
+  operator|(syntax_option_type __a, syntax_option_type __b)
+  {
+    return (syntax_option_type)(static_cast<unsigned int>(__a)
+                                | static_cast<unsigned int>(__b));
+  }
+
+  constexpr inline syntax_option_type
+  operator^(syntax_option_type __a, syntax_option_type __b)
+  {
+    return (syntax_option_type)(static_cast<unsigned int>(__a)
+                                ^ static_cast<unsigned int>(__b));
+  }
+
+  constexpr inline syntax_option_type
+  operator~(syntax_option_type __a)
+  { return (syntax_option_type)(~static_cast<unsigned int>(__a)); }
+
+  inline syntax_option_type&
+  operator&=(syntax_option_type& __a, syntax_option_type __b)
+  { return __a = __a & __b; }
+
+  inline syntax_option_type&
+  operator|=(syntax_option_type& __a, syntax_option_type __b)
+  { return __a = __a | __b; }
+
+  inline syntax_option_type&
+  operator^=(syntax_option_type& __a, syntax_option_type __b)
+  { return __a = __a ^ __b; }
+
   //@}
 
   /**

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-09  5:09                     ` Tim Shen
@ 2013-08-09  7:00                       ` Paolo Carlini
  2013-08-09  7:57                         ` Tim Shen
  0 siblings, 1 reply; 22+ messages in thread
From: Paolo Carlini @ 2013-08-09  7:00 UTC (permalink / raw)
  To: Tim Shen; +Cc: libstdc++, gcc-patches, Andreas Schwab, Rainer Orth

Hi,

On 08/09/2013 07:08 AM, Tim Shen wrote:
> On Fri, Aug 9, 2013 at 12:51 AM, Tim Shen <timshen91@gmail.com> wrote:
>> So here's the change. It's under testing now, but could took several
>> hours. If someone has a faster machine, please tell the result :)
> Unfortuantely using `unsigned int => unsigned short` cannot work.
> Instead, I create a enum and do some operator overloadings.
>
> This patch passed bootstrap and all tests under the configuration under x86_64:
>
> --with-arch=corei7 --with-cpu=corei7 --prefix=/usr/local
> --enable-clocale=gnu --with-system-zlib --enable-shared
> --with-demangler-in-ld --with-fpmath=sse --enable-languages=c++
Yes, if, as it should, it works on -m32 too, let's go with this. By the 
way, you didn't say how exactly you are testing?!? Because just make 
check doesn't test -m32. I use, something like:

make -k check-target-libstdc++-v3 
RUNTESTFLAGS="--target_board='unix/\{-m32,-m64\}'"

for sure there are other ways to obtain the same result.

Paolo.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-09  7:00                       ` Paolo Carlini
@ 2013-08-09  7:57                         ` Tim Shen
  2013-08-09 11:37                           ` Rainer Orth
  0 siblings, 1 reply; 22+ messages in thread
From: Tim Shen @ 2013-08-09  7:57 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: libstdc++, gcc-patches, Andreas Schwab, Rainer Orth

On Fri, Aug 9, 2013 at 2:59 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Yes, if, as it should, it works on -m32 too, let's go with this. By the way,
> you didn't say how exactly you are testing?!? Because just make check
> doesn't test -m32. I use, something like:
>
> make -k check-target-libstdc++-v3
> RUNTESTFLAGS="--target_board='unix/\{-m32,-m64\}'"
>
> for sure there are other ways to obtain the same result.

Committed.

I entered `gcc-build/x86_64-unknown-linux-gnu/32/libstdc++-v3` then
run `make check`. I see -m32 in test log.


-- 
Tim Shen

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Patch] Whole regex refactoring and current status
  2013-08-09  7:57                         ` Tim Shen
@ 2013-08-09 11:37                           ` Rainer Orth
  0 siblings, 0 replies; 22+ messages in thread
From: Rainer Orth @ 2013-08-09 11:37 UTC (permalink / raw)
  To: Tim Shen; +Cc: Paolo Carlini, libstdc++, gcc-patches, Andreas Schwab

Tim Shen <timshen91@gmail.com> writes:

> On Fri, Aug 9, 2013 at 2:59 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
>> Yes, if, as it should, it works on -m32 too, let's go with this. By the way,
>> you didn't say how exactly you are testing?!? Because just make check
>> doesn't test -m32. I use, something like:
>>
>> make -k check-target-libstdc++-v3
>> RUNTESTFLAGS="--target_board='unix/\{-m32,-m64\}'"
>>
>> for sure there are other ways to obtain the same result.
>
> Committed.
>
> I entered `gcc-build/x86_64-unknown-linux-gnu/32/libstdc++-v3` then
> run `make check`. I see -m32 in test log.

As expected, i386-pc-solaris2.10 testsuite results are back to normal
now.

Thanks.
        Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2013-08-09 11:37 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-05 17:05 [Patch] Whole regex refactoring and current status Tim Shen
     [not found] ` <52001184.5020707@oracle.com>
2013-08-06  1:21   ` Tim Shen
     [not found]     ` <87txj35v5n.fsf@fencepost.gnu.org>
     [not found]       ` <5200C326.8030300@oracle.com>
     [not found]         ` <CAPrifDkBTkBrdpQrE6caD_X6pmbApEW5B42_AadqThNbJ+HqCg@mail.gmail.com>
     [not found]           ` <52011EA2.3070703@oracle.com>
2013-08-08  0:18             ` Tim Shen
2013-08-08 10:01 ` Rainer Orth
2013-08-08 10:25   ` Kyrylo Tkachov
2013-08-08 10:26   ` Paolo Carlini
2013-08-08 12:48     ` Rainer Orth
2013-08-08 12:53       ` Paolo Carlini
2013-08-08 14:04         ` Tim Shen
2013-08-08 14:23           ` Tim Shen
2013-08-08 15:15             ` Paolo Carlini
2013-08-08 15:21               ` Tim Shen
2013-08-08 16:12                 ` Paolo Carlini
2013-08-08 15:39               ` Andreas Schwab
2013-08-08 16:15                 ` Paolo Carlini
2013-08-08 16:51                   ` Tim Shen
2013-08-08 17:25                     ` Paolo Carlini
2013-08-09  5:09                     ` Tim Shen
2013-08-09  7:00                       ` Paolo Carlini
2013-08-09  7:57                         ` Tim Shen
2013-08-09 11:37                           ` Rainer Orth
2013-08-08 13:20       ` Kyrylo Tkachov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).