xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/regex.tcc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
14d5abbe8Smrg // class template regex -*- C++ -*-
24d5abbe8Smrg 
3*b1e83836Smrg // Copyright (C) 2013-2022 Free Software Foundation, Inc.
44d5abbe8Smrg //
54d5abbe8Smrg // This file is part of the GNU ISO C++ Library.  This library is free
64d5abbe8Smrg // software; you can redistribute it and/or modify it under the
74d5abbe8Smrg // terms of the GNU General Public License as published by the
84d5abbe8Smrg // Free Software Foundation; either version 3, or (at your option)
94d5abbe8Smrg // any later version.
104d5abbe8Smrg 
114d5abbe8Smrg // This library is distributed in the hope that it will be useful,
124d5abbe8Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
134d5abbe8Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144d5abbe8Smrg // GNU General Public License for more details.
154d5abbe8Smrg 
164d5abbe8Smrg // Under Section 7 of GPL version 3, you are granted additional
174d5abbe8Smrg // permissions described in the GCC Runtime Library Exception, version
184d5abbe8Smrg // 3.1, as published by the Free Software Foundation.
194d5abbe8Smrg 
204d5abbe8Smrg // You should have received a copy of the GNU General Public License and
214d5abbe8Smrg // a copy of the GCC Runtime Library Exception along with this program;
224d5abbe8Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
234d5abbe8Smrg // <http://www.gnu.org/licenses/>.
244d5abbe8Smrg 
254d5abbe8Smrg /**
264d5abbe8Smrg  *  @file bits/regex.tcc
274d5abbe8Smrg  *  This is an internal header file, included by other library headers.
284d5abbe8Smrg  *  Do not attempt to use it directly. @headername{regex}
294d5abbe8Smrg  */
304d5abbe8Smrg 
314d5abbe8Smrg namespace std _GLIBCXX_VISIBILITY(default)
324d5abbe8Smrg {
338b6133e5Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
348b6133e5Smrg 
35a3e9eb18Smrg namespace __detail
36a3e9eb18Smrg {
37fb8a8121Smrg   /// @cond undocumented
38fb8a8121Smrg 
394d5abbe8Smrg   // Result of merging regex_match and regex_search.
404d5abbe8Smrg   //
414d5abbe8Smrg   // __policy now can be _S_auto (auto dispatch) and _S_alternate (use
424d5abbe8Smrg   // the other one if possible, for test purpose).
434d5abbe8Smrg   //
444d5abbe8Smrg   // That __match_mode is true means regex_match, else regex_search.
454d5abbe8Smrg   template<typename _BiIter, typename _Alloc,
46*b1e83836Smrg 	   typename _CharT, typename _TraitsT>
474d5abbe8Smrg     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,_RegexExecutorPolicy __policy,bool __match_mode)484d5abbe8Smrg     __regex_algo_impl(_BiIter                              __s,
494d5abbe8Smrg 		      _BiIter                              __e,
504d5abbe8Smrg 		      match_results<_BiIter, _Alloc>&      __m,
514d5abbe8Smrg 		      const basic_regex<_CharT, _TraitsT>& __re,
52*b1e83836Smrg 		      regex_constants::match_flag_type     __flags,
53*b1e83836Smrg 		      _RegexExecutorPolicy		   __policy,
54*b1e83836Smrg 		      bool				   __match_mode)
554d5abbe8Smrg     {
564d5abbe8Smrg       if (__re._M_automaton == nullptr)
574d5abbe8Smrg 	return false;
584d5abbe8Smrg 
59*b1e83836Smrg       typename match_results<_BiIter, _Alloc>::_Unchecked& __res = __m;
604d5abbe8Smrg       __m._M_begin = __s;
614d5abbe8Smrg       __m._M_resize(__re._M_automaton->_M_sub_count());
624d5abbe8Smrg 
634d5abbe8Smrg       bool __ret;
64f9a78e0eSmrg       if ((__re.flags() & regex_constants::__polynomial)
65f9a78e0eSmrg 	  || (__policy == _RegexExecutorPolicy::_S_alternate
66f9a78e0eSmrg 	      && !__re._M_automaton->_M_has_backref))
674d5abbe8Smrg 	{
684d5abbe8Smrg 	  _Executor<_BiIter, _Alloc, _TraitsT, false>
69*b1e83836Smrg 	    __executor(__s, __e, __res, __re, __flags);
704d5abbe8Smrg 	  if (__match_mode)
714d5abbe8Smrg 	    __ret = __executor._M_match();
724d5abbe8Smrg 	  else
734d5abbe8Smrg 	    __ret = __executor._M_search();
744d5abbe8Smrg 	}
754d5abbe8Smrg       else
764d5abbe8Smrg 	{
774d5abbe8Smrg 	  _Executor<_BiIter, _Alloc, _TraitsT, true>
78*b1e83836Smrg 	    __executor(__s, __e, __res, __re, __flags);
794d5abbe8Smrg 	  if (__match_mode)
804d5abbe8Smrg 	    __ret = __executor._M_match();
814d5abbe8Smrg 	  else
824d5abbe8Smrg 	    __ret = __executor._M_search();
834d5abbe8Smrg 	}
844d5abbe8Smrg       if (__ret)
854d5abbe8Smrg 	{
864d5abbe8Smrg 	  for (auto& __it : __res)
874d5abbe8Smrg 	    if (!__it.matched)
884d5abbe8Smrg 	      __it.first = __it.second = __e;
894d5abbe8Smrg 	  auto& __pre = __m._M_prefix();
904d5abbe8Smrg 	  auto& __suf = __m._M_suffix();
914d5abbe8Smrg 	  if (__match_mode)
924d5abbe8Smrg 	    {
934d5abbe8Smrg 	      __pre.matched = false;
944d5abbe8Smrg 	      __pre.first = __s;
954d5abbe8Smrg 	      __pre.second = __s;
964d5abbe8Smrg 	      __suf.matched = false;
974d5abbe8Smrg 	      __suf.first = __e;
984d5abbe8Smrg 	      __suf.second = __e;
994d5abbe8Smrg 	    }
1004d5abbe8Smrg 	  else
1014d5abbe8Smrg 	    {
1024d5abbe8Smrg 	      __pre.first = __s;
1034d5abbe8Smrg 	      __pre.second = __res[0].first;
1044d5abbe8Smrg 	      __pre.matched = (__pre.first != __pre.second);
1054d5abbe8Smrg 	      __suf.first = __res[0].second;
1064d5abbe8Smrg 	      __suf.second = __e;
1074d5abbe8Smrg 	      __suf.matched = (__suf.first != __suf.second);
1084d5abbe8Smrg 	    }
1094d5abbe8Smrg 	}
1104d5abbe8Smrg       else
1114d5abbe8Smrg 	{
112fb8a8121Smrg 	  __m._M_establish_failed_match(__e);
1134d5abbe8Smrg 	}
1144d5abbe8Smrg       return __ret;
1154d5abbe8Smrg     }
116fb8a8121Smrg   /// @endcond
117fb8a8121Smrg } // namespace __detail
118fb8a8121Smrg 
119fb8a8121Smrg   /// @cond
1204d5abbe8Smrg 
1214d5abbe8Smrg   template<typename _Ch_type>
1224d5abbe8Smrg   template<typename _Fwd_iter>
1234d5abbe8Smrg     typename regex_traits<_Ch_type>::string_type
1244d5abbe8Smrg     regex_traits<_Ch_type>::
lookup_collatename(_Fwd_iter __first,_Fwd_iter __last) const1254d5abbe8Smrg     lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
1264d5abbe8Smrg     {
1274d5abbe8Smrg       typedef std::ctype<char_type> __ctype_type;
1284d5abbe8Smrg       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
1294d5abbe8Smrg 
1304d5abbe8Smrg       static const char* __collatenames[] =
1314d5abbe8Smrg 	{
1324d5abbe8Smrg 	  "NUL",
1334d5abbe8Smrg 	  "SOH",
1344d5abbe8Smrg 	  "STX",
1354d5abbe8Smrg 	  "ETX",
1364d5abbe8Smrg 	  "EOT",
1374d5abbe8Smrg 	  "ENQ",
1384d5abbe8Smrg 	  "ACK",
1394d5abbe8Smrg 	  "alert",
1404d5abbe8Smrg 	  "backspace",
1414d5abbe8Smrg 	  "tab",
1424d5abbe8Smrg 	  "newline",
1434d5abbe8Smrg 	  "vertical-tab",
1444d5abbe8Smrg 	  "form-feed",
1454d5abbe8Smrg 	  "carriage-return",
1464d5abbe8Smrg 	  "SO",
1474d5abbe8Smrg 	  "SI",
1484d5abbe8Smrg 	  "DLE",
1494d5abbe8Smrg 	  "DC1",
1504d5abbe8Smrg 	  "DC2",
1514d5abbe8Smrg 	  "DC3",
1524d5abbe8Smrg 	  "DC4",
1534d5abbe8Smrg 	  "NAK",
1544d5abbe8Smrg 	  "SYN",
1554d5abbe8Smrg 	  "ETB",
1564d5abbe8Smrg 	  "CAN",
1574d5abbe8Smrg 	  "EM",
1584d5abbe8Smrg 	  "SUB",
1594d5abbe8Smrg 	  "ESC",
1604d5abbe8Smrg 	  "IS4",
1614d5abbe8Smrg 	  "IS3",
1624d5abbe8Smrg 	  "IS2",
1634d5abbe8Smrg 	  "IS1",
1644d5abbe8Smrg 	  "space",
1654d5abbe8Smrg 	  "exclamation-mark",
1664d5abbe8Smrg 	  "quotation-mark",
1674d5abbe8Smrg 	  "number-sign",
1684d5abbe8Smrg 	  "dollar-sign",
1694d5abbe8Smrg 	  "percent-sign",
1704d5abbe8Smrg 	  "ampersand",
1714d5abbe8Smrg 	  "apostrophe",
1724d5abbe8Smrg 	  "left-parenthesis",
1734d5abbe8Smrg 	  "right-parenthesis",
1744d5abbe8Smrg 	  "asterisk",
1754d5abbe8Smrg 	  "plus-sign",
1764d5abbe8Smrg 	  "comma",
1774d5abbe8Smrg 	  "hyphen",
1784d5abbe8Smrg 	  "period",
1794d5abbe8Smrg 	  "slash",
1804d5abbe8Smrg 	  "zero",
1814d5abbe8Smrg 	  "one",
1824d5abbe8Smrg 	  "two",
1834d5abbe8Smrg 	  "three",
1844d5abbe8Smrg 	  "four",
1854d5abbe8Smrg 	  "five",
1864d5abbe8Smrg 	  "six",
1874d5abbe8Smrg 	  "seven",
1884d5abbe8Smrg 	  "eight",
1894d5abbe8Smrg 	  "nine",
1904d5abbe8Smrg 	  "colon",
1914d5abbe8Smrg 	  "semicolon",
1924d5abbe8Smrg 	  "less-than-sign",
1934d5abbe8Smrg 	  "equals-sign",
1944d5abbe8Smrg 	  "greater-than-sign",
1954d5abbe8Smrg 	  "question-mark",
1964d5abbe8Smrg 	  "commercial-at",
1974d5abbe8Smrg 	  "A",
1984d5abbe8Smrg 	  "B",
1994d5abbe8Smrg 	  "C",
2004d5abbe8Smrg 	  "D",
2014d5abbe8Smrg 	  "E",
2024d5abbe8Smrg 	  "F",
2034d5abbe8Smrg 	  "G",
2044d5abbe8Smrg 	  "H",
2054d5abbe8Smrg 	  "I",
2064d5abbe8Smrg 	  "J",
2074d5abbe8Smrg 	  "K",
2084d5abbe8Smrg 	  "L",
2094d5abbe8Smrg 	  "M",
2104d5abbe8Smrg 	  "N",
2114d5abbe8Smrg 	  "O",
2124d5abbe8Smrg 	  "P",
2134d5abbe8Smrg 	  "Q",
2144d5abbe8Smrg 	  "R",
2154d5abbe8Smrg 	  "S",
2164d5abbe8Smrg 	  "T",
2174d5abbe8Smrg 	  "U",
2184d5abbe8Smrg 	  "V",
2194d5abbe8Smrg 	  "W",
2204d5abbe8Smrg 	  "X",
2214d5abbe8Smrg 	  "Y",
2224d5abbe8Smrg 	  "Z",
2234d5abbe8Smrg 	  "left-square-bracket",
2244d5abbe8Smrg 	  "backslash",
2254d5abbe8Smrg 	  "right-square-bracket",
2264d5abbe8Smrg 	  "circumflex",
2274d5abbe8Smrg 	  "underscore",
2284d5abbe8Smrg 	  "grave-accent",
2294d5abbe8Smrg 	  "a",
2304d5abbe8Smrg 	  "b",
2314d5abbe8Smrg 	  "c",
2324d5abbe8Smrg 	  "d",
2334d5abbe8Smrg 	  "e",
2344d5abbe8Smrg 	  "f",
2354d5abbe8Smrg 	  "g",
2364d5abbe8Smrg 	  "h",
2374d5abbe8Smrg 	  "i",
2384d5abbe8Smrg 	  "j",
2394d5abbe8Smrg 	  "k",
2404d5abbe8Smrg 	  "l",
2414d5abbe8Smrg 	  "m",
2424d5abbe8Smrg 	  "n",
2434d5abbe8Smrg 	  "o",
2444d5abbe8Smrg 	  "p",
2454d5abbe8Smrg 	  "q",
2464d5abbe8Smrg 	  "r",
2474d5abbe8Smrg 	  "s",
2484d5abbe8Smrg 	  "t",
2494d5abbe8Smrg 	  "u",
2504d5abbe8Smrg 	  "v",
2514d5abbe8Smrg 	  "w",
2524d5abbe8Smrg 	  "x",
2534d5abbe8Smrg 	  "y",
2544d5abbe8Smrg 	  "z",
2554d5abbe8Smrg 	  "left-curly-bracket",
2564d5abbe8Smrg 	  "vertical-line",
2574d5abbe8Smrg 	  "right-curly-bracket",
2584d5abbe8Smrg 	  "tilde",
2594d5abbe8Smrg 	  "DEL",
2604d5abbe8Smrg 	};
2614d5abbe8Smrg 
2624d5abbe8Smrg       string __s;
2634d5abbe8Smrg       for (; __first != __last; ++__first)
2644d5abbe8Smrg 	__s += __fctyp.narrow(*__first, 0);
2654d5abbe8Smrg 
2664d5abbe8Smrg       for (const auto& __it : __collatenames)
2674d5abbe8Smrg 	if (__s == __it)
2684d5abbe8Smrg 	  return string_type(1, __fctyp.widen(
2694d5abbe8Smrg 	    static_cast<char>(&__it - __collatenames)));
2704d5abbe8Smrg 
2714d5abbe8Smrg       // TODO Add digraph support:
2724d5abbe8Smrg       // http://boost.sourceforge.net/libs/regex/doc/collating_names.html
2734d5abbe8Smrg 
2744d5abbe8Smrg       return string_type();
2754d5abbe8Smrg     }
2764d5abbe8Smrg 
2774d5abbe8Smrg   template<typename _Ch_type>
2784d5abbe8Smrg   template<typename _Fwd_iter>
2794d5abbe8Smrg     typename regex_traits<_Ch_type>::char_class_type
2804d5abbe8Smrg     regex_traits<_Ch_type>::
lookup_classname(_Fwd_iter __first,_Fwd_iter __last,bool __icase) const2814d5abbe8Smrg     lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const
2824d5abbe8Smrg     {
2834d5abbe8Smrg       typedef std::ctype<char_type> __ctype_type;
2844d5abbe8Smrg       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
2854d5abbe8Smrg 
2864d5abbe8Smrg       // Mappings from class name to class mask.
2874d5abbe8Smrg       static const pair<const char*, char_class_type> __classnames[] =
2884d5abbe8Smrg       {
2894d5abbe8Smrg 	{"d", ctype_base::digit},
2904d5abbe8Smrg 	{"w", {ctype_base::alnum, _RegexMask::_S_under}},
2914d5abbe8Smrg 	{"s", ctype_base::space},
2924d5abbe8Smrg 	{"alnum", ctype_base::alnum},
2934d5abbe8Smrg 	{"alpha", ctype_base::alpha},
2944d5abbe8Smrg 	{"blank", ctype_base::blank},
2954d5abbe8Smrg 	{"cntrl", ctype_base::cntrl},
2964d5abbe8Smrg 	{"digit", ctype_base::digit},
2974d5abbe8Smrg 	{"graph", ctype_base::graph},
2984d5abbe8Smrg 	{"lower", ctype_base::lower},
2994d5abbe8Smrg 	{"print", ctype_base::print},
3004d5abbe8Smrg 	{"punct", ctype_base::punct},
3014d5abbe8Smrg 	{"space", ctype_base::space},
3024d5abbe8Smrg 	{"upper", ctype_base::upper},
3034d5abbe8Smrg 	{"xdigit", ctype_base::xdigit},
3044d5abbe8Smrg       };
3054d5abbe8Smrg 
3064d5abbe8Smrg       string __s;
3074d5abbe8Smrg       for (; __first != __last; ++__first)
3084d5abbe8Smrg 	__s += __fctyp.narrow(__fctyp.tolower(*__first), 0);
3094d5abbe8Smrg 
3104d5abbe8Smrg       for (const auto& __it : __classnames)
3114d5abbe8Smrg 	if (__s == __it.first)
3124d5abbe8Smrg 	  {
3134d5abbe8Smrg 	    if (__icase
3144d5abbe8Smrg 		&& ((__it.second
3154d5abbe8Smrg 		     & (ctype_base::lower | ctype_base::upper)) != 0))
3164d5abbe8Smrg 	      return ctype_base::alpha;
3174d5abbe8Smrg 	    return __it.second;
3184d5abbe8Smrg 	  }
3194d5abbe8Smrg       return 0;
3204d5abbe8Smrg     }
3214d5abbe8Smrg 
3224d5abbe8Smrg   template<typename _Ch_type>
3234d5abbe8Smrg     bool
3244d5abbe8Smrg     regex_traits<_Ch_type>::
isctype(_Ch_type __c,char_class_type __f) const3254d5abbe8Smrg     isctype(_Ch_type __c, char_class_type __f) const
3264d5abbe8Smrg     {
3274d5abbe8Smrg       typedef std::ctype<char_type> __ctype_type;
3284d5abbe8Smrg       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
3294d5abbe8Smrg 
3304d5abbe8Smrg       return __fctyp.is(__f._M_base, __c)
3314d5abbe8Smrg 	// [[:w:]]
3324d5abbe8Smrg 	|| ((__f._M_extended & _RegexMask::_S_under)
3334d5abbe8Smrg 	    && __c == __fctyp.widen('_'));
3344d5abbe8Smrg     }
3354d5abbe8Smrg 
3364d5abbe8Smrg   template<typename _Ch_type>
3374d5abbe8Smrg     int
3384d5abbe8Smrg     regex_traits<_Ch_type>::
value(_Ch_type __ch,int __radix) const3394d5abbe8Smrg     value(_Ch_type __ch, int __radix) const
3404d5abbe8Smrg     {
3414d5abbe8Smrg       std::basic_istringstream<char_type> __is(string_type(1, __ch));
3424d5abbe8Smrg       long __v;
3434d5abbe8Smrg       if (__radix == 8)
3444d5abbe8Smrg 	__is >> std::oct;
3454d5abbe8Smrg       else if (__radix == 16)
3464d5abbe8Smrg 	__is >> std::hex;
3474d5abbe8Smrg       __is >> __v;
3484d5abbe8Smrg       return __is.fail() ? -1 : __v;
3494d5abbe8Smrg     }
3504d5abbe8Smrg 
3514d5abbe8Smrg   template<typename _Bi_iter, typename _Alloc>
3524d5abbe8Smrg   template<typename _Out_iter>
353fb8a8121Smrg     _Out_iter
354fb8a8121Smrg     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) const3554d5abbe8Smrg     format(_Out_iter __out,
3564d5abbe8Smrg 	   const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first,
3574d5abbe8Smrg 	   const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last,
3584d5abbe8Smrg 	   match_flag_type __flags) const
3594d5abbe8Smrg     {
360f9a78e0eSmrg       __glibcxx_assert( ready() );
3614d5abbe8Smrg       regex_traits<char_type> __traits;
3624d5abbe8Smrg       typedef std::ctype<char_type> __ctype_type;
3634d5abbe8Smrg       const __ctype_type&
3644d5abbe8Smrg 	__fctyp(use_facet<__ctype_type>(__traits.getloc()));
3654d5abbe8Smrg 
3664d5abbe8Smrg       auto __output = [&](size_t __idx)
3674d5abbe8Smrg 	{
3684d5abbe8Smrg 	  auto& __sub = (*this)[__idx];
3694d5abbe8Smrg 	  if (__sub.matched)
3704d5abbe8Smrg 	    __out = std::copy(__sub.first, __sub.second, __out);
3714d5abbe8Smrg 	};
3724d5abbe8Smrg 
3734d5abbe8Smrg       if (__flags & regex_constants::format_sed)
3744d5abbe8Smrg 	{
375a3e9eb18Smrg 	  bool __escaping = false;
376a3e9eb18Smrg 	  for (; __fmt_first != __fmt_last; __fmt_first++)
377a3e9eb18Smrg 	    {
378a3e9eb18Smrg 	      if (__escaping)
379a3e9eb18Smrg 		{
380a3e9eb18Smrg 		  __escaping = false;
381a3e9eb18Smrg 		  if (__fctyp.is(__ctype_type::digit, *__fmt_first))
382a3e9eb18Smrg 		    __output(__traits.value(*__fmt_first, 10));
383a3e9eb18Smrg 		  else
384a3e9eb18Smrg 		    *__out++ = *__fmt_first;
385a3e9eb18Smrg 		  continue;
386a3e9eb18Smrg 		}
387a3e9eb18Smrg 	      if (*__fmt_first == '\\')
388a3e9eb18Smrg 		{
389a3e9eb18Smrg 		  __escaping = true;
390a3e9eb18Smrg 		  continue;
391a3e9eb18Smrg 		}
3924d5abbe8Smrg 	      if (*__fmt_first == '&')
3934d5abbe8Smrg 		{
3944d5abbe8Smrg 		  __output(0);
395a3e9eb18Smrg 		  continue;
3964d5abbe8Smrg 		}
397a3e9eb18Smrg 	      *__out++ = *__fmt_first;
398a3e9eb18Smrg 	    }
399a3e9eb18Smrg 	  if (__escaping)
4004d5abbe8Smrg 	    *__out++ = '\\';
4014d5abbe8Smrg 	}
4024d5abbe8Smrg       else
4034d5abbe8Smrg 	{
4044d5abbe8Smrg 	  while (1)
4054d5abbe8Smrg 	    {
4064d5abbe8Smrg 	      auto __next = std::find(__fmt_first, __fmt_last, '$');
4074d5abbe8Smrg 	      if (__next == __fmt_last)
4084d5abbe8Smrg 		break;
4094d5abbe8Smrg 
4104d5abbe8Smrg 	      __out = std::copy(__fmt_first, __next, __out);
4114d5abbe8Smrg 
4124d5abbe8Smrg 	      auto __eat = [&](char __ch) -> bool
4134d5abbe8Smrg 		{
4144d5abbe8Smrg 		  if (*__next == __ch)
4154d5abbe8Smrg 		    {
4164d5abbe8Smrg 		      ++__next;
4174d5abbe8Smrg 		      return true;
4184d5abbe8Smrg 		    }
4194d5abbe8Smrg 		  return false;
4204d5abbe8Smrg 		};
4214d5abbe8Smrg 
4224d5abbe8Smrg 	      if (++__next == __fmt_last)
4234d5abbe8Smrg 		*__out++ = '$';
4244d5abbe8Smrg 	      else if (__eat('$'))
4254d5abbe8Smrg 		*__out++ = '$';
4264d5abbe8Smrg 	      else if (__eat('&'))
4274d5abbe8Smrg 		__output(0);
4284d5abbe8Smrg 	      else if (__eat('`'))
4294d5abbe8Smrg 		{
4304d5abbe8Smrg 		  auto& __sub = _M_prefix();
4314d5abbe8Smrg 		  if (__sub.matched)
4324d5abbe8Smrg 		    __out = std::copy(__sub.first, __sub.second, __out);
4334d5abbe8Smrg 		}
4344d5abbe8Smrg 	      else if (__eat('\''))
4354d5abbe8Smrg 		{
4364d5abbe8Smrg 		  auto& __sub = _M_suffix();
4374d5abbe8Smrg 		  if (__sub.matched)
4384d5abbe8Smrg 		    __out = std::copy(__sub.first, __sub.second, __out);
4394d5abbe8Smrg 		}
4404d5abbe8Smrg 	      else if (__fctyp.is(__ctype_type::digit, *__next))
4414d5abbe8Smrg 		{
4424d5abbe8Smrg 		  long __num = __traits.value(*__next, 10);
4434d5abbe8Smrg 		  if (++__next != __fmt_last
4444d5abbe8Smrg 		      && __fctyp.is(__ctype_type::digit, *__next))
4454d5abbe8Smrg 		    {
4464d5abbe8Smrg 		      __num *= 10;
4474d5abbe8Smrg 		      __num += __traits.value(*__next++, 10);
4484d5abbe8Smrg 		    }
4494d5abbe8Smrg 		  if (0 <= __num && __num < this->size())
4504d5abbe8Smrg 		    __output(__num);
4514d5abbe8Smrg 		}
4524d5abbe8Smrg 	      else
4534d5abbe8Smrg 		*__out++ = '$';
4544d5abbe8Smrg 	      __fmt_first = __next;
4554d5abbe8Smrg 	    }
4564d5abbe8Smrg 	  __out = std::copy(__fmt_first, __fmt_last, __out);
4574d5abbe8Smrg 	}
4584d5abbe8Smrg       return __out;
4594d5abbe8Smrg     }
4604d5abbe8Smrg 
4614d5abbe8Smrg   template<typename _Out_iter, typename _Bi_iter,
4624d5abbe8Smrg 	   typename _Rx_traits, typename _Ch_type>
4634d5abbe8Smrg     _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)4647d4dc15bSmrg     __regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
4654d5abbe8Smrg 		    const basic_regex<_Ch_type, _Rx_traits>& __e,
4667d4dc15bSmrg 		    const _Ch_type* __fmt, size_t __len,
4674d5abbe8Smrg 		    regex_constants::match_flag_type __flags)
4684d5abbe8Smrg     {
4694d5abbe8Smrg       typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT;
4704d5abbe8Smrg       _IterT __i(__first, __last, __e, __flags);
4714d5abbe8Smrg       _IterT __end;
4724d5abbe8Smrg       if (__i == __end)
4734d5abbe8Smrg 	{
4744d5abbe8Smrg 	  if (!(__flags & regex_constants::format_no_copy))
4754d5abbe8Smrg 	    __out = std::copy(__first, __last, __out);
4764d5abbe8Smrg 	}
4774d5abbe8Smrg       else
4784d5abbe8Smrg 	{
4794d5abbe8Smrg 	  sub_match<_Bi_iter> __last;
4804d5abbe8Smrg 	  for (; __i != __end; ++__i)
4814d5abbe8Smrg 	    {
4824d5abbe8Smrg 	      if (!(__flags & regex_constants::format_no_copy))
4834d5abbe8Smrg 		__out = std::copy(__i->prefix().first, __i->prefix().second,
4844d5abbe8Smrg 				  __out);
4854d5abbe8Smrg 	      __out = __i->format(__out, __fmt, __fmt + __len, __flags);
4864d5abbe8Smrg 	      __last = __i->suffix();
4874d5abbe8Smrg 	      if (__flags & regex_constants::format_first_only)
4884d5abbe8Smrg 		break;
4894d5abbe8Smrg 	    }
4904d5abbe8Smrg 	  if (!(__flags & regex_constants::format_no_copy))
4914d5abbe8Smrg 	    __out = std::copy(__last.first, __last.second, __out);
4924d5abbe8Smrg 	}
4934d5abbe8Smrg       return __out;
4944d5abbe8Smrg     }
4954d5abbe8Smrg 
4964d5abbe8Smrg   template<typename _Bi_iter,
4974d5abbe8Smrg 	   typename _Ch_type,
4984d5abbe8Smrg 	   typename _Rx_traits>
4994d5abbe8Smrg     bool
5004d5abbe8Smrg     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ==(const regex_iterator & __rhs) const501181254a7Smrg     operator==(const regex_iterator& __rhs) const noexcept
5024d5abbe8Smrg     {
5033f4ceed9Smrg       if (_M_pregex == nullptr && __rhs._M_pregex == nullptr)
5043f4ceed9Smrg 	return true;
5053f4ceed9Smrg       return _M_pregex == __rhs._M_pregex
5063f4ceed9Smrg 	  && _M_begin == __rhs._M_begin
5074d5abbe8Smrg 	  && _M_end == __rhs._M_end
5084d5abbe8Smrg 	  && _M_flags == __rhs._M_flags
5093f4ceed9Smrg 	  && _M_match[0] == __rhs._M_match[0];
5104d5abbe8Smrg     }
5114d5abbe8Smrg 
5124d5abbe8Smrg   template<typename _Bi_iter,
5134d5abbe8Smrg 	   typename _Ch_type,
5144d5abbe8Smrg 	   typename _Rx_traits>
5154d5abbe8Smrg     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
5164d5abbe8Smrg     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ++()5174d5abbe8Smrg     operator++()
5184d5abbe8Smrg     {
5194d5abbe8Smrg       // In all cases in which the call to regex_search returns true,
5204d5abbe8Smrg       // match.prefix().first shall be equal to the previous value of
5214d5abbe8Smrg       // match[0].second, and for each index i in the half-open range
5224d5abbe8Smrg       // [0, match.size()) for which match[i].matched is true,
5234d5abbe8Smrg       // match[i].position() shall return distance(begin, match[i].first).
5244d5abbe8Smrg       // [28.12.1.4.5]
5254d5abbe8Smrg       if (_M_match[0].matched)
5264d5abbe8Smrg 	{
5274d5abbe8Smrg 	  auto __start = _M_match[0].second;
5284d5abbe8Smrg 	  auto __prefix_first = _M_match[0].second;
5294d5abbe8Smrg 	  if (_M_match[0].first == _M_match[0].second)
5304d5abbe8Smrg 	    {
5314d5abbe8Smrg 	      if (__start == _M_end)
5324d5abbe8Smrg 		{
5333f4ceed9Smrg 		  _M_pregex = nullptr;
5344d5abbe8Smrg 		  return *this;
5354d5abbe8Smrg 		}
5364d5abbe8Smrg 	      else
5374d5abbe8Smrg 		{
5384d5abbe8Smrg 		  if (regex_search(__start, _M_end, _M_match, *_M_pregex,
5394d5abbe8Smrg 				   _M_flags
5404d5abbe8Smrg 				   | regex_constants::match_not_null
5414d5abbe8Smrg 				   | regex_constants::match_continuous))
5424d5abbe8Smrg 		    {
543f9a78e0eSmrg 		      __glibcxx_assert(_M_match[0].matched);
5444d5abbe8Smrg 		      auto& __prefix = _M_match._M_prefix();
5454d5abbe8Smrg 		      __prefix.first = __prefix_first;
5464d5abbe8Smrg 		      __prefix.matched = __prefix.first != __prefix.second;
5474d5abbe8Smrg 		      // [28.12.1.4.5]
5484d5abbe8Smrg 		      _M_match._M_begin = _M_begin;
5494d5abbe8Smrg 		      return *this;
5504d5abbe8Smrg 		    }
5514d5abbe8Smrg 		  else
5524d5abbe8Smrg 		    ++__start;
5534d5abbe8Smrg 		}
5544d5abbe8Smrg 	    }
5554d5abbe8Smrg 	  _M_flags |= regex_constants::match_prev_avail;
5564d5abbe8Smrg 	  if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
5574d5abbe8Smrg 	    {
558f9a78e0eSmrg 	      __glibcxx_assert(_M_match[0].matched);
5594d5abbe8Smrg 	      auto& __prefix = _M_match._M_prefix();
5604d5abbe8Smrg 	      __prefix.first = __prefix_first;
5614d5abbe8Smrg 	      __prefix.matched = __prefix.first != __prefix.second;
5624d5abbe8Smrg 	      // [28.12.1.4.5]
5634d5abbe8Smrg 	      _M_match._M_begin = _M_begin;
5644d5abbe8Smrg 	    }
5654d5abbe8Smrg 	  else
5663f4ceed9Smrg 	    _M_pregex = nullptr;
5674d5abbe8Smrg 	}
5684d5abbe8Smrg       return *this;
5694d5abbe8Smrg     }
5704d5abbe8Smrg 
5714d5abbe8Smrg   template<typename _Bi_iter,
5724d5abbe8Smrg 	   typename _Ch_type,
5734d5abbe8Smrg 	   typename _Rx_traits>
5744d5abbe8Smrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
5754d5abbe8Smrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator =(const regex_token_iterator & __rhs)5764d5abbe8Smrg     operator=(const regex_token_iterator& __rhs)
5774d5abbe8Smrg     {
5784d5abbe8Smrg       _M_position = __rhs._M_position;
5794d5abbe8Smrg       _M_subs = __rhs._M_subs;
5804d5abbe8Smrg       _M_n = __rhs._M_n;
5814d5abbe8Smrg       _M_suffix = __rhs._M_suffix;
5824d5abbe8Smrg       _M_has_m1 = __rhs._M_has_m1;
5834d5abbe8Smrg       _M_normalize_result();
5844d5abbe8Smrg       return *this;
5854d5abbe8Smrg     }
5864d5abbe8Smrg 
5874d5abbe8Smrg   template<typename _Bi_iter,
5884d5abbe8Smrg 	   typename _Ch_type,
5894d5abbe8Smrg 	   typename _Rx_traits>
5904d5abbe8Smrg     bool
5914d5abbe8Smrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ==(const regex_token_iterator & __rhs) const5924d5abbe8Smrg     operator==(const regex_token_iterator& __rhs) const
5934d5abbe8Smrg     {
5944d5abbe8Smrg       if (_M_end_of_seq() && __rhs._M_end_of_seq())
5954d5abbe8Smrg 	return true;
5964d5abbe8Smrg       if (_M_suffix.matched && __rhs._M_suffix.matched
5974d5abbe8Smrg 	  && _M_suffix == __rhs._M_suffix)
5984d5abbe8Smrg 	return true;
5994d5abbe8Smrg       if (_M_end_of_seq() || _M_suffix.matched
6004d5abbe8Smrg 	  || __rhs._M_end_of_seq() || __rhs._M_suffix.matched)
6014d5abbe8Smrg 	return false;
6024d5abbe8Smrg       return _M_position == __rhs._M_position
6034d5abbe8Smrg 	&& _M_n == __rhs._M_n
6044d5abbe8Smrg 	&& _M_subs == __rhs._M_subs;
6054d5abbe8Smrg     }
6064d5abbe8Smrg 
6074d5abbe8Smrg   template<typename _Bi_iter,
6084d5abbe8Smrg 	   typename _Ch_type,
6094d5abbe8Smrg 	   typename _Rx_traits>
6104d5abbe8Smrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
6114d5abbe8Smrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ++()6124d5abbe8Smrg     operator++()
6134d5abbe8Smrg     {
6144d5abbe8Smrg       _Position __prev = _M_position;
6154d5abbe8Smrg       if (_M_suffix.matched)
6164d5abbe8Smrg 	*this = regex_token_iterator();
6174d5abbe8Smrg       else if (_M_n + 1 < _M_subs.size())
6184d5abbe8Smrg 	{
6194d5abbe8Smrg 	  _M_n++;
6204d5abbe8Smrg 	  _M_result = &_M_current_match();
6214d5abbe8Smrg 	}
6224d5abbe8Smrg       else
6234d5abbe8Smrg 	{
6244d5abbe8Smrg 	  _M_n = 0;
6254d5abbe8Smrg 	  ++_M_position;
6264d5abbe8Smrg 	  if (_M_position != _Position())
6274d5abbe8Smrg 	    _M_result = &_M_current_match();
6284d5abbe8Smrg 	  else if (_M_has_m1 && __prev->suffix().length() != 0)
6294d5abbe8Smrg 	    {
6304d5abbe8Smrg 	      _M_suffix.matched = true;
6314d5abbe8Smrg 	      _M_suffix.first = __prev->suffix().first;
6324d5abbe8Smrg 	      _M_suffix.second = __prev->suffix().second;
6334d5abbe8Smrg 	      _M_result = &_M_suffix;
6344d5abbe8Smrg 	    }
6354d5abbe8Smrg 	  else
6364d5abbe8Smrg 	    *this = regex_token_iterator();
6374d5abbe8Smrg 	}
6384d5abbe8Smrg       return *this;
6394d5abbe8Smrg     }
6404d5abbe8Smrg 
6414d5abbe8Smrg   template<typename _Bi_iter,
6424d5abbe8Smrg 	   typename _Ch_type,
6434d5abbe8Smrg 	   typename _Rx_traits>
6444d5abbe8Smrg     void
6454d5abbe8Smrg     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
_M_init(_Bi_iter __a,_Bi_iter __b)6464d5abbe8Smrg     _M_init(_Bi_iter __a, _Bi_iter __b)
6474d5abbe8Smrg     {
6484d5abbe8Smrg       _M_has_m1 = false;
6494d5abbe8Smrg       for (auto __it : _M_subs)
6504d5abbe8Smrg 	if (__it == -1)
6514d5abbe8Smrg 	  {
6524d5abbe8Smrg 	    _M_has_m1 = true;
6534d5abbe8Smrg 	    break;
6544d5abbe8Smrg 	  }
6554d5abbe8Smrg       if (_M_position != _Position())
6564d5abbe8Smrg 	_M_result = &_M_current_match();
6574d5abbe8Smrg       else if (_M_has_m1)
6584d5abbe8Smrg 	{
6594d5abbe8Smrg 	  _M_suffix.matched = true;
6604d5abbe8Smrg 	  _M_suffix.first = __a;
6614d5abbe8Smrg 	  _M_suffix.second = __b;
6624d5abbe8Smrg 	  _M_result = &_M_suffix;
6634d5abbe8Smrg 	}
6644d5abbe8Smrg       else
6654d5abbe8Smrg 	_M_result = nullptr;
6664d5abbe8Smrg     }
6674d5abbe8Smrg 
668fb8a8121Smrg   /// @endcond
669fb8a8121Smrg 
6704d5abbe8Smrg _GLIBCXX_END_NAMESPACE_VERSION
6714d5abbe8Smrg } // namespace
672