https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126274

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
And this optimization for std::regex_replace in the case where the matches are
replaced with a fixed string, not something like "extra text \1 extra text"
that refers to one of the matched groups.

--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -566,6 +566,16 @@ namespace __detail
                    const _Ch_type* __fmt, size_t __len,
                    regex_constants::match_flag_type __flags)
     {
+      bool __trivial_fmt = false;
+      if (__flags & regex_constants::format_sed)
+       {
+         if (char_traits<_Ch_type>::find(__fmt, __len, '\\') == nullptr
+               && char_traits<_Ch_type>::find(__fmt, __len, '&') == nullptr)
+           __trivial_fmt = true;
+       }
+      else if (char_traits<_Ch_type>::find(__fmt, __len, '$') == nullptr)
+       __trivial_fmt = true;
+
       typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT;
       _IterT __i(__first, __last, __e, __flags);
       _IterT __end;
@@ -582,7 +592,10 @@ namespace __detail
              if (!(__flags & regex_constants::format_no_copy))
                __out = std::copy(__i->prefix().first, __i->prefix().second,
                                  __out);
-             __out = __i->format(__out, __fmt, __fmt + __len, __flags);
+             if (__trivial_fmt)
+               __out = std::copy(__fmt, __fmt + __len, __out);
+             else
+               __out = __i->format(__out, __fmt, __fmt + __len, __flags);
              __last = __i->suffix();
              if (__flags & regex_constants::format_first_only)
                break;

Reply via email to