1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // ADDITIONAL_COMPILE_FLAGS: -Wno-sign-compare
13 // template<InputIterator Iter, class T>
14 // requires HasEqualTo<Iter::value_type, T>
15 // constexpr Iter // constexpr after C++17
16 // find(Iter first, Iter last, const T& value);
21 #include <type_traits>
23 #include "test_macros.h"
24 #include "test_iterators.h"
25 #include "type_algorithms.h"
27 static std::vector
<int> comparable_data
;
29 template <class ArrayT
, class CompareT
>
32 TEST_CONSTEXPR_CXX20
void operator()() {
34 ArrayT(1), ArrayT(2), ArrayT(3), ArrayT(4), ArrayT(5), ArrayT(6), ArrayT(7), ArrayT(8), ArrayT(9), ArrayT(10)};
36 static_assert(std::is_same
<decltype(std::find(Iter(arr
), Iter(arr
), 0)), Iter
>::value
, "");
38 { // first element matches
39 Iter iter
= std::find(Iter(arr
), Iter(arr
+ 10), CompareT(1));
40 assert(*iter
== ArrayT(1));
41 assert(base(iter
) == arr
);
44 { // range is empty; return last
45 Iter iter
= std::find(Iter(arr
), Iter(arr
), CompareT(1));
46 assert(base(iter
) == arr
);
49 { // if multiple elements match, return the first match
51 ArrayT(1), ArrayT(2), ArrayT(3), ArrayT(4), ArrayT(5), ArrayT(6), ArrayT(7), ArrayT(5), ArrayT(4)};
52 Iter iter
= std::find(Iter(std::begin(data
)), Iter(std::end(data
)), CompareT(5));
53 assert(*iter
== ArrayT(5));
54 assert(base(iter
) == data
+ 4);
57 { // some element matches
58 Iter iter
= std::find(Iter(arr
), Iter(arr
+ 10), CompareT(6));
59 assert(*iter
== ArrayT(6));
60 assert(base(iter
) == arr
+ 5);
63 { // last element matches
64 Iter iter
= std::find(Iter(arr
), Iter(arr
+ 10), CompareT(10));
65 assert(*iter
== ArrayT(10));
66 assert(base(iter
) == arr
+ 9);
69 { // if no element matches, last is returned
70 Iter iter
= std::find(Iter(arr
), Iter(arr
+ 10), CompareT(20));
71 assert(base(iter
) == arr
+ 10);
74 if (!TEST_IS_CONSTANT_EVALUATED
)
75 comparable_data
.clear();
79 template <class IndexT
>
83 static IndexT
init_index(IndexT i
) {
84 IndexT size
= static_cast<IndexT
>(comparable_data
.size());
85 comparable_data
.push_back(i
);
90 Comparable(IndexT i
) : index_(init_index(i
)) {}
92 friend bool operator==(const Comparable
& lhs
, const Comparable
& rhs
) {
93 return comparable_data
[lhs
.index_
] == comparable_data
[rhs
.index_
];
97 #if TEST_STD_VER >= 20
98 template <class ElementT
>
99 class TriviallyComparable
{
103 explicit constexpr TriviallyComparable(ElementT el
) : el_(el
) {}
104 bool operator==(const TriviallyComparable
&) const = default;
108 template <class CompareT
>
111 TEST_CONSTEXPR_CXX20
void operator()() {
112 types::for_each(types::cpp17_input_iterator_list
<T
*>(), Test
<T
, CompareT
>());
116 TEST_CONSTEXPR_CXX20
bool test() {
117 types::for_each(types::integer_types(), TestTypes
<char>());
118 types::for_each(types::integer_types(), TestTypes
<int>());
119 types::for_each(types::integer_types(), TestTypes
<long long>());
120 #if TEST_STD_VER >= 20
121 Test
<TriviallyComparable
<char>, TriviallyComparable
<char>>().operator()<TriviallyComparable
<char>*>();
122 Test
<TriviallyComparable
<wchar_t>, TriviallyComparable
<wchar_t>>().operator()<TriviallyComparable
<wchar_t>*>();
128 int main(int, char**) {
130 #if TEST_STD_VER >= 20
131 static_assert(test());
134 Test
<Comparable
<char>, Comparable
<char> >().operator()<Comparable
<char>*>();
135 Test
<Comparable
<wchar_t>, Comparable
<wchar_t> >().operator()<Comparable
<wchar_t>*>();