https://gcc.gnu.org/g:ea8ef439718f51592b4eadb989d2609d57d4b7db
commit r16-3267-gea8ef439718f51592b4eadb989d2609d57d4b7db Author: Tomasz KamiĆski <tkami...@redhat.com> Date: Thu Aug 14 16:54:16 2025 +0200 libstdc++: Add nodiscard attribute for ranges algorithm [PR121476] 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/max/constrained.cc: Likewise. * testsuite/25_algorithms/minmax/constrained.cc: Likewise. * testsuite/25_algorithms/minmax_element/constrained.cc: Likewise. Diff: --- 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 +- .../testsuite/25_algorithms/max/constrained.cc | 4 +- .../testsuite/25_algorithms/min/constrained.cc | 4 +- .../testsuite/25_algorithms/minmax/constrained.cc | 16 ++- .../25_algorithms/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 9f8945a7133a..6e1e06cb2d0f 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 a08f659b3aef..45ed5b4edc61 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 53b7f5c17f1c..84de258908ea 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 3f4674d5ca42..81a2457ae6f2 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 c3cd288f5613..c6759f8fdc8e 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 d5de04078394..7d4fa58aa118 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 5a5d34123cf2..270fd45132d1 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 99ebf03120bd..1eaaf0711b8d 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