1*38fd1498Szrj // class template regex -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2013-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /**
26*38fd1498Szrj  *  @file bits/regex.tcc
27*38fd1498Szrj  *  This is an internal header file, included by other library headers.
28*38fd1498Szrj  *  Do not attempt to use it directly. @headername{regex}
29*38fd1498Szrj  */
30*38fd1498Szrj 
31*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
32*38fd1498Szrj {
33*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
34*38fd1498Szrj 
35*38fd1498Szrj namespace __detail
36*38fd1498Szrj {
37*38fd1498Szrj   // Result of merging regex_match and regex_search.
38*38fd1498Szrj   //
39*38fd1498Szrj   // __policy now can be _S_auto (auto dispatch) and _S_alternate (use
40*38fd1498Szrj   // the other one if possible, for test purpose).
41*38fd1498Szrj   //
42*38fd1498Szrj   // That __match_mode is true means regex_match, else regex_search.
43*38fd1498Szrj   template<typename _BiIter, typename _Alloc,
44*38fd1498Szrj 	   typename _CharT, typename _TraitsT,
45*38fd1498Szrj 	   _RegexExecutorPolicy __policy,
46*38fd1498Szrj 	   bool __match_mode>
47*38fd1498Szrj     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)48*38fd1498Szrj     __regex_algo_impl(_BiIter                              __s,
49*38fd1498Szrj 		      _BiIter                              __e,
50*38fd1498Szrj 		      match_results<_BiIter, _Alloc>&      __m,
51*38fd1498Szrj 		      const basic_regex<_CharT, _TraitsT>& __re,
52*38fd1498Szrj 		      regex_constants::match_flag_type     __flags)
53*38fd1498Szrj     {
54*38fd1498Szrj       if (__re._M_automaton == nullptr)
55*38fd1498Szrj 	return false;
56*38fd1498Szrj 
57*38fd1498Szrj       typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
58*38fd1498Szrj       __m._M_begin = __s;
59*38fd1498Szrj       __m._M_resize(__re._M_automaton->_M_sub_count());
60*38fd1498Szrj       for (auto& __it : __res)
61*38fd1498Szrj 	__it.matched = false;
62*38fd1498Szrj 
63*38fd1498Szrj       bool __ret;
64*38fd1498Szrj       if ((__re.flags() & regex_constants::__polynomial)
65*38fd1498Szrj 	  || (__policy == _RegexExecutorPolicy::_S_alternate
66*38fd1498Szrj 	      && !__re._M_automaton->_M_has_backref))
67*38fd1498Szrj 	{
68*38fd1498Szrj 	  _Executor<_BiIter, _Alloc, _TraitsT, false>
69*38fd1498Szrj 	    __executor(__s, __e, __m, __re, __flags);
70*38fd1498Szrj 	  if (__match_mode)
71*38fd1498Szrj 	    __ret = __executor._M_match();
72*38fd1498Szrj 	  else
73*38fd1498Szrj 	    __ret = __executor._M_search();
74*38fd1498Szrj 	}
75*38fd1498Szrj       else
76*38fd1498Szrj 	{
77*38fd1498Szrj 	  _Executor<_BiIter, _Alloc, _TraitsT, true>
78*38fd1498Szrj 	    __executor(__s, __e, __m, __re, __flags);
79*38fd1498Szrj 	  if (__match_mode)
80*38fd1498Szrj 	    __ret = __executor._M_match();
81*38fd1498Szrj 	  else
82*38fd1498Szrj 	    __ret = __executor._M_search();
83*38fd1498Szrj 	}
84*38fd1498Szrj       if (__ret)
85*38fd1498Szrj 	{
86*38fd1498Szrj 	  for (auto& __it : __res)
87*38fd1498Szrj 	    if (!__it.matched)
88*38fd1498Szrj 	      __it.first = __it.second = __e;
89*38fd1498Szrj 	  auto& __pre = __m._M_prefix();
90*38fd1498Szrj 	  auto& __suf = __m._M_suffix();
91*38fd1498Szrj 	  if (__match_mode)
92*38fd1498Szrj 	    {
93*38fd1498Szrj 	      __pre.matched = false;
94*38fd1498Szrj 	      __pre.first = __s;
95*38fd1498Szrj 	      __pre.second = __s;
96*38fd1498Szrj 	      __suf.matched = false;
97*38fd1498Szrj 	      __suf.first = __e;
98*38fd1498Szrj 	      __suf.second = __e;
99*38fd1498Szrj 	    }
100*38fd1498Szrj 	  else
101*38fd1498Szrj 	    {
102*38fd1498Szrj 	      __pre.first = __s;
103*38fd1498Szrj 	      __pre.second = __res[0].first;
104*38fd1498Szrj 	      __pre.matched = (__pre.first != __pre.second);
105*38fd1498Szrj 	      __suf.first = __res[0].second;
106*38fd1498Szrj 	      __suf.second = __e;
107*38fd1498Szrj 	      __suf.matched = (__suf.first != __suf.second);
108*38fd1498Szrj 	    }
109*38fd1498Szrj 	}
110*38fd1498Szrj       else
111*38fd1498Szrj 	{
112*38fd1498Szrj 	  __m._M_resize(0);
113*38fd1498Szrj 	  for (auto& __it : __res)
114*38fd1498Szrj 	    {
115*38fd1498Szrj 	      __it.matched = false;
116*38fd1498Szrj 	      __it.first = __it.second = __e;
117*38fd1498Szrj 	    }
118*38fd1498Szrj 	}
119*38fd1498Szrj       return __ret;
120*38fd1498Szrj     }
121*38fd1498Szrj }
122*38fd1498Szrj 
123*38fd1498Szrj   template<typename _Ch_type>
124*38fd1498Szrj   template<typename _Fwd_iter>
125*38fd1498Szrj     typename regex_traits<_Ch_type>::string_type
126*38fd1498Szrj     regex_traits<_Ch_type>::
lookup_collatename(_Fwd_iter __first,_Fwd_iter __last) const127*38fd1498Szrj     lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
128*38fd1498Szrj     {
129*38fd1498Szrj       typedef std::ctype<char_type> __ctype_type;
130*38fd1498Szrj       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
131*38fd1498Szrj 
132*38fd1498Szrj       static const char* __collatenames[] =
133*38fd1498Szrj 	{
134*38fd1498Szrj 	  "NUL",
135*38fd1498Szrj 	  "SOH",
136*38fd1498Szrj 	  "STX",
137*38fd1498Szrj 	  "ETX",
138*38fd1498Szrj 	  "EOT",
139*38fd1498Szrj 	  "ENQ",
140*38fd1498Szrj 	  "ACK",
141*38fd1498Szrj 	  "alert",
142*38fd1498Szrj 	  "backspace",
143*38fd1498Szrj 	  "tab",
144*38fd1498Szrj 	  "newline",
145*38fd1498Szrj 	  "vertical-tab",
146*38fd1498Szrj 	  "form-feed",
147*38fd1498Szrj 	  "carriage-return",
148*38fd1498Szrj 	  "SO",
149*38fd1498Szrj 	  "SI",
150*38fd1498Szrj 	  "DLE",
151*38fd1498Szrj 	  "DC1",
152*38fd1498Szrj 	  "DC2",
153*38fd1498Szrj 	  "DC3",
154*38fd1498Szrj 	  "DC4",
155*38fd1498Szrj 	  "NAK",
156*38fd1498Szrj 	  "SYN",
157*38fd1498Szrj 	  "ETB",
158*38fd1498Szrj 	  "CAN",
159*38fd1498Szrj 	  "EM",
160*38fd1498Szrj 	  "SUB",
161*38fd1498Szrj 	  "ESC",
162*38fd1498Szrj 	  "IS4",
163*38fd1498Szrj 	  "IS3",
164*38fd1498Szrj 	  "IS2",
165*38fd1498Szrj 	  "IS1",
166*38fd1498Szrj 	  "space",
167*38fd1498Szrj 	  "exclamation-mark",
168*38fd1498Szrj 	  "quotation-mark",
169*38fd1498Szrj 	  "number-sign",
170*38fd1498Szrj 	  "dollar-sign",
171*38fd1498Szrj 	  "percent-sign",
172*38fd1498Szrj 	  "ampersand",
173*38fd1498Szrj 	  "apostrophe",
174*38fd1498Szrj 	  "left-parenthesis",
175*38fd1498Szrj 	  "right-parenthesis",
176*38fd1498Szrj 	  "asterisk",
177*38fd1498Szrj 	  "plus-sign",
178*38fd1498Szrj 	  "comma",
179*38fd1498Szrj 	  "hyphen",
180*38fd1498Szrj 	  "period",
181*38fd1498Szrj 	  "slash",
182*38fd1498Szrj 	  "zero",
183*38fd1498Szrj 	  "one",
184*38fd1498Szrj 	  "two",
185*38fd1498Szrj 	  "three",
186*38fd1498Szrj 	  "four",
187*38fd1498Szrj 	  "five",
188*38fd1498Szrj 	  "six",
189*38fd1498Szrj 	  "seven",
190*38fd1498Szrj 	  "eight",
191*38fd1498Szrj 	  "nine",
192*38fd1498Szrj 	  "colon",
193*38fd1498Szrj 	  "semicolon",
194*38fd1498Szrj 	  "less-than-sign",
195*38fd1498Szrj 	  "equals-sign",
196*38fd1498Szrj 	  "greater-than-sign",
197*38fd1498Szrj 	  "question-mark",
198*38fd1498Szrj 	  "commercial-at",
199*38fd1498Szrj 	  "A",
200*38fd1498Szrj 	  "B",
201*38fd1498Szrj 	  "C",
202*38fd1498Szrj 	  "D",
203*38fd1498Szrj 	  "E",
204*38fd1498Szrj 	  "F",
205*38fd1498Szrj 	  "G",
206*38fd1498Szrj 	  "H",
207*38fd1498Szrj 	  "I",
208*38fd1498Szrj 	  "J",
209*38fd1498Szrj 	  "K",
210*38fd1498Szrj 	  "L",
211*38fd1498Szrj 	  "M",
212*38fd1498Szrj 	  "N",
213*38fd1498Szrj 	  "O",
214*38fd1498Szrj 	  "P",
215*38fd1498Szrj 	  "Q",
216*38fd1498Szrj 	  "R",
217*38fd1498Szrj 	  "S",
218*38fd1498Szrj 	  "T",
219*38fd1498Szrj 	  "U",
220*38fd1498Szrj 	  "V",
221*38fd1498Szrj 	  "W",
222*38fd1498Szrj 	  "X",
223*38fd1498Szrj 	  "Y",
224*38fd1498Szrj 	  "Z",
225*38fd1498Szrj 	  "left-square-bracket",
226*38fd1498Szrj 	  "backslash",
227*38fd1498Szrj 	  "right-square-bracket",
228*38fd1498Szrj 	  "circumflex",
229*38fd1498Szrj 	  "underscore",
230*38fd1498Szrj 	  "grave-accent",
231*38fd1498Szrj 	  "a",
232*38fd1498Szrj 	  "b",
233*38fd1498Szrj 	  "c",
234*38fd1498Szrj 	  "d",
235*38fd1498Szrj 	  "e",
236*38fd1498Szrj 	  "f",
237*38fd1498Szrj 	  "g",
238*38fd1498Szrj 	  "h",
239*38fd1498Szrj 	  "i",
240*38fd1498Szrj 	  "j",
241*38fd1498Szrj 	  "k",
242*38fd1498Szrj 	  "l",
243*38fd1498Szrj 	  "m",
244*38fd1498Szrj 	  "n",
245*38fd1498Szrj 	  "o",
246*38fd1498Szrj 	  "p",
247*38fd1498Szrj 	  "q",
248*38fd1498Szrj 	  "r",
249*38fd1498Szrj 	  "s",
250*38fd1498Szrj 	  "t",
251*38fd1498Szrj 	  "u",
252*38fd1498Szrj 	  "v",
253*38fd1498Szrj 	  "w",
254*38fd1498Szrj 	  "x",
255*38fd1498Szrj 	  "y",
256*38fd1498Szrj 	  "z",
257*38fd1498Szrj 	  "left-curly-bracket",
258*38fd1498Szrj 	  "vertical-line",
259*38fd1498Szrj 	  "right-curly-bracket",
260*38fd1498Szrj 	  "tilde",
261*38fd1498Szrj 	  "DEL",
262*38fd1498Szrj 	};
263*38fd1498Szrj 
264*38fd1498Szrj       string __s;
265*38fd1498Szrj       for (; __first != __last; ++__first)
266*38fd1498Szrj 	__s += __fctyp.narrow(*__first, 0);
267*38fd1498Szrj 
268*38fd1498Szrj       for (const auto& __it : __collatenames)
269*38fd1498Szrj 	if (__s == __it)
270*38fd1498Szrj 	  return string_type(1, __fctyp.widen(
271*38fd1498Szrj 	    static_cast<char>(&__it - __collatenames)));
272*38fd1498Szrj 
273*38fd1498Szrj       // TODO Add digraph support:
274*38fd1498Szrj       // http://boost.sourceforge.net/libs/regex/doc/collating_names.html
275*38fd1498Szrj 
276*38fd1498Szrj       return string_type();
277*38fd1498Szrj     }
278*38fd1498Szrj 
279*38fd1498Szrj   template<typename _Ch_type>
280*38fd1498Szrj   template<typename _Fwd_iter>
281*38fd1498Szrj     typename regex_traits<_Ch_type>::char_class_type
282*38fd1498Szrj     regex_traits<_Ch_type>::
lookup_classname(_Fwd_iter __first,_Fwd_iter __last,bool __icase) const283*38fd1498Szrj     lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const
284*38fd1498Szrj     {
285*38fd1498Szrj       typedef std::ctype<char_type> __ctype_type;
286*38fd1498Szrj       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
287*38fd1498Szrj 
288*38fd1498Szrj       // Mappings from class name to class mask.
289*38fd1498Szrj       static const pair<const char*, char_class_type> __classnames[] =
290*38fd1498Szrj       {
291*38fd1498Szrj 	{"d", ctype_base::digit},
292*38fd1498Szrj 	{"w", {ctype_base::alnum, _RegexMask::_S_under}},
293*38fd1498Szrj 	{"s", ctype_base::space},
294*38fd1498Szrj 	{"alnum", ctype_base::alnum},
295*38fd1498Szrj 	{"alpha", ctype_base::alpha},
296*38fd1498Szrj 	{"blank", ctype_base::blank},
297*38fd1498Szrj 	{"cntrl", ctype_base::cntrl},
298*38fd1498Szrj 	{"digit", ctype_base::digit},
299*38fd1498Szrj 	{"graph", ctype_base::graph},
300*38fd1498Szrj 	{"lower", ctype_base::lower},
301*38fd1498Szrj 	{"print", ctype_base::print},
302*38fd1498Szrj 	{"punct", ctype_base::punct},
303*38fd1498Szrj 	{"space", ctype_base::space},
304*38fd1498Szrj 	{"upper", ctype_base::upper},
305*38fd1498Szrj 	{"xdigit", ctype_base::xdigit},
306*38fd1498Szrj       };
307*38fd1498Szrj 
308*38fd1498Szrj       string __s;
309*38fd1498Szrj       for (; __first != __last; ++__first)
310*38fd1498Szrj 	__s += __fctyp.narrow(__fctyp.tolower(*__first), 0);
311*38fd1498Szrj 
312*38fd1498Szrj       for (const auto& __it : __classnames)
313*38fd1498Szrj 	if (__s == __it.first)
314*38fd1498Szrj 	  {
315*38fd1498Szrj 	    if (__icase
316*38fd1498Szrj 		&& ((__it.second
317*38fd1498Szrj 		     & (ctype_base::lower | ctype_base::upper)) != 0))
318*38fd1498Szrj 	      return ctype_base::alpha;
319*38fd1498Szrj 	    return __it.second;
320*38fd1498Szrj 	  }
321*38fd1498Szrj       return 0;
322*38fd1498Szrj     }
323*38fd1498Szrj 
324*38fd1498Szrj   template<typename _Ch_type>
325*38fd1498Szrj     bool
326*38fd1498Szrj     regex_traits<_Ch_type>::
isctype(_Ch_type __c,char_class_type __f) const327*38fd1498Szrj     isctype(_Ch_type __c, char_class_type __f) const
328*38fd1498Szrj     {
329*38fd1498Szrj       typedef std::ctype<char_type> __ctype_type;
330*38fd1498Szrj       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
331*38fd1498Szrj 
332*38fd1498Szrj       return __fctyp.is(__f._M_base, __c)
333*38fd1498Szrj 	// [[:w:]]
334*38fd1498Szrj 	|| ((__f._M_extended & _RegexMask::_S_under)
335*38fd1498Szrj 	    && __c == __fctyp.widen('_'));
336*38fd1498Szrj     }
337*38fd1498Szrj 
338*38fd1498Szrj   template<typename _Ch_type>
339*38fd1498Szrj     int
340*38fd1498Szrj     regex_traits<_Ch_type>::
value(_Ch_type __ch,int __radix) const341*38fd1498Szrj     value(_Ch_type __ch, int __radix) const
342*38fd1498Szrj     {
343*38fd1498Szrj       std::basic_istringstream<char_type> __is(string_type(1, __ch));
344*38fd1498Szrj       long __v;
345*38fd1498Szrj       if (__radix == 8)
346*38fd1498Szrj 	__is >> std::oct;
347*38fd1498Szrj       else if (__radix == 16)
348*38fd1498Szrj 	__is >> std::hex;
349*38fd1498Szrj       __is >> __v;
350*38fd1498Szrj       return __is.fail() ? -1 : __v;
351*38fd1498Szrj     }
352*38fd1498Szrj 
353*38fd1498Szrj   template<typename _Bi_iter, typename _Alloc>
354*38fd1498Szrj   template<typename _Out_iter>
355*38fd1498Szrj     _Out_iter 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) const356*38fd1498Szrj     format(_Out_iter __out,
357*38fd1498Szrj 	   const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first,
358*38fd1498Szrj 	   const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last,
359*38fd1498Szrj 	   match_flag_type __flags) const
360*38fd1498Szrj     {
361*38fd1498Szrj       __glibcxx_assert( ready() );
362*38fd1498Szrj       regex_traits<char_type> __traits;
363*38fd1498Szrj       typedef std::ctype<char_type> __ctype_type;
364*38fd1498Szrj       const __ctype_type&
365*38fd1498Szrj 	__fctyp(use_facet<__ctype_type>(__traits.getloc()));
366*38fd1498Szrj 
367*38fd1498Szrj       auto __output = [&](size_t __idx)
368*38fd1498Szrj 	{
369*38fd1498Szrj 	  auto& __sub = (*this)[__idx];
370*38fd1498Szrj 	  if (__sub.matched)
371*38fd1498Szrj 	    __out = std::copy(__sub.first, __sub.second, __out);
372*38fd1498Szrj 	};
373*38fd1498Szrj 
374*38fd1498Szrj       if (__flags & regex_constants::format_sed)
375*38fd1498Szrj 	{
376*38fd1498Szrj 	  bool __escaping = false;
377*38fd1498Szrj 	  for (; __fmt_first != __fmt_last; __fmt_first++)
378*38fd1498Szrj 	    {
379*38fd1498Szrj 	      if (__escaping)
380*38fd1498Szrj 		{
381*38fd1498Szrj 		  __escaping = false;
382*38fd1498Szrj 		  if (__fctyp.is(__ctype_type::digit, *__fmt_first))
383*38fd1498Szrj 		    __output(__traits.value(*__fmt_first, 10));
384*38fd1498Szrj 		  else
385*38fd1498Szrj 		    *__out++ = *__fmt_first;
386*38fd1498Szrj 		  continue;
387*38fd1498Szrj 		}
388*38fd1498Szrj 	      if (*__fmt_first == '\\')
389*38fd1498Szrj 		{
390*38fd1498Szrj 		  __escaping = true;
391*38fd1498Szrj 		  continue;
392*38fd1498Szrj 		}
393*38fd1498Szrj 	      if (*__fmt_first == '&')
394*38fd1498Szrj 		{
395*38fd1498Szrj 		  __output(0);
396*38fd1498Szrj 		  continue;
397*38fd1498Szrj 		}
398*38fd1498Szrj 	      *__out++ = *__fmt_first;
399*38fd1498Szrj 	    }
400*38fd1498Szrj 	  if (__escaping)
401*38fd1498Szrj 	    *__out++ = '\\';
402*38fd1498Szrj 	}
403*38fd1498Szrj       else
404*38fd1498Szrj 	{
405*38fd1498Szrj 	  while (1)
406*38fd1498Szrj 	    {
407*38fd1498Szrj 	      auto __next = std::find(__fmt_first, __fmt_last, '$');
408*38fd1498Szrj 	      if (__next == __fmt_last)
409*38fd1498Szrj 		break;
410*38fd1498Szrj 
411*38fd1498Szrj 	      __out = std::copy(__fmt_first, __next, __out);
412*38fd1498Szrj 
413*38fd1498Szrj 	      auto __eat = [&](char __ch) -> bool
414*38fd1498Szrj 		{
415*38fd1498Szrj 		  if (*__next == __ch)
416*38fd1498Szrj 		    {
417*38fd1498Szrj 		      ++__next;
418*38fd1498Szrj 		      return true;
419*38fd1498Szrj 		    }
420*38fd1498Szrj 		  return false;
421*38fd1498Szrj 		};
422*38fd1498Szrj 
423*38fd1498Szrj 	      if (++__next == __fmt_last)
424*38fd1498Szrj 		*__out++ = '$';
425*38fd1498Szrj 	      else if (__eat('$'))
426*38fd1498Szrj 		*__out++ = '$';
427*38fd1498Szrj 	      else if (__eat('&'))
428*38fd1498Szrj 		__output(0);
429*38fd1498Szrj 	      else if (__eat('`'))
430*38fd1498Szrj 		{
431*38fd1498Szrj 		  auto& __sub = _M_prefix();
432*38fd1498Szrj 		  if (__sub.matched)
433*38fd1498Szrj 		    __out = std::copy(__sub.first, __sub.second, __out);
434*38fd1498Szrj 		}
435*38fd1498Szrj 	      else if (__eat('\''))
436*38fd1498Szrj 		{
437*38fd1498Szrj 		  auto& __sub = _M_suffix();
438*38fd1498Szrj 		  if (__sub.matched)
439*38fd1498Szrj 		    __out = std::copy(__sub.first, __sub.second, __out);
440*38fd1498Szrj 		}
441*38fd1498Szrj 	      else if (__fctyp.is(__ctype_type::digit, *__next))
442*38fd1498Szrj 		{
443*38fd1498Szrj 		  long __num = __traits.value(*__next, 10);
444*38fd1498Szrj 		  if (++__next != __fmt_last
445*38fd1498Szrj 		      && __fctyp.is(__ctype_type::digit, *__next))
446*38fd1498Szrj 		    {
447*38fd1498Szrj 		      __num *= 10;
448*38fd1498Szrj 		      __num += __traits.value(*__next++, 10);
449*38fd1498Szrj 		    }
450*38fd1498Szrj 		  if (0 <= __num && __num < this->size())
451*38fd1498Szrj 		    __output(__num);
452*38fd1498Szrj 		}
453*38fd1498Szrj 	      else
454*38fd1498Szrj 		*__out++ = '$';
455*38fd1498Szrj 	      __fmt_first = __next;
456*38fd1498Szrj 	    }
457*38fd1498Szrj 	  __out = std::copy(__fmt_first, __fmt_last, __out);
458*38fd1498Szrj 	}
459*38fd1498Szrj       return __out;
460*38fd1498Szrj     }
461*38fd1498Szrj 
462*38fd1498Szrj   template<typename _Out_iter, typename _Bi_iter,
463*38fd1498Szrj 	   typename _Rx_traits, typename _Ch_type>
464*38fd1498Szrj     _Out_iter
465*38fd1498Szrj     regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
466*38fd1498Szrj 		  const basic_regex<_Ch_type, _Rx_traits>& __e,
467*38fd1498Szrj 		  const _Ch_type* __fmt,
468*38fd1498Szrj 		  regex_constants::match_flag_type __flags)
469*38fd1498Szrj     {
470*38fd1498Szrj       typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT;
471*38fd1498Szrj       _IterT __i(__first, __last, __e, __flags);
472*38fd1498Szrj       _IterT __end;
473*38fd1498Szrj       if (__i == __end)
474*38fd1498Szrj 	{
475*38fd1498Szrj 	  if (!(__flags & regex_constants::format_no_copy))
476*38fd1498Szrj 	    __out = std::copy(__first, __last, __out);
477*38fd1498Szrj 	}
478*38fd1498Szrj       else
479*38fd1498Szrj 	{
480*38fd1498Szrj 	  sub_match<_Bi_iter> __last;
481*38fd1498Szrj 	  auto __len = char_traits<_Ch_type>::length(__fmt);
482*38fd1498Szrj 	  for (; __i != __end; ++__i)
483*38fd1498Szrj 	    {
484*38fd1498Szrj 	      if (!(__flags & regex_constants::format_no_copy))
485*38fd1498Szrj 		__out = std::copy(__i->prefix().first, __i->prefix().second,
486*38fd1498Szrj 				  __out);
487*38fd1498Szrj 	      __out = __i->format(__out, __fmt, __fmt + __len, __flags);
488*38fd1498Szrj 	      __last = __i->suffix();
489*38fd1498Szrj 	      if (__flags & regex_constants::format_first_only)
490*38fd1498Szrj 		break;
491*38fd1498Szrj 	    }
492*38fd1498Szrj 	  if (!(__flags & regex_constants::format_no_copy))
493*38fd1498Szrj 	    __out = std::copy(__last.first, __last.second, __out);
494*38fd1498Szrj 	}
495*38fd1498Szrj       return __out;
496*38fd1498Szrj     }
497*38fd1498Szrj 
498*38fd1498Szrj   template<typename _Bi_iter,
499*38fd1498Szrj 	   typename _Ch_type,
500*38fd1498Szrj 	   typename _Rx_traits>
501*38fd1498Szrj     bool
502*38fd1498Szrj     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ==(const regex_iterator & __rhs) const503*38fd1498Szrj     operator==(const regex_iterator& __rhs) const
504*38fd1498Szrj     {
505*38fd1498Szrj       if (_M_pregex == nullptr && __rhs._M_pregex == nullptr)
506*38fd1498Szrj 	return true;
507*38fd1498Szrj       return _M_pregex == __rhs._M_pregex
508*38fd1498Szrj 	  && _M_begin == __rhs._M_begin
509*38fd1498Szrj 	  && _M_end == __rhs._M_end
510*38fd1498Szrj 	  && _M_flags == __rhs._M_flags
511*38fd1498Szrj 	  && _M_match[0] == __rhs._M_match[0];
512*38fd1498Szrj     }
513*38fd1498Szrj 
514*38fd1498Szrj   template<typename _Bi_iter,
515*38fd1498Szrj 	   typename _Ch_type,
516*38fd1498Szrj 	   typename _Rx_traits>
517*38fd1498Szrj     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
518*38fd1498Szrj     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ++()519*38fd1498Szrj     operator++()
520*38fd1498Szrj     {
521*38fd1498Szrj       // In all cases in which the call to regex_search returns true,
522*38fd1498Szrj       // match.prefix().first shall be equal to the previous value of
523*38fd1498Szrj       // match[0].second, and for each index i in the half-open range
524*38fd1498Szrj       // [0, match.size()) for which match[i].matched is true,
525*38fd1498Szrj       // match[i].position() shall return distance(begin, match[i].first).
526*38fd1498Szrj       // [28.12.1.4.5]
527*38fd1498Szrj       if (_M_match[0].matched)
528*38fd1498Szrj 	{
529*38fd1498Szrj 	  auto __start = _M_match[0].second;
530*38fd1498Szrj 	  auto __prefix_first = _M_match[0].second;
531*38fd1498Szrj 	  if (_M_match[0].first == _M_match[0].second)
532*38fd1498Szrj 	    {
533*38fd1498Szrj 	      if (__start == _M_end)
534*38fd1498Szrj 		{
535*38fd1498Szrj 		  _M_pregex = nullptr;
536*38fd1498Szrj 		  return *this;
537*38fd1498Szrj 		}
538*38fd1498Szrj 	      else
539*38fd1498Szrj 		{
540*38fd1498Szrj 		  if (regex_search(__start, _M_end, _M_match, *_M_pregex,
541*38fd1498Szrj 				   _M_flags
542*38fd1498Szrj 				   | regex_constants::match_not_null
543*38fd1498Szrj 				   | regex_constants::match_continuous))
544*38fd1498Szrj 		    {
545*38fd1498Szrj 		      __glibcxx_assert(_M_match[0].matched);
546*38fd1498Szrj 		      auto& __prefix = _M_match._M_prefix();
547*38fd1498Szrj 		      __prefix.first = __prefix_first;
548*38fd1498Szrj 		      __prefix.matched = __prefix.first != __prefix.second;
549*38fd1498Szrj 		      // [28.12.1.4.5]
550*38fd1498Szrj 		      _M_match._M_begin = _M_begin;
551*38fd1498Szrj 		      return *this;
552*38fd1498Szrj 		    }
553*38fd1498Szrj 		  else
554*38fd1498Szrj 		    ++__start;
555*38fd1498Szrj 		}
556*38fd1498Szrj 	    }
557*38fd1498Szrj 	  _M_flags |= regex_constants::match_prev_avail;
558*38fd1498Szrj 	  if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
559*38fd1498Szrj 	    {
560*38fd1498Szrj 	      __glibcxx_assert(_M_match[0].matched);
561*38fd1498Szrj 	      auto& __prefix = _M_match._M_prefix();
562*38fd1498Szrj 	      __prefix.first = __prefix_first;
563*38fd1498Szrj 	      __prefix.matched = __prefix.first != __prefix.second;
564*38fd1498Szrj 	      // [28.12.1.4.5]
565*38fd1498Szrj 	      _M_match._M_begin = _M_begin;
566*38fd1498Szrj 	    }
567*38fd1498Szrj 	  else
568*38fd1498Szrj 	    _M_pregex = nullptr;
569*38fd1498Szrj 	}
570*38fd1498Szrj       return *this;
571*38fd1498Szrj     }
572*38fd1498Szrj 
573*38fd1498Szrj   template<typename _Bi_iter,
574*38fd1498Szrj 	   typename _Ch_type,
575*38fd1498Szrj 	   typename _Rx_traits>
576*38fd1498Szrj     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
577*38fd1498Szrj     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator =(const regex_token_iterator & __rhs)578*38fd1498Szrj     operator=(const regex_token_iterator& __rhs)
579*38fd1498Szrj     {
580*38fd1498Szrj       _M_position = __rhs._M_position;
581*38fd1498Szrj       _M_subs = __rhs._M_subs;
582*38fd1498Szrj       _M_n = __rhs._M_n;
583*38fd1498Szrj       _M_suffix = __rhs._M_suffix;
584*38fd1498Szrj       _M_has_m1 = __rhs._M_has_m1;
585*38fd1498Szrj       _M_normalize_result();
586*38fd1498Szrj       return *this;
587*38fd1498Szrj     }
588*38fd1498Szrj 
589*38fd1498Szrj   template<typename _Bi_iter,
590*38fd1498Szrj 	   typename _Ch_type,
591*38fd1498Szrj 	   typename _Rx_traits>
592*38fd1498Szrj     bool
593*38fd1498Szrj     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ==(const regex_token_iterator & __rhs) const594*38fd1498Szrj     operator==(const regex_token_iterator& __rhs) const
595*38fd1498Szrj     {
596*38fd1498Szrj       if (_M_end_of_seq() && __rhs._M_end_of_seq())
597*38fd1498Szrj 	return true;
598*38fd1498Szrj       if (_M_suffix.matched && __rhs._M_suffix.matched
599*38fd1498Szrj 	  && _M_suffix == __rhs._M_suffix)
600*38fd1498Szrj 	return true;
601*38fd1498Szrj       if (_M_end_of_seq() || _M_suffix.matched
602*38fd1498Szrj 	  || __rhs._M_end_of_seq() || __rhs._M_suffix.matched)
603*38fd1498Szrj 	return false;
604*38fd1498Szrj       return _M_position == __rhs._M_position
605*38fd1498Szrj 	&& _M_n == __rhs._M_n
606*38fd1498Szrj 	&& _M_subs == __rhs._M_subs;
607*38fd1498Szrj     }
608*38fd1498Szrj 
609*38fd1498Szrj   template<typename _Bi_iter,
610*38fd1498Szrj 	   typename _Ch_type,
611*38fd1498Szrj 	   typename _Rx_traits>
612*38fd1498Szrj     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
613*38fd1498Szrj     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator ++()614*38fd1498Szrj     operator++()
615*38fd1498Szrj     {
616*38fd1498Szrj       _Position __prev = _M_position;
617*38fd1498Szrj       if (_M_suffix.matched)
618*38fd1498Szrj 	*this = regex_token_iterator();
619*38fd1498Szrj       else if (_M_n + 1 < _M_subs.size())
620*38fd1498Szrj 	{
621*38fd1498Szrj 	  _M_n++;
622*38fd1498Szrj 	  _M_result = &_M_current_match();
623*38fd1498Szrj 	}
624*38fd1498Szrj       else
625*38fd1498Szrj 	{
626*38fd1498Szrj 	  _M_n = 0;
627*38fd1498Szrj 	  ++_M_position;
628*38fd1498Szrj 	  if (_M_position != _Position())
629*38fd1498Szrj 	    _M_result = &_M_current_match();
630*38fd1498Szrj 	  else if (_M_has_m1 && __prev->suffix().length() != 0)
631*38fd1498Szrj 	    {
632*38fd1498Szrj 	      _M_suffix.matched = true;
633*38fd1498Szrj 	      _M_suffix.first = __prev->suffix().first;
634*38fd1498Szrj 	      _M_suffix.second = __prev->suffix().second;
635*38fd1498Szrj 	      _M_result = &_M_suffix;
636*38fd1498Szrj 	    }
637*38fd1498Szrj 	  else
638*38fd1498Szrj 	    *this = regex_token_iterator();
639*38fd1498Szrj 	}
640*38fd1498Szrj       return *this;
641*38fd1498Szrj     }
642*38fd1498Szrj 
643*38fd1498Szrj   template<typename _Bi_iter,
644*38fd1498Szrj 	   typename _Ch_type,
645*38fd1498Szrj 	   typename _Rx_traits>
646*38fd1498Szrj     void
647*38fd1498Szrj     regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
_M_init(_Bi_iter __a,_Bi_iter __b)648*38fd1498Szrj     _M_init(_Bi_iter __a, _Bi_iter __b)
649*38fd1498Szrj     {
650*38fd1498Szrj       _M_has_m1 = false;
651*38fd1498Szrj       for (auto __it : _M_subs)
652*38fd1498Szrj 	if (__it == -1)
653*38fd1498Szrj 	  {
654*38fd1498Szrj 	    _M_has_m1 = true;
655*38fd1498Szrj 	    break;
656*38fd1498Szrj 	  }
657*38fd1498Szrj       if (_M_position != _Position())
658*38fd1498Szrj 	_M_result = &_M_current_match();
659*38fd1498Szrj       else if (_M_has_m1)
660*38fd1498Szrj 	{
661*38fd1498Szrj 	  _M_suffix.matched = true;
662*38fd1498Szrj 	  _M_suffix.first = __a;
663*38fd1498Szrj 	  _M_suffix.second = __b;
664*38fd1498Szrj 	  _M_result = &_M_suffix;
665*38fd1498Szrj 	}
666*38fd1498Szrj       else
667*38fd1498Szrj 	_M_result = nullptr;
668*38fd1498Szrj     }
669*38fd1498Szrj 
670*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
671*38fd1498Szrj } // namespace
672