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