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