On Mon, 18 Aug 2025 at 10:14, Tomasz Kamiński wrote:
>
> This patch adds the [[nodiscard]] attribute to the operator() of ranges
> algorithm function objects if their std counterpart has it.
>
> Furthermore, we [[nodiscard]] the operator() of the following ranges
> algorithms that lack a std counterpart:
> * find_last, find_last_if, find_last_if_not (to match other find
>   algorithms)
> * contains, contains_subrange (to match find/any_of and search)
>
> Finally, [[nodiscard]] is added to std::min and std::max overloads
> that accept std::initializer_list. This appears to be an oversight,
> as std::minmax is already marked, and other min overloads are as well.
> The same applies to corresponding operator() overloads of ranges::min and
> ranges::max.

Yes, I think that was just an oversight on my part.

>
>         PR libstdc++/121476
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/ranges_algo.h (__all_of_fn::operator()):
>         (__any_of_fn::operator(), __none_of_fn::operator())
>         (__find_first_of_fn::operator(), __count_fn::operator())
>         (__find_end_fn::operator(), __remove_if_fn::operator())
>         (__remove_fn::operator(), __unique_fn::operator())
>         (__is_sorted_until_fn::operator(), __is_sorted_fn::operator())
>         (__lower_bound_fn::operator(), __upper_bound_fn::operator())
>         (__equal_range_fn::operator(), __binary_search_fn::operator())
>         (__is_partitioned_fn::operator(), __partition_point_fn::operator())
>         (__minmax_fn::operator(), __min_element_fn::operator())
>         (__includes_fn::operator(), __max_fn::operator())
>         (__lexicographical_compare_fn::operator(), __clamp__fn::operator())
>         (__find_last_fn::operator(), __find_last_if_fn::operator())
>         (__find_last_if_not_fn::operator()): Add [[nodiscard]] attribute.
>         * include/bits/ranges_algobase.h (__equal_fn::operator()):
>         Add [[nodiscard]] attribute.
>         * include/bits/ranges_util.h (__find_fn::operator())
>         (__find_if_fn::operator(), __find_if_not_fn::operator())
>         (__mismatch_fn::operator(), __search_fn::operator())
>         (__min_fn::operator(), __adjacent_find_fn::operator()):
>         Add [[nodiscard]] attribute.
>         * include/bits/stl_algo.h (std::min(initializer_list<T>))
>         (std::min(initializer_list<T>, _Compare))
>         (std::max(initializer_list<T>))
>         (std::mmax(initializer_list<T>, _Compare)): Add _GLIBCXX_NODISCARD.
>         * testsuite/25_algorithms/min/constrained.cc: Silence nodiscard
>         warning.
>         * testsuite/25_algorithms/minmax/constrained.cc: Likewise.
>         * testsuite/25_algorithms/minmax_element/constrained.cc: Likewise.
> ---
> Tested on x86_64-linux locally.
> OK for trunk.
>
>  libstdc++-v3/include/bits/ranges_algo.h       | 118 +++++++++---------
>  libstdc++-v3/include/bits/ranges_algobase.h   |   4 +-
>  libstdc++-v3/include/bits/ranges_util.h       |  29 ++---
>  libstdc++-v3/include/bits/stl_algo.h          |   8 +-
>  .../25_algorithms/max/constrained.cc          |   4 +-
>  .../25_algorithms/min/constrained.cc          |   4 +-
>  .../25_algorithms/minmax/constrained.cc       |  16 ++-
>  .../minmax_element/constrained.cc             |  16 ++-
>  8 files changed, 108 insertions(+), 91 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
> b/libstdc++-v3/include/bits/ranges_algo.h
> index 9f8945a7133..6e1e06cb2d0 100644
> --- a/libstdc++-v3/include/bits/ranges_algo.h
> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> @@ -109,7 +109,7 @@ namespace ranges
>      template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
>              typename _Proj = identity,
>              indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
> -      constexpr bool
> +      [[nodiscard]] constexpr bool
>        operator()(_Iter __first, _Sent __last,
>                  _Pred __pred, _Proj __proj = {}) const
>        {
> @@ -122,7 +122,7 @@ namespace ranges
>      template<input_range _Range, typename _Proj = identity,
>              indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
>                _Pred>
> -      constexpr bool
> +      [[nodiscard]] constexpr bool
>        operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
>        {
>         return (*this)(ranges::begin(__r), ranges::end(__r),
> @@ -137,7 +137,7 @@ namespace ranges
>      template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
>              typename _Proj = identity,
>              indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
> -      constexpr bool
> +      [[nodiscard]] constexpr bool
>        operator()(_Iter __first, _Sent __last,
>                  _Pred __pred, _Proj __proj = {}) const
>        {
> @@ -150,7 +150,7 @@ namespace ranges
>      template<input_range _Range, typename _Proj = identity,
>              indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
>                _Pred>
> -      constexpr bool
> +      [[nodiscard]] constexpr bool
>        operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
>        {
>         return (*this)(ranges::begin(__r), ranges::end(__r),
> @@ -165,7 +165,7 @@ namespace ranges
>      template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
>              typename _Proj = identity,
>              indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
> -      constexpr bool
> +      [[nodiscard]] constexpr bool
>        operator()(_Iter __first, _Sent __last,
>                  _Pred __pred, _Proj __proj = {}) const
>        {
> @@ -178,7 +178,7 @@ namespace ranges
>      template<input_range _Range, typename _Proj = identity,
>              indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
>                _Pred>
> -      constexpr bool
> +      [[nodiscard]] constexpr bool
>        operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
>        {
>         return (*this)(ranges::begin(__r), ranges::end(__r),
> @@ -279,7 +279,7 @@ namespace ranges
>              typename _Pred = ranges::equal_to,
>              typename _Proj1 = identity, typename _Proj2 = identity>
>        requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
> -      constexpr _Iter1
> +      [[nodiscard]] constexpr _Iter1
>        operator()(_Iter1 __first1, _Sent1 __last1,


N.B. In older releases this would have needed the [[nodiscard]] to be
placed after operator(), for compatibility with the Concepts TS
(because otherwise the grammar says that the [[ is treated as a
subscript operator for the requires-expression!)

That's no longer an issue because the Concepts TS is not supported since GCC 15.

OK for trunk, thanks.

Reply via email to