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