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.

        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,
                 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -298,7 +298,7 @@ namespace ranges
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
                                     _Pred, _Proj1, _Proj2>
-      constexpr borrowed_iterator_t<_Range1>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range1>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -319,7 +319,7 @@ namespace ranges
       requires indirect_binary_predicate<ranges::equal_to,
                                         projected<_Iter, _Proj>,
                                         const _Tp*>
-      constexpr iter_difference_t<_Iter>
+      [[nodiscard]] constexpr iter_difference_t<_Iter>
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Proj __proj = {}) const
       {
@@ -336,7 +336,7 @@ namespace ranges
       requires indirect_binary_predicate<ranges::equal_to,
                                         projected<iterator_t<_Range>, _Proj>,
                                         const _Tp*>
-      constexpr range_difference_t<_Range>
+      [[nodiscard]] constexpr range_difference_t<_Range>
       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -726,7 +726,7 @@ namespace ranges
             typename _Pred = ranges::equal_to,
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-      constexpr subrange<_Iter1>
+      [[nodiscard]] constexpr subrange<_Iter1>
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -783,7 +783,7 @@ namespace ranges
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
                                     _Pred, _Proj1, _Proj2>
-      constexpr borrowed_subrange_t<_Range1>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range1>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -806,7 +806,7 @@ namespace ranges
             indirect_equivalence_relation<projected<_Iter1, _Proj1>,
                                           projected<_Iter2, _Proj2>> _Pred
               = ranges::equal_to>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -875,7 +875,7 @@ namespace ranges
             indirect_equivalence_relation<
               projected<iterator_t<_Range1>, _Proj1>,
               projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -1281,7 +1281,7 @@ namespace ranges
     template<permutable _Iter, sentinel_for<_Iter> _Sent,
             typename _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last,
                 _Pred __pred, _Proj __proj = {}) const
       {
@@ -1305,7 +1305,7 @@ namespace ranges
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
               _Pred>
       requires permutable<iterator_t<_Range>>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1323,7 +1323,7 @@ namespace ranges
       requires indirect_binary_predicate<ranges::equal_to,
                                         projected<_Iter, _Proj>,
                                         const _Tp*>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Proj __proj = {}) const
       {
@@ -1341,7 +1341,7 @@ namespace ranges
        && indirect_binary_predicate<ranges::equal_to,
                                     projected<iterator_t<_Range>, _Proj>,
                                     const _Tp*>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1440,7 +1440,7 @@ namespace ranges
             typename _Proj = identity,
             indirect_equivalence_relation<
               projected<_Iter, _Proj>> _Comp = ranges::equal_to>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -1462,7 +1462,7 @@ namespace ranges
             indirect_equivalence_relation<
               projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
       requires permutable<iterator_t<_Range>>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2849,7 +2849,7 @@ namespace ranges
             typename _Proj = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2868,7 +2868,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2884,7 +2884,7 @@ namespace ranges
             typename _Proj = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Iter __first, _Sent __last,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2903,7 +2903,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2987,7 +2987,7 @@ namespace ranges
             typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
             indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3017,7 +3017,7 @@ namespace ranges
             indirect_strict_weak_order<const _Tp*,
                                        projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r,
                 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3035,7 +3035,7 @@ namespace ranges
             typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
             indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3065,7 +3065,7 @@ namespace ranges
             indirect_strict_weak_order<const _Tp*,
                                        projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r,
                 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3083,7 +3083,7 @@ namespace ranges
             typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
             indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3128,7 +3128,7 @@ namespace ranges
             indirect_strict_weak_order<const _Tp*,
                                        projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, const _Tp& __value,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3146,7 +3146,7 @@ namespace ranges
             typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
             indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -3164,7 +3164,7 @@ namespace ranges
             indirect_strict_weak_order<const _Tp*,
                                        projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {},
                 _Proj __proj = {}) const
       {
@@ -3180,7 +3180,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
       {
@@ -3196,7 +3196,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),
@@ -3488,7 +3488,7 @@ namespace ranges
     template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
             typename _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Pred __pred, _Proj __proj = {}) const
       {
@@ -3514,7 +3514,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
               _Pred>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3875,7 +3875,7 @@ namespace ranges
             indirect_strict_weak_order<projected<_Iter1, _Proj1>,
                                        projected<_Iter2, _Proj2>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2,
                 _Comp __comp = {},
@@ -3904,7 +3904,7 @@ namespace ranges
             indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
                                        projected<iterator_t<_Range2>, _Proj2>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -4175,7 +4175,7 @@ namespace ranges
     template<typename _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>>
               _Comp = ranges::less>
-      constexpr const _Tp&
+      [[nodiscard]] constexpr const _Tp&
       operator()(const _Tp& __a, const _Tp& __b,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4192,7 +4192,7 @@ namespace ranges
               _Comp = ranges::less>
       requires indirectly_copyable_storable<iterator_t<_Range>,
                                            range_value_t<_Range>*>
-      constexpr range_value_t<_Range>
+      [[nodiscard]] constexpr range_value_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        auto __first = ranges::begin(__r);
@@ -4213,7 +4213,7 @@ namespace ranges
     template<copyable _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>>
               _Comp = ranges::less>
-      constexpr _Tp
+      [[nodiscard]] constexpr _Tp
       operator()(initializer_list<_Tp> __r,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4229,7 +4229,7 @@ namespace ranges
     template<typename _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp
               = ranges::less>
-      constexpr const _Tp&
+      [[nodiscard]] constexpr const _Tp&
       operator()(const _Tp& __val, const _Tp& __lo, const _Tp& __hi,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4279,7 +4279,7 @@ namespace ranges
     template<typename _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>>
               _Comp = ranges::less>
-      constexpr minmax_result<const _Tp&>
+      [[nodiscard]] constexpr minmax_result<const _Tp&>
       operator()(const _Tp& __a, const _Tp& __b,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4295,7 +4295,7 @@ namespace ranges
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
       requires indirectly_copyable_storable<iterator_t<_Range>, 
range_value_t<_Range>*>
-      constexpr minmax_result<range_value_t<_Range>>
+      [[nodiscard]] constexpr minmax_result<range_value_t<_Range>>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        auto __first = ranges::begin(__r);
@@ -4354,7 +4354,7 @@ namespace ranges
     template<copyable _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>>
               _Comp = ranges::less>
-      constexpr minmax_result<_Tp>
+      [[nodiscard]] constexpr minmax_result<_Tp>
       operator()(initializer_list<_Tp> __r,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4371,7 +4371,7 @@ namespace ranges
             typename _Proj = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4392,7 +4392,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -4408,7 +4408,7 @@ namespace ranges
             typename _Proj = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4429,7 +4429,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -4448,7 +4448,7 @@ namespace ranges
             typename _Proj = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>>
               _Comp = ranges::less>
-      constexpr minmax_element_result<_Iter>
+      [[nodiscard]] constexpr minmax_element_result<_Iter>
       operator()(_Iter __first, _Sent __last,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -4503,7 +4503,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
               _Comp = ranges::less>
-      constexpr minmax_element_result<borrowed_iterator_t<_Range>>
+      [[nodiscard]] constexpr 
minmax_element_result<borrowed_iterator_t<_Range>>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -4521,7 +4521,7 @@ namespace ranges
             indirect_strict_weak_order<projected<_Iter1, _Proj1>,
                                        projected<_Iter2, _Proj2>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2,
                 _Comp __comp = {},
@@ -4607,7 +4607,7 @@ namespace ranges
             indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
                                        projected<iterator_t<_Range2>, _Proj2>>
               _Comp = ranges::less>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -4836,7 +4836,7 @@ namespace ranges
             typename _Proj = identity,
             typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
       requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, 
_Proj>, const _Tp*>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj 
= {}) const
       {
        if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
@@ -4869,7 +4869,7 @@ namespace ranges
             typename _Tp
               _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
       requires indirect_binary_predicate<ranges::equal_to, 
projected<iterator_t<_Range>, _Proj>, const _Tp*>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
       { return (*this)(ranges::begin(__r), ranges::end(__r), __value, 
std::move(__proj)); }
   };
@@ -4880,7 +4880,7 @@ namespace ranges
   {
     template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Proj 
= identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) 
const
       {
        if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
@@ -4911,7 +4911,7 @@ namespace ranges
 
     template<forward_range _Range, typename _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> 
_Pred>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       { return (*this)(ranges::begin(__r), ranges::end(__r), 
std::move(__pred), std::move(__proj)); }
   };
@@ -4922,7 +4922,7 @@ namespace ranges
   {
     template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Proj 
= identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-      constexpr subrange<_Iter>
+      [[nodiscard]] constexpr subrange<_Iter>
       operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) 
const
       {
        if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
@@ -4953,7 +4953,7 @@ namespace ranges
 
     template<forward_range _Range, typename _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> 
_Pred>
-      constexpr borrowed_subrange_t<_Range>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       { return (*this)(ranges::begin(__r), ranges::end(__r), 
std::move(__pred), std::move(__proj)); }
   };
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
b/libstdc++-v3/include/bits/ranges_algobase.h
index a08f659b3ae..45ed5b4edc6 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -101,7 +101,7 @@ namespace ranges
             typename _Pred = ranges::equal_to,
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -168,7 +168,7 @@ namespace ranges
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
                                     _Pred, _Proj1, _Proj2>
-      constexpr bool
+      [[nodiscard]] constexpr bool
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
diff --git a/libstdc++-v3/include/bits/ranges_util.h 
b/libstdc++-v3/include/bits/ranges_util.h
index 53b7f5c17f1..84de258908e 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -501,7 +501,7 @@ namespace ranges
             typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
       requires indirect_binary_predicate<ranges::equal_to,
                                         projected<_Iter, _Proj>, const _Tp*>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 const _Tp& __value, _Proj __proj = {}) const
       {
@@ -537,7 +537,7 @@ namespace ranges
       requires indirect_binary_predicate<ranges::equal_to,
                                         projected<iterator_t<_Range>, _Proj>,
                                         const _Tp*>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -552,7 +552,7 @@ namespace ranges
     template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
             typename _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Pred __pred, _Proj __proj = {}) const
       {
@@ -565,7 +565,7 @@ namespace ranges
     template<input_range _Range, typename _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
               _Pred>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -580,7 +580,7 @@ namespace ranges
     template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
             typename _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Pred __pred, _Proj __proj = {}) const
       {
@@ -593,7 +593,7 @@ namespace ranges
     template<input_range _Range, typename _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
               _Pred>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -634,7 +634,7 @@ namespace ranges
             typename _Pred = ranges::equal_to,
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-      constexpr mismatch_result<_Iter1, _Iter2>
+      [[nodiscard]] constexpr mismatch_result<_Iter1, _Iter2>
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -655,6 +655,7 @@ namespace ranges
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
                                     _Pred, _Proj1, _Proj2>
+      [[nodiscard]]    
       constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -675,7 +676,7 @@ namespace ranges
             typename _Pred = ranges::equal_to,
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-      constexpr subrange<_Iter1>
+      [[nodiscard]] constexpr subrange<_Iter1>
       operator()(_Iter1 __first1, _Sent1 __last1,
                 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -719,7 +720,7 @@ namespace ranges
             typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
                                     _Pred, _Proj1, _Proj2>
-      constexpr borrowed_subrange_t<_Range1>
+      [[nodiscard]] constexpr borrowed_subrange_t<_Range1>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
                 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -737,7 +738,7 @@ namespace ranges
     template<typename _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>>
               _Comp = ranges::less>
-      constexpr const _Tp&
+      [[nodiscard]] constexpr const _Tp&
       operator()(const _Tp& __a, const _Tp& __b,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -754,7 +755,7 @@ namespace ranges
               _Comp = ranges::less>
       requires indirectly_copyable_storable<iterator_t<_Range>,
                                            range_value_t<_Range>*>
-      constexpr range_value_t<_Range>
+      [[nodiscard]] constexpr range_value_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
        auto __first = ranges::begin(__r);
@@ -775,7 +776,7 @@ namespace ranges
     template<copyable _Tp, typename _Proj = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>>
               _Comp = ranges::less>
-      constexpr _Tp
+      [[nodiscard]] constexpr _Tp
       operator()(initializer_list<_Tp> __r,
                 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -793,7 +794,7 @@ namespace ranges
             indirect_binary_predicate<projected<_Iter, _Proj>,
                                       projected<_Iter, _Proj>> _Pred
               = ranges::equal_to>
-      constexpr _Iter
+      [[nodiscard]] constexpr _Iter
       operator()(_Iter __first, _Sent __last,
                 _Pred __pred = {}, _Proj __proj = {}) const
       {
@@ -814,7 +815,7 @@ namespace ranges
             indirect_binary_predicate<
               projected<iterator_t<_Range>, _Proj>,
               projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
-      constexpr borrowed_iterator_t<_Range>
+      [[nodiscard]] constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const
       {
        return (*this)(ranges::begin(__r), ranges::end(__r),
diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 3f4674d5ca4..81a2457ae6f 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -5759,7 +5759,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 #if __cplusplus >= 201103L
   // N2722 + DR 915.
   template<typename _Tp>
-    _GLIBCXX14_CONSTEXPR
+    _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
     inline _Tp
     min(initializer_list<_Tp> __l)
     {
@@ -5769,7 +5769,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     }
 
   template<typename _Tp, typename _Compare>
-    _GLIBCXX14_CONSTEXPR
+    _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
     inline _Tp
     min(initializer_list<_Tp> __l, _Compare __comp)
     {
@@ -5779,7 +5779,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     }
 
   template<typename _Tp>
-    _GLIBCXX14_CONSTEXPR
+    _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
     inline _Tp
     max(initializer_list<_Tp> __l)
     {
@@ -5789,7 +5789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     }
 
   template<typename _Tp, typename _Compare>
-    _GLIBCXX14_CONSTEXPR
+    _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
     inline _Tp
     max(initializer_list<_Tp> __l, _Compare __comp)
     {
diff --git a/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc 
b/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc
index c3cd288f561..c6759f8fdc8 100644
--- a/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc
@@ -87,12 +87,12 @@ test04()
     int m;
   };
   A r[5] = {5, 4, 3, 2, 1};
-  ranges::max(r, ranges::less{}, &A::m);
+  (void)ranges::max(r, ranges::less{}, &A::m);
   VERIFY( copies == 1 );
   VERIFY( moves == 0 );
   copies = moves = 0;
   A s[5] = {1, 2, 3, 4, 5};
-  ranges::max(s, ranges::less{}, &A::m);
+  (void)ranges::max(s, ranges::less{}, &A::m);
   VERIFY( copies == 5 );
   VERIFY( moves == 0 );
 }
diff --git a/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc 
b/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc
index d5de0407839..7d4fa58aa11 100644
--- a/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc
@@ -87,12 +87,12 @@ test04()
     int m;
   };
   A r[5] = {5, 4, 3, 2, 1};
-  ranges::min(r, ranges::less{}, &A::m);
+  (void)ranges::min(r, ranges::less{}, &A::m);
   VERIFY( copies == 5 );
   VERIFY( moves == 0 );
   copies = moves = 0;
   A s[5] = {1, 2, 3, 4, 5};
-  ranges::min(s, ranges::less{}, &A::m);
+  (void)ranges::min(s, ranges::less{}, &A::m);
   VERIFY( copies == 1 );
   VERIFY( moves == 0 );
 }
diff --git a/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc 
b/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
index 5a5d34123cf..270fd45132d 100644
--- a/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
@@ -99,20 +99,28 @@ test04()
   struct counted_less
   { bool operator()(int a, int b) { ++counter; return a < b; } };
 
-  ranges::minmax({1,2}, counted_less{});
+  auto p = ranges::minmax({1,2}, counted_less{});
   VERIFY( counter == 1 );
+  VERIFY( p.min = 1 );
+  VERIFY( p.max = 2 );
 
   counter = 0;
-  ranges::minmax({1,2,3}, counted_less{});
+  p = ranges::minmax({1,2,3}, counted_less{});
   VERIFY( counter == 3 );
+  VERIFY( p.min = 1 );
+  VERIFY( p.max = 3 );
 
   counter = 0;
-  ranges::minmax({1,2,3,4,5,6,7,8,9,10}, counted_less{});
+  p = ranges::minmax({1,2,3,4,5,6,7,8,9,10}, counted_less{});
   VERIFY( counter <= 15 );
+  VERIFY( p.min = 1 );
+  VERIFY( p.max = 10 );
 
   counter = 0;
-  ranges::minmax({10,9,8,7,6,5,4,3,2,1}, counted_less{});
+  p = ranges::minmax({10,9,8,7,6,5,4,3,2,1}, counted_less{});
   VERIFY( counter <= 15 );
+  VERIFY( p.min = 1 );
+  VERIFY( p.max = 10 );
 }
 
 void
diff --git a/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc 
b/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc
index 99ebf03120b..1eaaf0711b8 100644
--- a/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc
@@ -70,21 +70,29 @@ test02()
   { bool operator()(int a, int b) { ++counter; return a < b; } };
 
   int x[] = {1,2,3,4,5,6,7,8,9,10};
-  ranges::minmax_element(x, x+2, counted_less{});
+  auto p = ranges::minmax_element(x, x+2, counted_less{});
   VERIFY( counter == 1 );
+  VERIFY( p.min == x+0 );
+  VERIFY( p.max == x+1 );
 
   counter = 0;
-  ranges::minmax_element(x, x+3, counted_less{});
+  p = ranges::minmax_element(x, x+3, counted_less{});
   VERIFY( counter == 3 );
+  VERIFY( p.min == x+0 );
+  VERIFY( p.max == x+2 );
 
   counter = 0;
-  ranges::minmax_element(x, counted_less{});
+  p = ranges::minmax_element(x, counted_less{});
   VERIFY( counter <= 15 );
+  VERIFY( p.min == x+0 );
+  VERIFY( p.max == x+9 );
 
   ranges::reverse(x);
   counter = 0;
-  ranges::minmax_element(x, counted_less{});
+  p = ranges::minmax_element(x, counted_less{});
   VERIFY( counter <= 15 );
+  VERIFY( p.min == x+9 );
+  VERIFY( p.max == x+0 );
 }
 
 int
-- 
2.50.1

Reply via email to