xref: /llvm-project/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search_pred.pass.cpp (revision 257831582c759048ecce5c393993268b71a602e0)
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <algorithm>
10 
11 // template<ForwardIterator Iter1, ForwardIterator Iter2>
12 //   requires HasEqualTo<Iter1::value_type, Iter2::value_type>
13 //   constexpr Iter1     // constexpr after C++17
14 //   search(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2);
15 
16 #include <algorithm>
17 #include <cassert>
18 
19 #include "test_macros.h"
20 #include "test_iterators.h"
21 
22 #if TEST_STD_VER > 17
23 TEST_CONSTEXPR bool eq(int a, int b) { return a == b; }
24 
25 TEST_CONSTEXPR bool test_constexpr() {
26     int ia[] = {0, 1, 2, 3};
27     int ib[] = {0, 1, 5, 3};
28     int ic[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
29     return    (std::search(std::begin(ic), std::end(ic), std::begin(ia), std::end(ia), eq) == ic+3)
30            && (std::search(std::begin(ic), std::end(ic), std::begin(ib), std::end(ib), eq) == std::end(ic))
31            ;
32     }
33 #endif
34 
35 struct count_equal
36 {
37     static unsigned count;
38     template <class T>
39     bool operator()(const T& x, const T& y) & {
40       ++count;
41       return x == y;
42     };
43     template <class T>
44     bool operator()(const T& x, const T& y) const& {
45       ++count;
46       return x == y;
47     };
48 };
49 
50 unsigned count_equal::count = 0;
51 
52 template <class Iter1, class Iter2>
53 void
54 test()
55 {
56     int ia[] = {0, 1, 2, 3, 4, 5};
57     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
58     count_equal::count = 0;
59     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia), count_equal()) == Iter1(ia));
60     assert(count_equal::count <= 0);
61     count_equal::count = 0;
62     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+1), count_equal()) == Iter1(ia));
63     assert(count_equal::count <= sa);
64     count_equal::count = 0;
65     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia+1), Iter2(ia+2), count_equal()) == Iter1(ia+1));
66     assert(count_equal::count <= sa);
67     count_equal::count = 0;
68     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+2), count_equal()) == Iter1(ia));
69     assert(count_equal::count <= 0);
70     count_equal::count = 0;
71     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), count_equal()) == Iter1(ia+2));
72     assert(count_equal::count <= sa);
73     count_equal::count = 0;
74     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), count_equal()) == Iter1(ia+2));
75     assert(count_equal::count <= sa);
76     count_equal::count = 0;
77     assert(std::search(Iter1(ia), Iter1(ia), Iter2(ia+2), Iter2(ia+3), count_equal()) == Iter1(ia));
78     assert(count_equal::count <= 0);
79     count_equal::count = 0;
80     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-1), Iter2(ia+sa), count_equal()) == Iter1(ia+sa-1));
81     assert(count_equal::count <= sa);
82     count_equal::count = 0;
83     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-3), Iter2(ia+sa), count_equal()) == Iter1(ia+sa-3));
84     assert(count_equal::count <= sa*3);
85     count_equal::count = 0;
86     assert(std::search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), count_equal()) == Iter1(ia));
87     assert(count_equal::count <= sa*sa);
88     count_equal::count = 0;
89     assert(std::search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia), Iter2(ia+sa), count_equal()) == Iter1(ia+sa-1));
90     assert(count_equal::count <= (sa-1)*sa);
91     count_equal::count = 0;
92     assert(std::search(Iter1(ia), Iter1(ia+1), Iter2(ia), Iter2(ia+sa), count_equal()) == Iter1(ia+1));
93     assert(count_equal::count <= sa);
94     count_equal::count = 0;
95     int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
96     const unsigned sb = sizeof(ib)/sizeof(ib[0]);
97     int ic[] = {1};
98     assert(std::search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), count_equal()) == Iter1(ib+1));
99     assert(count_equal::count <= sb);
100     count_equal::count = 0;
101     int id[] = {1, 2};
102     assert(std::search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), count_equal()) == Iter1(ib+1));
103     assert(count_equal::count <= sb*2);
104     count_equal::count = 0;
105     int ie[] = {1, 2, 3};
106     assert(std::search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), count_equal()) == Iter1(ib+4));
107     assert(count_equal::count <= sb*3);
108     count_equal::count = 0;
109     int ig[] = {1, 2, 3, 4};
110     assert(std::search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), count_equal()) == Iter1(ib+8));
111     assert(count_equal::count <= sb*4);
112     count_equal::count = 0;
113     int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
114     const unsigned sh = sizeof(ih)/sizeof(ih[0]);
115     int ii[] = {1, 1, 2};
116     assert(std::search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), count_equal()) == Iter1(ih+3));
117     assert(count_equal::count <= sh*3);
118 }
119 
120 int main(int, char**)
121 {
122     test<forward_iterator<const int*>, forward_iterator<const int*> >();
123     test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
124     test<forward_iterator<const int*>, random_access_iterator<const int*> >();
125     test<bidirectional_iterator<const int*>, forward_iterator<const int*> >();
126     test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();
127     test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();
128     test<random_access_iterator<const int*>, forward_iterator<const int*> >();
129     test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();
130     test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
131 
132 #if TEST_STD_VER > 17
133     static_assert(test_constexpr());
134 #endif
135 
136   return 0;
137 }
138