On Fri, Apr 25, 2025 at 9:47 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> This will hardly make a dent in the very slow compile times for <regex>
> but it seems worth doing anyway.
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/regex_compiler.h (_AnyMatcher::operator()):
>         Replace tag dispatching with 'if constexpr'.
>         (_AnyMatcher::_M_apply): Remove both overloads.
>         (_BracketMatcher::operator(), _BracketMatcher::_M_ready):
>         Replace tag dispatching with 'if constexpr'.
>         (_BracketMatcher::_M_apply(_CharT, true_type)): Remove.
>         (_BracketMatcher::_M_apply(_CharT, false_type)): Remove second
>         parameter.
>         (_BracketMatcher::_M_make_cache): Remove both overloads.
>         * include/bits/regex_compiler.tcc (_BracketMatcher::_M_apply):
>         Remove second parameter.
> ---
>
> Tested x86_64-linux.
>
>  libstdc++-v3/include/bits/regex_compiler.h   | 59 +++++++++-----------
>  libstdc++-v3/include/bits/regex_compiler.tcc |  2 +-
>  2 files changed, 26 insertions(+), 35 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/regex_compiler.h
> b/libstdc++-v3/include/bits/regex_compiler.h
> index f24c7e3baa6..3931790091a 100644
> --- a/libstdc++-v3/include/bits/regex_compiler.h
> +++ b/libstdc++-v3/include/bits/regex_compiler.h
> @@ -376,26 +376,21 @@ namespace __detail
>
>        bool
>        operator()(_CharT __ch) const
> -      { return _M_apply(__ch, typename is_same<_CharT, char>::type()); }
> -
> -      bool
> -      _M_apply(_CharT __ch, true_type) const
>        {
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
>         auto __c = _M_translator._M_translate(__ch);
>         auto __n = _M_translator._M_translate('\n');
>         auto __r = _M_translator._M_translate('\r');
> -       return __c != __n && __c != __r;
> -      }
> -
> -      bool
> -      _M_apply(_CharT __ch, false_type) const
> -      {
> -       auto __c = _M_translator._M_translate(__ch);
> -       auto __n = _M_translator._M_translate('\n');
> -       auto __r = _M_translator._M_translate('\r');
> -       auto __u2028 = _M_translator._M_translate(u'\u2028');
> -       auto __u2029 = _M_translator._M_translate(u'\u2029');
> -       return __c != __n && __c != __r && __c != __u2028 && __c !=
> __u2029;
>
Could we implement this as, to avoid calling _M_translate when not
necessary?
```
if (__c == __n || __c == __r)
  return false;
if constexpr (!is_same<_CharT, char>::value)
   {
      auto __ls = _M_translator._M_translate(u'\u2028'); // line sep
     auto __ps = _M_translator._M_translate(u'\u2029'); // para sep
     return __c != __ls && __c != __ps;
}
return true;

```

> +       if constexpr (is_same<_CharT, char>::value)
> +         return __c != __n && __c != __r;
> +       else
> +         {
> +           auto __ls = _M_translator._M_translate(u'\u2028'); // line sep
> +           auto __ps = _M_translator._M_translate(u'\u2029'); // para sep
> +           return __c != __n && __c != __r && __c != __ls && __c != __ps;
> +         }
> +#pragma GCC diagnostic pop
>        }
>
>        _TransT _M_translator;
> @@ -440,8 +435,14 @@ namespace __detail
>        bool
>        operator()(_CharT __ch) const
>        {
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
>         _GLIBCXX_DEBUG_ASSERT(_M_is_ready);
> -       return _M_apply(__ch, _UseCache());
> +       if constexpr (_UseCache::value)
> +         if (!(__ch & 0x80)) [[__likely__]]
> +           return _M_cache[static_cast<_UnsignedCharT>(__ch)];
> +       return _M_apply(__ch);
> +#pragma GCC diagnostic pop
>        }
>
>        void
> @@ -509,11 +510,16 @@ namespace __detail
>        void
>        _M_ready()
>        {
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
>         std::sort(_M_char_set.begin(), _M_char_set.end());
>         auto __end = std::unique(_M_char_set.begin(), _M_char_set.end());
>         _M_char_set.erase(__end, _M_char_set.end());
> -       _M_make_cache(_UseCache());
> +       if constexpr (_UseCache::value)
> +         for (unsigned __i = 0; __i < 128; __i++) // Only cache 7-bit
> chars
> +           _M_cache[__i] = _M_apply(static_cast<_CharT>(__i));
>         _GLIBCXX_DEBUG_ONLY(_M_is_ready = true);
> +#pragma GCC diagnostic pop
>        }
>
>      private:
> @@ -531,22 +537,7 @@ namespace __detail
>        using _UnsignedCharT = typename std::make_unsigned<_CharT>::type;
>
>        bool
> -      _M_apply(_CharT __ch, false_type) const;
> -
> -      bool
> -      _M_apply(_CharT __ch, true_type) const
> -      { return _M_cache[static_cast<_UnsignedCharT>(__ch)]; }
> -
> -      void
> -      _M_make_cache(true_type)
> -      {
> -       for (unsigned __i = 0; __i < _M_cache.size(); __i++)
> -         _M_cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type());
> -      }
> -
> -      void
> -      _M_make_cache(false_type)
> -      { }
> +      _M_apply(_CharT __ch) const;
>
>      private:
>        _GLIBCXX_STD_C::vector<_CharT>            _M_char_set;
> diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc
> b/libstdc++-v3/include/bits/regex_compiler.tcc
> index cd0db2761b5..59b79fdd106 100644
> --- a/libstdc++-v3/include/bits/regex_compiler.tcc
> +++ b/libstdc++-v3/include/bits/regex_compiler.tcc
> @@ -598,7 +598,7 @@ namespace __detail
>    template<typename _TraitsT, bool __icase, bool __collate>
>      bool
>      _BracketMatcher<_TraitsT, __icase, __collate>::
> -    _M_apply(_CharT __ch, false_type) const
> +    _M_apply(_CharT __ch) const
>      {
>        return [this, __ch]
>        {
> --
> 2.49.0
>
>

Reply via email to