https://gcc.gnu.org/g:c55c1de3a9adb241e3c0dabd7d1edd8ebe9c065f
commit r16-4709-gc55c1de3a9adb241e3c0dabd7d1edd8ebe9c065f Author: Jonathan Wakely <[email protected]> Date: Tue Oct 28 12:15:52 2025 +0000 libstdc++: Simplify std::regex_traits::value We don't need to use an istringstream to convert a hex digit to its numerical value. And if we don't use istringstream there, we don't need to include <sstream> in <regex>. libstdc++-v3/ChangeLog: * include/bits/regex.tcc (regex_traits::value): Implement without using istringstream. * include/std/regex: Do not include <sstream>. Reviewed-by: Tomasz KamiĆski <[email protected]> Diff: --- libstdc++-v3/include/bits/regex.tcc | 49 +++++++++++++++++++++++++++++++------ libstdc++-v3/include/std/regex | 1 - 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index b94fe4490f7c..a0edf272717e 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -331,20 +331,53 @@ namespace __detail && __c == __fctyp.widen('_')); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr template<typename _Ch_type> int regex_traits<_Ch_type>:: value(_Ch_type __ch, int __radix) const { - std::basic_istringstream<char_type> __is(string_type(1, __ch)); - long __v; - if (__radix == 8) - __is >> std::oct; - else if (__radix == 16) - __is >> std::hex; - __is >> __v; - return __is.fail() ? -1 : __v; + if constexpr (sizeof(_Ch_type) > 1) + { + const auto& __ctyp = std::use_facet<ctype<_Ch_type>>(_M_locale); + const char __c = __ctyp.narrow(__ch, '\0'); + return regex_traits<char>{}.value(__c, __radix); + } + else + { + const char __c = static_cast<char>(__ch); + const char __max_digit = __radix == 8 ? '7' : '9'; + if ('0' <= __ch && __ch <= __max_digit) + return __ch - '0'; + if (__radix < 16) + return -1; + switch (__ch) + { + case 'a': + case 'A': + return 10; + case 'b': + case 'B': + return 11; + case 'c': + case 'C': + return 12; + case 'd': + case 'D': + return 13; + case 'e': + case 'E': + return 14; + case 'f': + case 'F': + return 15; + default: + return -1; + } + } } +#pragma GCC diagnostic pop template<typename _Bi_iter, typename _Alloc> template<typename _Out_iter> diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex index 022306621cba..9121d267a793 100644 --- a/libstdc++-v3/include/std/regex +++ b/libstdc++-v3/include/std/regex @@ -41,7 +41,6 @@ #include <bitset> #include <locale> -#include <sstream> #include <stack> #include <stdexcept> #include <string>
