]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // { dg-do run { target c++20 } }
24 #include <testsuite_hooks.h>
25 #include <testsuite_iterators.h>
27 using __gnu_test::test_container
;
28 using __gnu_test::test_range
;
29 using __gnu_test::input_iterator_wrapper
;
31 namespace ranges
= std::ranges
;
33 template<typename T1
, typename T2
>
35 operator==(const ranges::minmax_result
<T1
>& lhs
,
36 const ranges::minmax_result
<T2
>& rhs
)
38 return (lhs
.min
== rhs
.min
39 && rhs
.max
== rhs
.max
);
48 using res_t
= ranges::minmax_result
<int>;
53 VERIFY( ranges::minmax(1, 2) == res_t(1,2) );
54 VERIFY( ranges::minmax(2, 1) == res_t(1,2) );
55 VERIFY( ranges::minmax(1, 2, ranges::greater
{}) == res_t(2,1) );
56 VERIFY( ranges::minmax(1, 2, ranges::greater
{}, std::negate
<>{}) == res_t(1,2) );
57 VERIFY( ranges::minmax(1, 2, {}, std::negate
<>{}) == res_t(2,1) );
58 VERIFY( ranges::minmax(X
{1,2}, X
{1,3}, {}, &X::i
).min
.j
== 2 );
59 VERIFY( ranges::minmax(X
{1,2}, X
{1,3}, {}, &X::i
).max
.j
== 3 );
68 test_range
<int, input_iterator_wrapper
> cx(x
);
69 VERIFY( ranges::minmax(cx
) == res_t(1,4) );
71 VERIFY( ranges::minmax(cx
, ranges::greater
{}) == res_t(4,1) );
73 VERIFY( ranges::minmax(cx
, {}, std::negate
<>{}) == res_t(4,1));
75 VERIFY( ranges::minmax(cx
, ranges::greater
{}, std::negate
<>{})
77 } while (ranges::next_permutation(x
).found
);
79 constexpr X y
[] = {{1,5},{1,2},{1,3}};
80 static_assert(ranges::minmax(y
, {}, &X::i
).min
.j
== 5);
81 static_assert(ranges::minmax(y
, {}, &X::i
).max
.j
== 3);
87 VERIFY( ranges::minmax({2,3,1,4}) == res_t(1,4) );
88 VERIFY( ranges::minmax({2,3,1,4}, ranges::greater
{}) == res_t(4,1) );
89 VERIFY( ranges::minmax({2,3,1,4}, {}, std::negate
<>{}) == res_t(4,1) );
90 VERIFY( ranges::minmax({2,3,1,4}, ranges::greater
{}, std::negate
<>{})
97 // Verify we perform at most 3*N/2 applications of the comparison predicate.
100 { bool operator()(int a
, int b
) { ++counter
; return a
< b
; } };
102 ranges::minmax({1,2}, counted_less
{});
103 VERIFY( counter
== 1 );
106 ranges::minmax({1,2,3}, counted_less
{});
107 VERIFY( counter
== 3 );
110 ranges::minmax({1,2,3,4,5,6,7,8,9,10}, counted_less
{});
111 VERIFY( counter
<= 15 );
114 ranges::minmax({10,9,8,7,6,5,4,3,2,1}, counted_less
{});
115 VERIFY( counter
<= 15 );
121 // PR libstdc++/100387
122 using namespace std::literals::string_literals
;
123 auto comp
= [](const auto& a
, const auto& b
) {
124 return a
.size() == b
.size() ? a
.front() < b
.front() : a
.size() > b
.size();
126 auto result
= ranges::minmax({"b"s
, "a"s
}, comp
);
127 VERIFY( result
.min
== "a"s
&& result
.max
== "b"s
);
128 result
= ranges::minmax({"c"s
, "b"s
, "a"s
}, comp
);
129 VERIFY( result
.min
== "a"s
&& result
.max
== "c"s
);
135 A(const A
&) = default;
136 A(A
&& other
) : A(std::as_const(other
)) { ++move_count
; }
137 A
& operator=(const A
&) = default;
138 A
& operator=(A
&& other
) {
140 return *this = std::as_const(other
);
142 friend auto operator<=>(const A
&, const A
&) = default;
143 static inline int move_count
= 0;
150 // PR libstdc++/104858
151 // Verify ranges::minmax doesn't dereference the iterator for the first
152 // element in the range twice.
154 ranges::subrange r
= {std::move_iterator(&a
), std::move_sentinel(&a
+ 1)};
155 auto result
= ranges::minmax(r
);
156 VERIFY( A::move_count
== 1 );
157 VERIFY( result
.min
.i
== 42 && result
.max
.i
== 42 );