On Thu, Sep 11, 2025 at 2:18 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> These _S_noexcept() functions are only used in noexcept-specifiers and
> never need to be called at runtime. They can be immediate functions,
> i.e. consteval.
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/iterator_concepts.h (_IterMove::_S_noexcept)
>         (_IterSwap::_S_noexcept): Change constexpr to consteval.
>         * include/bits/ranges_base.h (_Begin::_S_noexcept)
>         (_End::_S_noexcept, _RBegin::_S_noexcept, _REnd::_S_noexcept)
>         (_Size::_S_noexcept, _Empty::_S_noexcept, _Data::_S_noexcept):
>         Likewise.
>         * include/std/concepts (_Swap::_S_noexcept): Likewise.
> ---
>
> Tested powerpc64-linux.
>
Also LGTM. Thanks.

>
>  libstdc++-v3/include/bits/iterator_concepts.h |  4 ++--
>  libstdc++-v3/include/bits/ranges_base.h       | 14 +++++++-------
>  libstdc++-v3/include/std/concepts             |  2 +-
>  3 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/iterator_concepts.h
> b/libstdc++-v3/include/bits/iterator_concepts.h
> index 979039e7da53..fd91b22d75a5 100644
> --- a/libstdc++-v3/include/bits/iterator_concepts.h
> +++ b/libstdc++-v3/include/bits/iterator_concepts.h
> @@ -141,21 +141,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>           {
>             // Instead of decltype(std::move(*E)) we define the type as the
>             // return type of std::move, i.e.
> remove_reference_t<iter_ref>&&.
>             // N.B. the use of decltype(declval<X>()) instead of just X&&
> is
>             // needed for function reference types, see PR
> libstdc++/119469.
>             using type
>               =
> decltype(std::declval<remove_reference_t<__iter_ref_t<_Tp>>>());
>           };
>
>         template<typename _Tp>
> -         static constexpr bool
> +         static consteval bool
>           _S_noexcept()
>           {
>             if constexpr (__adl_imove<_Tp>)
>               return noexcept(iter_move(std::declval<_Tp>()));
>             else
>               return noexcept(*std::declval<_Tp>());
>           }
>
>        public:
>         // The result type of iter_move(std::declval<_Tp>())
> @@ -877,21 +877,21 @@ namespace ranges
>        {
>         iter_value_t<_Xp> __old_value(iter_move(__x));
>         *__x = iter_move(__y);
>         return __old_value;
>        }
>
>      struct _IterSwap
>      {
>      private:
>        template<typename _Tp, typename _Up>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (__adl_iswap<_Tp, _Up>)
>             return noexcept(iter_swap(std::declval<_Tp>(),
>                                       std::declval<_Up>()));
>           else if constexpr (indirectly_readable<_Tp>
>               && indirectly_readable<_Up>
>               && swappable_with<iter_reference_t<_Tp>,
> iter_reference_t<_Up>>)
>             return noexcept(ranges::swap(*std::declval<_Tp>(),
>                                          *std::declval<_Up>()));
> diff --git a/libstdc++-v3/include/bits/ranges_base.h
> b/libstdc++-v3/include/bits/ranges_base.h
> index c1a9f6a90009..1c4bf432c8f4 100644
> --- a/libstdc++-v3/include/bits/ranges_base.h
> +++ b/libstdc++-v3/include/bits/ranges_base.h
> @@ -99,21 +99,21 @@ namespace ranges
>    // Namespace for helpers for the <ranges> customization points.
>    namespace __access
>    {
>      using std::ranges::__detail::__maybe_borrowed_range;
>      using std::__detail::__range_iter_t;
>
>      struct _Begin
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (is_array_v<remove_reference_t<_Tp>>)
>             return true;
>           else if constexpr (__member_begin<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().begin()));
>           else
>             return
> noexcept(_GLIBCXX_AUTO_CAST(begin(std::declval<_Tp&>())));
>         }
>
> @@ -150,21 +150,21 @@ namespace ranges
>        concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
>         && requires(_Tp& __t)
>         {
>           { _GLIBCXX_AUTO_CAST(end(__t)) } ->
> sentinel_for<__range_iter_t<_Tp>>;
>         };
>
>      struct _End
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
>             return true;
>           else if constexpr (__member_end<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().end()));
>           else
>             return noexcept(_GLIBCXX_AUTO_CAST(end(std::declval<_Tp&>())));
>         }
>
> @@ -207,21 +207,21 @@ namespace ranges
>        concept __reversable = requires(_Tp& __t)
>         {
>           { _Begin{}(__t) } -> bidirectional_iterator;
>           { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
>         };
>
>      struct _RBegin
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (__member_rbegin<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().rbegin()));
>           else if constexpr (__adl_rbegin<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(rbegin(std::declval<_Tp&>())));
>           else
>             {
>               if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
>                 {
> @@ -265,21 +265,21 @@ namespace ranges
>         && requires(_Tp& __t)
>         {
>           { _GLIBCXX_AUTO_CAST(rend(__t)) }
>             -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
>         };
>
>      struct _REnd
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (__member_rend<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().rend()));
>           else if constexpr (__adl_rend<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(rend(std::declval<_Tp&>())));
>           else
>             {
>               if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
>                 {
> @@ -335,21 +335,21 @@ namespace ranges
>
>           { _End{}(__t) } -> sized_sentinel_for<decltype(_Begin{}(__t))>;
>
>           __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
>         };
>
>      struct _Size
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
>             return true;
>           else if constexpr (__member_size<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().size()));
>           else if constexpr (__adl_size<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(size(std::declval<_Tp&>())));
>           else if constexpr (__sentinel_size<_Tp>)
>             return noexcept(_End{}(std::declval<_Tp&>())
> @@ -415,21 +415,21 @@ namespace ranges
>
>           { _Begin{}(__t) } -> forward_iterator;
>
>           bool(_Begin{}(__t) == _End{}(__t));
>         };
>
>      struct _Empty
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (__member_empty<_Tp>)
>             return noexcept(bool(std::declval<_Tp&>().empty()));
>           else if constexpr (__size0_empty<_Tp>)
>             return noexcept(_Size{}(std::declval<_Tp&>()) == 0);
>           else
>             return noexcept(bool(_Begin{}(std::declval<_Tp&>())
>                 == _End{}(std::declval<_Tp&>())));
>         }
> @@ -461,21 +461,21 @@ namespace ranges
>           { _GLIBCXX_AUTO_CAST(__t.data()) } -> __pointer_to_object;
>         };
>
>      template<typename _Tp>
>        concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>;
>
>      struct _Data
>      {
>      private:
>        template<typename _Tp>
> -       static constexpr bool
> +       static consteval bool
>         _S_noexcept()
>         {
>           if constexpr (__member_data<_Tp>)
>             return
> noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().data()));
>           else
>             return noexcept(_Begin{}(std::declval<_Tp&>()));
>         }
>
>      public:
>        template<__maybe_borrowed_range _Tp>
> diff --git a/libstdc++-v3/include/std/concepts
> b/libstdc++-v3/include/std/concepts
> index 5899f032434a..d9920a8f20a8 100644
> --- a/libstdc++-v3/include/std/concepts
> +++ b/libstdc++-v3/include/std/concepts
> @@ -197,21 +197,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>           = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>
>             || std::__detail::__class_or_enum<remove_reference_t<_Up>>)
>           && requires(_Tp&& __t, _Up&& __u) {
>             swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
>           };
>
>        struct _Swap
>        {
>        private:
>         template<typename _Tp, typename _Up>
> -         static constexpr bool
> +         static consteval bool
>           _S_noexcept()
>           {
>             if constexpr (__adl_swap<_Tp, _Up>)
>               return noexcept(swap(std::declval<_Tp>(),
> std::declval<_Up>()));
>             else
>               return
> is_nothrow_move_constructible_v<remove_reference_t<_Tp>>
>                    &&
> is_nothrow_move_assignable_v<remove_reference_t<_Tp>>;
>           }
>
>        public:
> --
> 2.51.0
>
>

Reply via email to