On Wed, 04 Feb 2026 at 13:44 +0000, Jonathan Wakely wrote:
On Sun, 27 Jul 2025 at 21:27 +0100, Caolán McNamara wrote:
From: Caolán McNamara <[email protected]>

libstdc++-v3/ChangeLog:
  * include/bits/regex.tcc (__collatenames): Make array const.

Thanks for the patch. This arrived while I was (mostly) offline for a
month in the summer and I missed it.

The change is good, and I think it's safe to push now. I'll take care
of it.

Signed-off-by: Caolán McNamara <[email protected]>
---
libstdc++-v3/include/bits/regex.tcc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/regex.tcc 
b/libstdc++-v3/include/bits/regex.tcc
index b94fe4490f7..84c15597436 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -125,7 +125,7 @@ namespace __detail
     typedef std::ctype<char_type> __ctype_type;
     const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));

-      static const char* __collatenames[] =
+      static const char* const __collatenames[] =
        {
          "NUL",
          "SOH",
--
2.49.0




I've pushed this to trunk now, thanks again.

For GCC 17 I think we should refactor that function so that we don't
repeat that static array for every instantiation of regex_traits<C>,
something like this:


  template<typename _Ch_type>
  template<typename _Fwd_iter>
    typename regex_traits<_Ch_type>::string_type
    regex_traits<_Ch_type>::
    lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
    {
      // TODO Add digraph support:
      // http://boost.sourceforge.net/libs/regex/doc/collating_names.html

      if constexpr (is_same<_CharT, char>::value)
        {
          string __s(__first, __last);
          __detail::__lookup_collatename(__s);
          return __s;
        }
      else
        {
          typedef std::ctype<char_type> __ctype_type;
          const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));

          string __s;
          for (; __first != __last; ++__first)
            __s += __fctyp.narrow(*__first, 0);
          __detail::__lookup_collatename(__s);
          if (!__s.empty())
            return string_type(1, __fctyp.widen(__s[0]));
        }

      return string_type();
    }


Where __detail::__lookup_collatename is a non-template function like
this:

  inline void
  __lookup_collatename(string& __name)
  {
    static const char* const __collatenames[] =
      {
        "NUL",
        "SOH",
        ...
        "tilde",
        "DEL",
      };

    for (const auto& __it : __collatenames)
      if (__s == __it)
        {
          __s.assign(1, static_cast<char>(&__it - __collatenames));
          return;
        }

    __s.clear();
  }


This way we only call narrow/widen when we don't already have a string
of char, and we only emit that array of strings into the binary once.




Reply via email to