xref: /llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/unique.pass.cpp (revision fb855eb941b6d740cc6560297d0b4d3201dcaf9f)
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 Iter>
12 //   requires OutputIterator<Iter, Iter::reference>
13 //         && EqualityComparable<Iter::value_type>
14 //   constexpr Iter        // constexpr after C++17
15 //   unique(Iter first, Iter last);
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <memory>
20 
21 #include "test_macros.h"
22 #include "test_iterators.h"
23 
24 #if TEST_STD_VER > 17
test_constexpr()25 TEST_CONSTEXPR bool test_constexpr() {
26           int ia[]       = {0, 1, 1, 3, 4};
27     const int expected[] = {0, 1, 3, 4};
28     const std::size_t N = 4;
29 
30     auto it = std::unique(std::begin(ia), std::end(ia));
31     return it == (std::begin(ia) + N)
32         && std::equal(std::begin(ia), it, std::begin(expected), std::end(expected))
33         ;
34     }
35 #endif
36 
37 template <class Iter>
38 void
test()39 test()
40 {
41     int ia[] = {0};
42     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
43     Iter r = std::unique(Iter(ia), Iter(ia+sa));
44     assert(base(r) == ia + sa);
45     assert(ia[0] == 0);
46 
47     int ib[] = {0, 1};
48     const unsigned sb = sizeof(ib)/sizeof(ib[0]);
49     r = std::unique(Iter(ib), Iter(ib+sb));
50     assert(base(r) == ib + sb);
51     assert(ib[0] == 0);
52     assert(ib[1] == 1);
53 
54     int ic[] = {0, 0};
55     const unsigned sc = sizeof(ic)/sizeof(ic[0]);
56     r = std::unique(Iter(ic), Iter(ic+sc));
57     assert(base(r) == ic + 1);
58     assert(ic[0] == 0);
59 
60     int id[] = {0, 0, 1};
61     const unsigned sd = sizeof(id)/sizeof(id[0]);
62     r = std::unique(Iter(id), Iter(id+sd));
63     assert(base(r) == id + 2);
64     assert(id[0] == 0);
65     assert(id[1] == 1);
66 
67     int ie[] = {0, 0, 1, 0};
68     const unsigned se = sizeof(ie)/sizeof(ie[0]);
69     r = std::unique(Iter(ie), Iter(ie+se));
70     assert(base(r) == ie + 3);
71     assert(ie[0] == 0);
72     assert(ie[1] == 1);
73     assert(ie[2] == 0);
74 
75     int ig[] = {0, 0, 1, 1};
76     const unsigned sg = sizeof(ig)/sizeof(ig[0]);
77     r = std::unique(Iter(ig), Iter(ig+sg));
78     assert(base(r) == ig + 2);
79     assert(ig[0] == 0);
80     assert(ig[1] == 1);
81 
82     int ih[] = {0, 1, 1};
83     const unsigned sh = sizeof(ih)/sizeof(ih[0]);
84     r = std::unique(Iter(ih), Iter(ih+sh));
85     assert(base(r) == ih + 2);
86     assert(ih[0] == 0);
87     assert(ih[1] == 1);
88 
89     int ii[] = {0, 1, 1, 1, 2, 2, 2};
90     const unsigned si = sizeof(ii)/sizeof(ii[0]);
91     r = std::unique(Iter(ii), Iter(ii+si));
92     assert(base(r) == ii + 3);
93     assert(ii[0] == 0);
94     assert(ii[1] == 1);
95     assert(ii[2] == 2);
96 }
97 
98 #if TEST_STD_VER >= 11
99 
100 struct do_nothing
101 {
operator ()do_nothing102     void operator()(void*) const {}
103 };
104 
105 typedef std::unique_ptr<int, do_nothing> Ptr;
106 
107 template <class Iter>
108 void
test1()109 test1()
110 {
111     int one = 1;
112     int two = 2;
113     Ptr ia[1];
114     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
115     Iter r = std::unique(Iter(ia), Iter(ia+sa));
116     assert(base(r) == ia + sa);
117     assert(ia[0] == 0);
118 
119     Ptr ib[2];
120     ib[1].reset(&one);
121     const unsigned sb = sizeof(ib)/sizeof(ib[0]);
122     r = std::unique(Iter(ib), Iter(ib+sb));
123     assert(base(r) == ib + sb);
124     assert(ib[0] == 0);
125     assert(*ib[1] == 1);
126 
127     Ptr ic[2];
128     const unsigned sc = sizeof(ic)/sizeof(ic[0]);
129     r = std::unique(Iter(ic), Iter(ic+sc));
130     assert(base(r) == ic + 1);
131     assert(ic[0] == 0);
132 
133     Ptr id[3];
134     id[2].reset(&one);
135     const unsigned sd = sizeof(id)/sizeof(id[0]);
136     r = std::unique(Iter(id), Iter(id+sd));
137     assert(base(r) == id + 2);
138     assert(id[0] == 0);
139     assert(*id[1] == 1);
140 
141     Ptr ie[4];
142     ie[2].reset(&one);
143     const unsigned se = sizeof(ie)/sizeof(ie[0]);
144     r = std::unique(Iter(ie), Iter(ie+se));
145     assert(base(r) == ie + 3);
146     assert(ie[0] == 0);
147     assert(*ie[1] == 1);
148     assert(ie[2] == 0);
149 
150     Ptr ig[4];
151     ig[2].reset(&one);
152     ig[3].reset(&one);
153     const unsigned sg = sizeof(ig)/sizeof(ig[0]);
154     r = std::unique(Iter(ig), Iter(ig+sg));
155     assert(base(r) == ig + 2);
156     assert(ig[0] == 0);
157     assert(*ig[1] == 1);
158 
159     Ptr ih[3];
160     ih[1].reset(&one);
161     ih[2].reset(&one);
162     const unsigned sh = sizeof(ih)/sizeof(ih[0]);
163     r = std::unique(Iter(ih), Iter(ih+sh));
164     assert(base(r) == ih + 2);
165     assert(ih[0] == 0);
166     assert(*ih[1] == 1);
167 
168     Ptr ii[7];
169     ii[1].reset(&one);
170     ii[2].reset(&one);
171     ii[3].reset(&one);
172     ii[4].reset(&two);
173     ii[5].reset(&two);
174     ii[6].reset(&two);
175     const unsigned si = sizeof(ii)/sizeof(ii[0]);
176     r = std::unique(Iter(ii), Iter(ii+si));
177     assert(base(r) == ii + 3);
178     assert(ii[0] == 0);
179     assert(*ii[1] == 1);
180     assert(*ii[2] == 2);
181 }
182 #endif // TEST_STD_VER >= 11
183 
main(int,char **)184 int main(int, char**)
185 {
186     test<forward_iterator<int*> >();
187     test<bidirectional_iterator<int*> >();
188     test<random_access_iterator<int*> >();
189     test<int*>();
190 
191 #if TEST_STD_VER >= 11
192     test1<forward_iterator<Ptr*> >();
193     test1<bidirectional_iterator<Ptr*> >();
194     test1<random_access_iterator<Ptr*> >();
195     test1<Ptr*>();
196 #endif
197 
198 #if TEST_STD_VER > 17
199     static_assert(test_constexpr());
200 #endif
201 
202   return 0;
203 }
204