xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/regex.tcc (revision 23f5f46327e37e7811da3520f4bb933f9489322f)
11debfc3dSmrg // class template regex -*- C++ -*-
21debfc3dSmrg 
38feb0f0bSmrg // Copyright (C) 2013-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /**
261debfc3dSmrg  *  @file bits/regex.tcc
271debfc3dSmrg  *  This is an internal header file, included by other library headers.
281debfc3dSmrg  *  Do not attempt to use it directly. @headername{regex}
291debfc3dSmrg  */
301debfc3dSmrg 
311debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
321debfc3dSmrg {
331debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
341debfc3dSmrg 
35a2dc1f3fSmrg namespace __detail
36a2dc1f3fSmrg {
378feb0f0bSmrg   /// @cond undocumented
388feb0f0bSmrg 
391debfc3dSmrg   // Result of merging regex_match and regex_search.
401debfc3dSmrg   //
411debfc3dSmrg   // __policy now can be _S_auto (auto dispatch) and _S_alternate (use
421debfc3dSmrg   // the other one if possible, for test purpose).
431debfc3dSmrg   //
441debfc3dSmrg   // That __match_mode is true means regex_match, else regex_search.
451debfc3dSmrg   template<typename _BiIter, typename _Alloc,
461debfc3dSmrg 	   typename _CharT, typename _TraitsT,
471debfc3dSmrg 	   _RegexExecutorPolicy __policy,
481debfc3dSmrg 	   bool __match_mode>
491debfc3dSmrg     bool
__regex_algo_impl(_BiIter __s,_BiIter __e,match_results<_BiIter,_Alloc> & __m,const basic_regex<_CharT,_TraitsT> & __re,regex_constants::match_flag_type __flags)501debfc3dSmrg     __regex_algo_impl(_BiIter                              __s,
511debfc3dSmrg 		      _BiIter                              __e,
521debfc3dSmrg 		      match_results<_BiIter, _Alloc>&      __m,
531debfc3dSmrg 		      const basic_regex<_CharT, _TraitsT>& __re,
541debfc3dSmrg 		      regex_constants::match_flag_type     __flags)
551debfc3dSmrg     {
561debfc3dSmrg       if (__re._M_automaton == nullptr)
571debfc3dSmrg 	return false;
581debfc3dSmrg 
591debfc3dSmrg       typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
601debfc3dSmrg       __m._M_begin = __s;
611debfc3dSmrg       __m._M_resize(__re._M_automaton->_M_sub_count());
621debfc3dSmrg 
631debfc3dSmrg       bool __ret;
641debfc3dSmrg       if ((__re.flags() & regex_constants::__polynomial)
651debfc3dSmrg 	  || (__policy == _RegexExecutorPolicy::_S_alternate
661debfc3dSmrg 	      && !__re._M_automaton->_M_has_backref))
671debfc3dSmrg 	{
681debfc3dSmrg 	  _Executor<_BiIter, _Alloc, _TraitsT, false>
691debfc3dSmrg 	    __executor(__s, __e, __m, __re, __flags);
701debfc3dSmrg 	  if (__match_mode)
711debfc3dSmrg 	    __ret = __executor._M_match();
721debfc3dSmrg 	  else
731debfc3dSmrg 	    __ret = __executor._M_search();
741debfc3dSmrg 	}
751debfc3dSmrg       else
761debfc3dSmrg 	{
771debfc3dSmrg 	  _Executor<_BiIter, _Alloc, _TraitsT, true>
781debfc3dSmrg 	    __executor(__s, __e, __m, __re, __flags);
791debfc3dSmrg 	  if (__match_mode)
801debfc3dSmrg 	    __ret = __executor._M_match();
811debfc3dSmrg 	  else
821debfc3dSmrg 	    __ret = __executor._M_search();
831debfc3dSmrg 	}
841debfc3dSmrg       if (__ret)
851debfc3dSmrg 	{
861debfc3dSmrg 	  for (auto& __it : __res)
871debfc3dSmrg 	    if (!__it.matched)
881debfc3dSmrg 	      __it.first = __it.second = __e;
891debfc3dSmrg 	  auto& __pre = __m._M_prefix();
901debfc3dSmrg 	  auto& __suf = __m._M_suffix();
911debfc3dSmrg 	  if (__match_mode)
921debfc3dSmrg 	    {
931debfc3dSmrg 	      __pre.matched = false;
941debfc3dSmrg 	      __pre.first = __s;
951debfc3dSmrg 	      __pre.second = __s;
961debfc3dSmrg 	      __suf.matched = false;
971debfc3dSmrg 	      __suf.first = __e;
981debfc3dSmrg 	      __suf.second = __e;
991debfc3dSmrg 	    }
1001debfc3dSmrg 	  else
1011debfc3dSmrg 	    {
1021debfc3dSmrg 	      __pre.first = __s;
1031debfc3dSmrg 	      __pre.second = __res[0].first;
1041debfc3dSmrg 	      __pre.matched = (__pre.first != __pre.second);
1051debfc3dSmrg 	      __suf.first = __res[0].second;
1061debfc3dSmrg 	      __suf.second = __e;
1071debfc3dSmrg 	      __suf.matched = (__suf.first != __suf.second);
1081debfc3dSmrg 	    }
1091debfc3dSmrg 	}
1101debfc3dSmrg       else
1111debfc3dSmrg 	{
1128feb0f0bSmrg 	  __m._M_establish_failed_match(__e);
1131debfc3dSmrg 	}
1141debfc3dSmrg       return __ret;
1151debfc3dSmrg     }
1168feb0f0bSmrg   /// @endcond
1178feb0f0bSmrg } // namespace __detail
1188feb0f0bSmrg 
1198feb0f0bSmrg   /// @cond
1201debfc3dSmrg 
1211debfc3dSmrg   template<typename _Ch_type>
1221debfc3dSmrg   template<typename _Fwd_iter>
1231debfc3dSmrg     typename regex_traits<_Ch_type>::string_type
1241debfc3dSmrg     regex_traits<_Ch_type>::
lookup_collatename(_Fwd_iter __first,_Fwd_iter __last) const1251debfc3dSmrg     lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
1261debfc3dSmrg     {
1271debfc3dSmrg       typedef std::ctype<char_type> __ctype_type;
1281debfc3dSmrg       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
1291debfc3dSmrg 
1301debfc3dSmrg       static const char* __collatenames[] =
1311debfc3dSmrg 	{
1321debfc3dSmrg 	  "NUL",
1331debfc3dSmrg 	  "SOH",
1341debfc3dSmrg 	  "STX",
1351debfc3dSmrg 	  "ETX",
1361debfc3dSmrg 	  "EOT",
1371debfc3dSmrg 	  "ENQ",
1381debfc3dSmrg 	  "ACK",
1391debfc3dSmrg 	  "alert",
1401debfc3dSmrg 	  "backspace",
1411debfc3dSmrg 	  "tab",
1421debfc3dSmrg 	  "newline",
1431debfc3dSmrg 	  "vertical-tab",
1441debfc3dSmrg 	  "form-feed",
1451debfc3dSmrg 	  "carriage-return",
1461debfc3dSmrg 	  "SO",
1471debfc3dSmrg 	  "SI",
1481debfc3dSmrg 	  "DLE",
1491debfc3dSmrg 	  "DC1",
1501debfc3dSmrg 	  "DC2",
1511debfc3dSmrg 	  "DC3",
1521debfc3dSmrg 	  "DC4",
1531debfc3dSmrg 	  "NAK",
1541debfc3dSmrg 	  "SYN",
1551debfc3dSmrg 	  "ETB",
1561debfc3dSmrg 	  "CAN",
1571debfc3dSmrg 	  "EM",
1581debfc3dSmrg 	  "SUB",
1591debfc3dSmrg 	  "ESC",
1601debfc3dSmrg 	  "IS4",
1611debfc3dSmrg 	  "IS3",
1621debfc3dSmrg 	  "IS2",
1631debfc3dSmrg 	  "IS1",
1641debfc3dSmrg 	  "space",
1651debfc3dSmrg 	  "exclamation-mark",
1661debfc3dSmrg 	  "quotation-mark",
1671debfc3dSmrg 	  "number-sign",
1681debfc3dSmrg 	  "dollar-sign",
1691debfc3dSmrg 	  "percent-sign",
1701debfc3dSmrg 	  "ampersand",
1711debfc3dSmrg 	  "apostrophe",
1721debfc3dSmrg 	  "left-parenthesis",
1731debfc3dSmrg 	  "right-parenthesis",
1741debfc3dSmrg 	  "asterisk",
1751debfc3dSmrg 	  "plus-sign",
1761debfc3dSmrg 	  "comma",
1771debfc3dSmrg 	  "hyphen",
1781debfc3dSmrg 	  "period",
1791debfc3dSmrg 	  "slash",
1801debfc3dSmrg 	  "zero",
1811debfc3dSmrg 	  "one",
1821debfc3dSmrg 	  "two",
1831debfc3dSmrg 	  "three",
1841debfc3dSmrg 	  "four",
1851debfc3dSmrg 	  "five",
1861debfc3dSmrg 	  "six",
1871debfc3dSmrg 	  "seven",
1881debfc3dSmrg 	  "eight",
1891debfc3dSmrg 	  "nine",
1901debfc3dSmrg 	  "colon",
1911debfc3dSmrg 	  "semicolon",
1921debfc3dSmrg 	  "less-than-sign",
1931debfc3dSmrg 	  "equals-sign",
1941debfc3dSmrg 	  "greater-than-sign",
1951debfc3dSmrg 	  "question-mark",
1961debfc3dSmrg 	  "commercial-at",
1971debfc3dSmrg 	  "A",
1981debfc3dSmrg 	  "B",
1991debfc3dSmrg 	  "C",
2001debfc3dSmrg 	  "D",
2011debfc3dSmrg 	  "E",
2021debfc3dSmrg 	  "F",
2031debfc3dSmrg 	  "G",
2041debfc3dSmrg 	  "H",
2051debfc3dSmrg 	  "I",
2061debfc3dSmrg 	  "J",
2071debfc3dSmrg 	  "K",
2081debfc3dSmrg 	  "L",
2091debfc3dSmrg 	  "M",
2101debfc3dSmrg 	  "N",
2111debfc3dSmrg 	  "O",
2121debfc3dSmrg 	  "P",
2131debfc3dSmrg 	  "Q",
2141debfc3dSmrg 	  "R",
2151debfc3dSmrg 	  "S",
2161debfc3dSmrg 	  "T",
2171debfc3dSmrg 	  "U",
2181debfc3dSmrg 	  "V",
2191debfc3dSmrg 	  "W",
2201debfc3dSmrg 	  "X",
2211debfc3dSmrg 	  "Y",
2221debfc3dSmrg 	  "Z",
2231debfc3dSmrg 	  "left-square-bracket",
2241debfc3dSmrg 	  "backslash",
2251debfc3dSmrg 	  "right-square-bracket",
2261debfc3dSmrg 	  "circumflex",
2271debfc3dSmrg 	  "underscore",
2281debfc3dSmrg 	  "grave-accent",
2291debfc3dSmrg 	  "a",
2301debfc3dSmrg 	  "b",
2311debfc3dSmrg 	  "c",
2321debfc3dSmrg 	  "d",
2331debfc3dSmrg 	  "e",
2341debfc3dSmrg 	  "f",
2351debfc3dSmrg 	  "g",
2361debfc3dSmrg 	  "h",
2371debfc3dSmrg 	  "i",
2381debfc3dSmrg 	  "j",
2391debfc3dSmrg 	  "k",
2401debfc3dSmrg 	  "l",
2411debfc3dSmrg 	  "m",
2421debfc3dSmrg 	  "n",
2431debfc3dSmrg 	  "o",
2441debfc3dSmrg 	  "p",
2451debfc3dSmrg 	  "q",
2461debfc3dSmrg 	  "r",
2471debfc3dSmrg 	  "s",
2481debfc3dSmrg 	  "t",
2491debfc3dSmrg 	  "u",
2501debfc3dSmrg 	  "v",
2511debfc3dSmrg 	  "w",
2521debfc3dSmrg 	  "x",
2531debfc3dSmrg 	  "y",
2541debfc3dSmrg 	  "z",
2551debfc3dSmrg 	  "left-curly-bracket",
2561debfc3dSmrg 	  "vertical-line",
2571debfc3dSmrg 	  "right-curly-bracket",
2581debfc3dSmrg 	  "tilde",
2591debfc3dSmrg 	  "DEL",
2601debfc3dSmrg 	};
2611debfc3dSmrg 
2621debfc3dSmrg       string __s;
2631debfc3dSmrg       for (; __first != __last; ++__first)
2641debfc3dSmrg 	__s += __fctyp.narrow(*__first, 0);
2651debfc3dSmrg 
2661debfc3dSmrg       for (const auto& __it : __collatenames)
2671debfc3dSmrg 	if (__s == __it)
2681debfc3dSmrg 	  return string_type(1, __fctyp.widen(
2691debfc3dSmrg 	    static_cast<char>(&__it - __collatenames)));
2701debfc3dSmrg 
2711debfc3dSmrg       // TODO Add digraph support:
2721debfc3dSmrg       // http://boost.sourceforge.net/libs/regex/doc/collating_names.html
2731debfc3dSmrg 
2741debfc3dSmrg       return string_type();
2751debfc3dSmrg     }
2761debfc3dSmrg 
2771debfc3dSmrg   template<typename _Ch_type>
2781debfc3dSmrg   template<typename _Fwd_iter>
2791debfc3dSmrg     typename regex_traits<_Ch_type>::char_class_type
2801debfc3dSmrg     regex_traits<_Ch_type>::
lookup_classname(_Fwd_iter __first,_Fwd_iter __last,bool __icase) const2811debfc3dSmrg     lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const
2821debfc3dSmrg     {
2831debfc3dSmrg       typedef std::ctype<char_type> __ctype_type;
2841debfc3dSmrg       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
2851debfc3dSmrg 
2861debfc3dSmrg       // Mappings from class name to class mask.
2871debfc3dSmrg       static const pair<const char*, char_class_type> __classnames[] =
2881debfc3dSmrg       {
2891debfc3dSmrg 	{"d", ctype_base::digit},
2901debfc3dSmrg 	{"w", {ctype_base::alnum, _RegexMask::_S_under}},
2911debfc3dSmrg 	{"s", ctype_base::space},
2921debfc3dSmrg 	{"alnum", ctype_base::alnum},
2931debfc3dSmrg 	{"alpha", ctype_base::alpha},
2941debfc3dSmrg 	{"blank", ctype_base::blank},
2951debfc3dSmrg 	{"cntrl", ctype_base::cntrl},
2961debfc3dSmrg 	{"digit", ctype_base::digit},
2971debfc3dSmrg 	{"graph", ctype_base::graph},
2981debfc3dSmrg 	{"lower", ctype_base::lower},
2991debfc3dSmrg 	{"print", ctype_base::print},
3001debfc3dSmrg 	{"punct", ctype_base::punct},
3011debfc3dSmrg 	{"space", ctype_base::space},
3021debfc3dSmrg 	{"upper", ctype_base::upper},
3031debfc3dSmrg 	{"xdigit", ctype_base::xdigit},
3041debfc3dSmrg       };
3051debfc3dSmrg 
3061debfc3dSmrg       string __s;
3071debfc3dSmrg       for (; __first != __last; ++__first)
3081debfc3dSmrg 	__s += __fctyp.narrow(__fctyp.tolower(*__first), 0);
3091debfc3dSmrg 
3101debfc3dSmrg       for (const auto& __it : __classnames)
3111debfc3dSmrg 	if (__s == __it.first)
3121debfc3dSmrg 	  {
3131debfc3dSmrg 	    if (__icase
3141debfc3dSmrg 		&& ((__it.second
3151debfc3dSmrg 		     & (ctype_base::lower | ctype_base::upper)) != 0))
3161debfc3dSmrg 	      return ctype_base::alpha;
3171debfc3dSmrg 	    return __it.second;
3181debfc3dSmrg 	  }
3191debfc3dSmrg       return 0;
3201debfc3dSmrg     }
3211debfc3dSmrg 
3221debfc3dSmrg   template<typename _Ch_type>
3231debfc3dSmrg     bool
3241debfc3dSmrg     regex_traits<_Ch_type>::
isctype(_Ch_type __c,char_class_type __f) const3251debfc3dSmrg     isctype(_Ch_type __c, char_class_type __f) const
3261debfc3dSmrg     {
3271debfc3dSmrg       typedef std::ctype<char_type> __ctype_type;
3281debfc3dSmrg       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
3291debfc3dSmrg 
3301debfc3dSmrg       return __fctyp.is(__f._M_base, __c)
3311debfc3dSmrg 	// [[:w:]]
3321debfc3dSmrg 	|| ((__f._M_extended & _RegexMask::_S_under)
3331debfc3dSmrg 	    && __c == __fctyp.widen('_'));
3341debfc3dSmrg     }
3351debfc3dSmrg 
3361debfc3dSmrg   template<typename _Ch_type>
3371debfc3dSmrg     int
3381debfc3dSmrg     regex_traits<_Ch_type>::
value(_Ch_type __ch,int __radix) const3391debfc3dSmrg     value(_Ch_type __ch, int __radix) const
3401debfc3dSmrg     {
3411debfc3dSmrg       std::basic_istringstream<char_type> __is(string_type(1, __ch));
3421debfc3dSmrg       long __v;
3431debfc3dSmrg       if (__radix == 8)
3441debfc3dSmrg 	__is >> std::oct;
3451debfc3dSmrg       else if (__radix == 16)
3461debfc3dSmrg 	__is >> std::hex;
3471debfc3dSmrg       __is >> __v;
3481debfc3dSmrg       return __is.fail() ? -1 : __v;
3491debfc3dSmrg     }
3501debfc3dSmrg 
3511debfc3dSmrg   template<typename _Bi_iter, typename _Alloc>
3521debfc3dSmrg   template<typename _Out_iter>
3538feb0f0bSmrg     _Out_iter
3548feb0f0bSmrg     match_results<_Bi_iter, _Alloc>::
format(_Out_iter __out,const match_results<_Bi_iter,_Alloc>::char_type * __fmt_first,const match_results<_Bi_iter,_Alloc>::char_type * __fmt_last,match_flag_type __flags) const3551debfc3dSmrg     format(_Out_iter __out,
3561debfc3dSmrg 	   const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first,
3571debfc3dSmrg 	   const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last,
3581debfc3dSmrg 	   match_flag_type __flags) const
3591debfc3dSmrg     {
3601debfc3dSmrg       __glibcxx_assert( ready() );
3611debfc3dSmrg       regex_traits<char_type> __traits;
3621debfc3dSmrg       typedef std::ctype<char_type> __ctype_type;
3631debfc3dSmrg       const __ctype_type&
3641debfc3dSmrg 	__fctyp(use_facet<__ctype_type>(__traits.getloc()));
3651debfc3dSmrg 
3661debfc3dSmrg       auto __output = [&](size_t __idx)
3671debfc3dSmrg 	{
3681debfc3dSmrg 	  auto& __sub = (*this)[__idx];
3691debfc3dSmrg 	  if (__sub.matched)
3701debfc3dSmrg 	    __out = std::copy(__sub.first, __sub.second, __out);
3711debfc3dSmrg 	};
3721debfc3dSmrg 
3731debfc3dSmrg       if (__flags & regex_constants::format_sed)
3741debfc3dSmrg 	{
375a2dc1f3fSmrg 	  bool __escaping = false;
376a2dc1f3fSmrg 	  for (; __fmt_first != __fmt_last; __fmt_first++)
377a2dc1f3fSmrg 	    {
378a2dc1f3fSmrg 	      if (__escaping)
379a2dc1f3fSmrg 		{
380a2dc1f3fSmrg 		  __escaping = false;
381a2dc1f3fSmrg 		  if (__fctyp.is(__ctype_type::digit, *__fmt_first))
382a2dc1f3fSmrg 		    __output(__traits.value(*__fmt_first, 10));
383a2dc1f3fSmrg 		  else
384a2dc1f3fSmrg 		    *__out++ = *__fmt_first;
385a2dc1f3fSmrg 		  continue;
386a2dc1f3fSmrg 		}
387a2dc1f3fSmrg 	      if (*__fmt_first == '\\')
388a2dc1f3fSmrg 		{
389a2dc1f3fSmrg 		  __escaping = true;
390a2dc1f3fSmrg 		  continue;
391a2dc1f3fSmrg 		}
3921debfc3dSmrg 	      if (*__fmt_first == '&')
3931debfc3dSmrg 		{
3941debfc3dSmrg 		  __output(0);
395a2dc1f3fSmrg 		  continue;
3961debfc3dSmrg 		}
397a2dc1f3fSmrg 	      *__out++ = *__fmt_first;
398a2dc1f3fSmrg 	    }
399a2dc1f3fSmrg 	  if (__escaping)
4001debfc3dSmrg 	    *__out++ = '\\';
4011debfc3dSmrg 	}
4021debfc3dSmrg       else
4031debfc3dSmrg 	{
4041debfc3dSmrg 	  while (1)
4051debfc3dSmrg 	    {
4061debfc3dSmrg 	      auto __next = std::find(__fmt_first, __fmt_last, '$');
4071debfc3dSmrg 	      if (__next == __fmt_last)
4081debfc3dSmrg 		break;
4091debfc3dSmrg 
4101debfc3dSmrg 	      __out = std::copy(__fmt_first, __next, __out);
4111debfc3dSmrg 
4121debfc3dSmrg 	      auto __eat = [&](char __ch) -> bool
4131debfc3dSmrg 		{
4141debfc3dSmrg 		  if (*__next == __ch)
4151debfc3dSmrg 		    {
4161debfc3dSmrg 		      ++__next;
4171debfc3dSmrg 		      return true;
4181debfc3dSmrg 		    }
4191debfc3dSmrg 		  return false;
4201debfc3dSmrg 		};
4211debfc3dSmrg 
4221debfc3dSmrg 	      if (++__next == __fmt_last)
4231debfc3dSmrg 		*__out++ = '$';
4241debfc3dSmrg 	      else if (__eat('$'))
4251debfc3dSmrg 		*__out++ = '$';
4261debfc3dSmrg 	      else if (__eat('&'))
4271debfc3dSmrg 		__output(0);
4281debfc3dSmrg 	      else if (__eat('`'))
4291debfc3dSmrg 		{
4301debfc3dSmrg 		  auto& __sub = _M_prefix();
4311debfc3dSmrg 		  if (__sub.matched)
4321debfc3dSmrg 		    __out = std::copy(__sub.first, __sub.second, __out);
4331debfc3dSmrg 		}
4341debfc3dSmrg 	      else if (__eat('\''))
4351debfc3dSmrg 		{
4361debfc3dSmrg 		  auto& __sub = _M_suffix();
4371debfc3dSmrg 		  if (__sub.matched)
4381debfc3dSmrg 		    __out = std::copy(__sub.first, __sub.second, __out);
4391debfc3dSmrg 		}
4401debfc3dSmrg 	      else if (__fctyp.is(__ctype_type::digit, *__next))
4411debfc3dSmrg 		{
4421debfc3dSmrg 		  long __num = __traits.value(*__next, 10);
4431debfc3dSmrg 		  if (++__next != __fmt_last
4441debfc3dSmrg 		      && __fctyp.is(__ctype_type::digit, *__next))
4451debfc3dSmrg 		    {
4461debfc3dSmrg 		      __num *= 10;
4471debfc3dSmrg 		      __num += __traits.value(*__next++, 10);
4481debfc3dSmrg 		    }
4491debfc3dSmrg 		  if (0 <= __num && __num < this->size())
4501debfc3dSmrg 		    __output(__num);
4511debfc3dSmrg 		}
4521debfc3dSmrg 	      else
4531debfc3dSmrg 		*__out++ = '$';
4541debfc3dSmrg 	      __fmt_first = __next;
4551debfc3dSmrg 	    }
4561debfc3dSmrg 	  __out = std::copy(__fmt_first, __fmt_last, __out);
4571debfc3dSmrg 	}
4581debfc3dSmrg       return __out;
4591debfc3dSmrg     }
4601debfc3dSmrg 
4611debfc3dSmrg   template<typename _Out_iter, typename _Bi_iter,
4621debfc3dSmrg 	   typename _Rx_traits, typename _Ch_type>
4631debfc3dSmrg     _Out_iter
__regex_replace(_Out_iter __out,_Bi_iter __first,_Bi_iter __last,const basic_regex<_Ch_type,_Rx_traits> & __e,const _Ch_type * __fmt,size_t __len,regex_constants::match_flag_type __flags)464*23f5f463Smrg     __regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
4651debfc3dSmrg 		    const basic_regex<_Ch_type, _Rx_traits>& __e,
466*23f5f463Smrg 		    const _Ch_type* __fmt, size_t __len,
4671debfc3dSmrg 		    regex_constants::match_flag_type __flags)
4681debfc3dSmrg     {
4691debfc3dSmrg       typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT;
4701debfc3dSmrg       _IterT __i(__first, __last, __e, __flags);
4711debfc3dSmrg       _IterT __end;
4721debfc3dSmrg       if (__i == __end)
4731debfc3dSmrg 	{
4741debfc3dSmrg 	  if (!(__flags & regex_constants::format_no_copy))
4751debfc3dSmrg 	    __out = std::copy(__first, __last, __out);
4761debfc3dSmrg 	}
4771debfc3dSmrg       else
4781debfc3dSmrg 	{
4791debfc3dSmrg 	  sub_match<_Bi_iter> __last;
4801debfc3dSmrg 	  for (; __i != __end; ++__i)
4811debfc3dSmrg 	    {
4821debfc3dSmrg 	      if (!(__flags & regex_constants::format_no_copy))
4831debfc3dSmrg 		__out = std::copy(__i->prefix().first, __i->prefix().second,
4841debfc3dSmrg 				  __out);
4851debfc3dSmrg 	      __out = __i->format(__out, __fmt, __fmt + __len, __flags);
4861debfc3dSmrg 	      __last = __i->suffix();
4871debfc3dSmrg 	      if (__flags & regex_constants::format_first_only)
4881debfc3dSmrg 		break;
4891debfc3dSmrg 	    }
4901debfc3dSmrg 	  if (!(__flags & regex_constants::format_no_copy))
4911debfc3dSmrg 	    __out = std::copy(__last.first, __last.second, __out);
4921debfc3dSmrg 	}
4931debfc3dSmrg       return __out;
4941debfc3dSmrg     }
4951debfc3dSmrg 
4961debfc3dSmrg   template<typename _Bi_iter,
4971debfc3dSmrg 	   typename _Ch_type,
4981debfc3dSmrg 	   typename _Rx_traits>
4991debfc3dSmrg     bool
5001debfc3dSmrg     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ==(const regex_iterator & __rhs) const501c0a68be4Smrg     operator==(const regex_iterator& __rhs) const noexcept
5021debfc3dSmrg     {
5031debfc3dSmrg       if (_M_pregex == nullptr && __rhs._M_pregex == nullptr)
5041debfc3dSmrg 	return true;
5051debfc3dSmrg       return _M_pregex == __rhs._M_pregex
5061debfc3dSmrg 	  && _M_begin == __rhs._M_begin
5071debfc3dSmrg 	  && _M_end == __rhs._M_end
5081debfc3dSmrg 	  && _M_flags == __rhs._M_flags
5091debfc3dSmrg 	  && _M_match[0] == __rhs._M_match[0];
5101debfc3dSmrg     }
5111debfc3dSmrg 
5121debfc3dSmrg   template<typename _Bi_iter,
5131debfc3dSmrg 	   typename _Ch_type,
5141debfc3dSmrg 	   typename _Rx_traits>
5151debfc3dSmrg     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
5161debfc3dSmrg     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ++()5171debfc3dSmrg     operator++()
5181debfc3dSmrg     {
5191debfc3dSmrg       // In all cases in which the call to regex_search returns true,
5201debfc3dSmrg       // match.prefix().first shall be equal to the previous value of
5211debfc3dSmrg       // match[0].second, and for each index i in the half-open range
5221debfc3dSmrg       // [0, match.size()) for which match[i].matched is true,
5231debfc3dSmrg       // match[i].position() shall return distance(begin, match[i].first).
5241debfc3dSmrg       // [28.12.1.4.5]
5251debfc3dSmrg       if (_M_match[0].matched)
5261debfc3dSmrg 	{
5271debfc3dSmrg 	  auto __start = _M_match[0].second;
5281debfc3dSmrg 	  auto __prefix_first = _M_match[0].second;
5291debfc3dSmrg 	  if (_M_match[0].first == _M_match[0].second)
5301debfc3dSmrg 	    {
5311debfc3dSmrg 	      if (__start == _M_end)
5321debfc3dSmrg 		{
5331debfc3dSmrg 		  _M_pregex = nullptr;
5341debfc3dSmrg 		  return *this;
5351debfc3dSmrg 		}
5361debfc3dSmrg 	      else
5371debfc3dSmrg 		{
5381debfc3dSmrg 		  if (regex_search(__start, _M_end, _M_match, *_M_pregex,
5391debfc3dSmrg 				   _M_flags
5401debfc3dSmrg 				   | regex_constants::match_not_null
5411debfc3dSmrg 				   | regex_constants::match_continuous))
5421debfc3dSmrg 		    {
5431debfc3dSmrg 		      __glibcxx_assert(_M_match[0].matched);
5441debfc3dSmrg 		      auto& __prefix = _M_match._M_prefix();
5451debfc3dSmrg 		      __prefix.first = __prefix_first;
5461debfc3dSmrg 		      __prefix.matched = __prefix.first != __prefix.second;
5471debfc3dSmrg 		      // [28.12.1.4.5]
5481debfc3dSmrg 		      _M_match._M_begin = _M_begin;
5491debfc3dSmrg 		      return *this;
5501debfc3dSmrg 		    }
5511debfc3dSmrg 		  else
5521debfc3dSmrg 		    ++__start;
5531debfc3dSmrg 		}
5541debfc3dSmrg 	    }
5551debfc3dSmrg 	  _M_flags |= regex_constants::match_prev_avail;
5561debfc3dSmrg 	  if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
5571debfc3dSmrg 	    {
5581debfc3dSmrg 	      __glibcxx_assert(_M_match[0].matched);
5591debfc3dSmrg 	      auto& __prefix = _M_match._M_prefix();
5601debfc3dSmrg 	      __prefix.first = __prefix_first;
5611debfc3dSmrg 	      __prefix.matched = __prefix.first != __prefix.second;
5621debfc3dSmrg 	      // [28.12.1.4.5]
5631debfc3dSmrg 	      _M_match._M_begin = _M_begin;
5641debfc3dSmrg 	    }
5651debfc3dSmrg 	  else
5661debfc3dSmrg 	    _M_pregex = nullptr;
5671debfc3dSmrg 	}
5681debfc3dSmrg       return *this;
5691debfc3dSmrg     }
5701debfc3dSmrg 
5711debfc3dSmrg   template<typename _Bi_iter,
5721debfc3dSmrg 	   typename _Ch_type,
5731debfc3dSmrg 	   typename _Rx_traits>
5741debfc3dSmrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
5751debfc3dSmrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator =(const regex_token_iterator & __rhs)5761debfc3dSmrg     operator=(const regex_token_iterator& __rhs)
5771debfc3dSmrg     {
5781debfc3dSmrg       _M_position = __rhs._M_position;
5791debfc3dSmrg       _M_subs = __rhs._M_subs;
5801debfc3dSmrg       _M_n = __rhs._M_n;
5811debfc3dSmrg       _M_suffix = __rhs._M_suffix;
5821debfc3dSmrg       _M_has_m1 = __rhs._M_has_m1;
5831debfc3dSmrg       _M_normalize_result();
5841debfc3dSmrg       return *this;
5851debfc3dSmrg     }
5861debfc3dSmrg 
5871debfc3dSmrg   template<typename _Bi_iter,
5881debfc3dSmrg 	   typename _Ch_type,
5891debfc3dSmrg 	   typename _Rx_traits>
5901debfc3dSmrg     bool
5911debfc3dSmrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ==(const regex_token_iterator & __rhs) const5921debfc3dSmrg     operator==(const regex_token_iterator& __rhs) const
5931debfc3dSmrg     {
5941debfc3dSmrg       if (_M_end_of_seq() && __rhs._M_end_of_seq())
5951debfc3dSmrg 	return true;
5961debfc3dSmrg       if (_M_suffix.matched && __rhs._M_suffix.matched
5971debfc3dSmrg 	  && _M_suffix == __rhs._M_suffix)
5981debfc3dSmrg 	return true;
5991debfc3dSmrg       if (_M_end_of_seq() || _M_suffix.matched
6001debfc3dSmrg 	  || __rhs._M_end_of_seq() || __rhs._M_suffix.matched)
6011debfc3dSmrg 	return false;
6021debfc3dSmrg       return _M_position == __rhs._M_position
6031debfc3dSmrg 	&& _M_n == __rhs._M_n
6041debfc3dSmrg 	&& _M_subs == __rhs._M_subs;
6051debfc3dSmrg     }
6061debfc3dSmrg 
6071debfc3dSmrg   template<typename _Bi_iter,
6081debfc3dSmrg 	   typename _Ch_type,
6091debfc3dSmrg 	   typename _Rx_traits>
6101debfc3dSmrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
6111debfc3dSmrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ++()6121debfc3dSmrg     operator++()
6131debfc3dSmrg     {
6141debfc3dSmrg       _Position __prev = _M_position;
6151debfc3dSmrg       if (_M_suffix.matched)
6161debfc3dSmrg 	*this = regex_token_iterator();
6171debfc3dSmrg       else if (_M_n + 1 < _M_subs.size())
6181debfc3dSmrg 	{
6191debfc3dSmrg 	  _M_n++;
6201debfc3dSmrg 	  _M_result = &_M_current_match();
6211debfc3dSmrg 	}
6221debfc3dSmrg       else
6231debfc3dSmrg 	{
6241debfc3dSmrg 	  _M_n = 0;
6251debfc3dSmrg 	  ++_M_position;
6261debfc3dSmrg 	  if (_M_position != _Position())
6271debfc3dSmrg 	    _M_result = &_M_current_match();
6281debfc3dSmrg 	  else if (_M_has_m1 && __prev->suffix().length() != 0)
6291debfc3dSmrg 	    {
6301debfc3dSmrg 	      _M_suffix.matched = true;
6311debfc3dSmrg 	      _M_suffix.first = __prev->suffix().first;
6321debfc3dSmrg 	      _M_suffix.second = __prev->suffix().second;
6331debfc3dSmrg 	      _M_result = &_M_suffix;
6341debfc3dSmrg 	    }
6351debfc3dSmrg 	  else
6361debfc3dSmrg 	    *this = regex_token_iterator();
6371debfc3dSmrg 	}
6381debfc3dSmrg       return *this;
6391debfc3dSmrg     }
6401debfc3dSmrg 
6411debfc3dSmrg   template<typename _Bi_iter,
6421debfc3dSmrg 	   typename _Ch_type,
6431debfc3dSmrg 	   typename _Rx_traits>
6441debfc3dSmrg     void
6451debfc3dSmrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
_M_init(_Bi_iter __a,_Bi_iter __b)6461debfc3dSmrg     _M_init(_Bi_iter __a, _Bi_iter __b)
6471debfc3dSmrg     {
6481debfc3dSmrg       _M_has_m1 = false;
6491debfc3dSmrg       for (auto __it : _M_subs)
6501debfc3dSmrg 	if (__it == -1)
6511debfc3dSmrg 	  {
6521debfc3dSmrg 	    _M_has_m1 = true;
6531debfc3dSmrg 	    break;
6541debfc3dSmrg 	  }
6551debfc3dSmrg       if (_M_position != _Position())
6561debfc3dSmrg 	_M_result = &_M_current_match();
6571debfc3dSmrg       else if (_M_has_m1)
6581debfc3dSmrg 	{
6591debfc3dSmrg 	  _M_suffix.matched = true;
6601debfc3dSmrg 	  _M_suffix.first = __a;
6611debfc3dSmrg 	  _M_suffix.second = __b;
6621debfc3dSmrg 	  _M_result = &_M_suffix;
6631debfc3dSmrg 	}
6641debfc3dSmrg       else
6651debfc3dSmrg 	_M_result = nullptr;
6661debfc3dSmrg     }
6671debfc3dSmrg 
6688feb0f0bSmrg   /// @endcond
6698feb0f0bSmrg 
6701debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
6711debfc3dSmrg } // namespace
672