]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Simplify std::regex_traits::value
authorJonathan Wakely <jwakely@redhat.com>
Tue, 28 Oct 2025 12:15:52 +0000 (12:15 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 29 Oct 2025 15:43:36 +0000 (15:43 +0000)
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 <tkaminsk@redhat.com>
libstdc++-v3/include/bits/regex.tcc
libstdc++-v3/include/std/regex

index b94fe4490f7ca8b5b567aa798c19f4cc5665f1f2..a0edf272717e38c815c6d5ce2d767e743e618135 100644 (file)
@@ -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>
index 022306621cba8de720f6a7bca2b2a141b0711a38..9121d267a79389d26f66cad152e0a87978ceb7ea 100644 (file)
@@ -41,7 +41,6 @@
 
 #include <bitset>
 #include <locale>
-#include <sstream>
 #include <stack>
 #include <stdexcept>
 #include <string>