1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // <algorithm>
11 
12 // template<ForwardIterator Iter, EquivalenceRelation<auto, Iter::value_type> Pred>
13 //   requires OutputIterator<Iter, RvalueOf<Iter::reference>::type>
14 //         && CopyConstructible<Pred>
15 //   Iter
16 //   unique(Iter first, Iter last, Pred pred);
17 
18 #include <algorithm>
19 #include <cassert>
20 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
21 #include <memory>
22 #endif
23 
24 #include "test_iterators.h"
25 
26 struct count_equal
27 {
28     static unsigned count;
29     template <class T>
30     bool operator()(const T& x, const T& y)
31         {++count; return x == y;}
32 };
33 
34 unsigned count_equal::count = 0;
35 
36 template <class Iter>
37 void
38 test()
39 {
40     int ia[] = {0};
41     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
42     count_equal::count = 0;
43     Iter r = std::unique(Iter(ia), Iter(ia+sa), count_equal());
44     assert(base(r) == ia + sa);
45     assert(ia[0] == 0);
46     assert(count_equal::count == sa-1);
47 
48     int ib[] = {0, 1};
49     const unsigned sb = sizeof(ib)/sizeof(ib[0]);
50     count_equal::count = 0;
51     r = std::unique(Iter(ib), Iter(ib+sb), count_equal());
52     assert(base(r) == ib + sb);
53     assert(ib[0] == 0);
54     assert(ib[1] == 1);
55     assert(count_equal::count == sb-1);
56 
57     int ic[] = {0, 0};
58     const unsigned sc = sizeof(ic)/sizeof(ic[0]);
59     count_equal::count = 0;
60     r = std::unique(Iter(ic), Iter(ic+sc), count_equal());
61     assert(base(r) == ic + 1);
62     assert(ic[0] == 0);
63     assert(count_equal::count == sc-1);
64 
65     int id[] = {0, 0, 1};
66     const unsigned sd = sizeof(id)/sizeof(id[0]);
67     count_equal::count = 0;
68     r = std::unique(Iter(id), Iter(id+sd), count_equal());
69     assert(base(r) == id + 2);
70     assert(id[0] == 0);
71     assert(id[1] == 1);
72     assert(count_equal::count == sd-1);
73 
74     int ie[] = {0, 0, 1, 0};
75     const unsigned se = sizeof(ie)/sizeof(ie[0]);
76     count_equal::count = 0;
77     r = std::unique(Iter(ie), Iter(ie+se), count_equal());
78     assert(base(r) == ie + 3);
79     assert(ie[0] == 0);
80     assert(ie[1] == 1);
81     assert(ie[2] == 0);
82     assert(count_equal::count == se-1);
83 
84     int ig[] = {0, 0, 1, 1};
85     const unsigned sg = sizeof(ig)/sizeof(ig[0]);
86     count_equal::count = 0;
87     r = std::unique(Iter(ig), Iter(ig+sg), count_equal());
88     assert(base(r) == ig + 2);
89     assert(ig[0] == 0);
90     assert(ig[1] == 1);
91     assert(count_equal::count == sg-1);
92 
93     int ih[] = {0, 1, 1};
94     const unsigned sh = sizeof(ih)/sizeof(ih[0]);
95     count_equal::count = 0;
96     r = std::unique(Iter(ih), Iter(ih+sh), count_equal());
97     assert(base(r) == ih + 2);
98     assert(ih[0] == 0);
99     assert(ih[1] == 1);
100     assert(count_equal::count == sh-1);
101 
102     int ii[] = {0, 1, 1, 1, 2, 2, 2};
103     const unsigned si = sizeof(ii)/sizeof(ii[0]);
104     count_equal::count = 0;
105     r = std::unique(Iter(ii), Iter(ii+si), count_equal());
106     assert(base(r) == ii + 3);
107     assert(ii[0] == 0);
108     assert(ii[1] == 1);
109     assert(ii[2] == 2);
110     assert(count_equal::count == si-1);
111 }
112 
113 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
114 
115 struct do_nothing
116 {
117     void operator()(void*) const {}
118 };
119 
120 typedef std::unique_ptr<int, do_nothing> Ptr;
121 
122 template <class Iter>
123 void
124 test1()
125 {
126     int one = 1;
127     int two = 2;
128     Ptr ia[1];
129     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
130     count_equal::count = 0;
131     Iter r = std::unique(Iter(ia), Iter(ia+sa), count_equal());
132     assert(base(r) == ia + sa);
133     assert(ia[0] == 0);
134     assert(count_equal::count == sa-1);
135 
136     Ptr ib[2];
137     ib[1].reset(&one);
138     const unsigned sb = sizeof(ib)/sizeof(ib[0]);
139     count_equal::count = 0;
140     r = std::unique(Iter(ib), Iter(ib+sb), count_equal());
141     assert(base(r) == ib + sb);
142     assert(ib[0] == 0);
143     assert(*ib[1] == 1);
144     assert(count_equal::count == sb-1);
145 
146     Ptr ic[2];
147     const unsigned sc = sizeof(ic)/sizeof(ic[0]);
148     count_equal::count = 0;
149     r = std::unique(Iter(ic), Iter(ic+sc), count_equal());
150     assert(base(r) == ic + 1);
151     assert(ic[0] == 0);
152     assert(count_equal::count == sc-1);
153 
154     Ptr id[3];
155     id[2].reset(&one);
156     const unsigned sd = sizeof(id)/sizeof(id[0]);
157     count_equal::count = 0;
158     r = std::unique(Iter(id), Iter(id+sd), count_equal());
159     assert(base(r) == id + 2);
160     assert(id[0] == 0);
161     assert(*id[1] == 1);
162     assert(count_equal::count == sd-1);
163 
164     Ptr ie[4];
165     ie[2].reset(&one);
166     const unsigned se = sizeof(ie)/sizeof(ie[0]);
167     count_equal::count = 0;
168     r = std::unique(Iter(ie), Iter(ie+se), count_equal());
169     assert(base(r) == ie + 3);
170     assert(ie[0] == 0);
171     assert(*ie[1] == 1);
172     assert(ie[2] == 0);
173     assert(count_equal::count == se-1);
174 
175     Ptr ig[4];
176     ig[2].reset(&one);
177     ig[3].reset(&one);
178     const unsigned sg = sizeof(ig)/sizeof(ig[0]);
179     count_equal::count = 0;
180     r = std::unique(Iter(ig), Iter(ig+sg), count_equal());
181     assert(base(r) == ig + 2);
182     assert(ig[0] == 0);
183     assert(*ig[1] == 1);
184     assert(count_equal::count == sg-1);
185 
186     Ptr ih[3];
187     ih[1].reset(&one);
188     ih[2].reset(&one);
189     const unsigned sh = sizeof(ih)/sizeof(ih[0]);
190     count_equal::count = 0;
191     r = std::unique(Iter(ih), Iter(ih+sh), count_equal());
192     assert(base(r) == ih + 2);
193     assert(ih[0] == 0);
194     assert(*ih[1] == 1);
195     assert(count_equal::count == sh-1);
196 
197     Ptr ii[7];
198     ii[1].reset(&one);
199     ii[2].reset(&one);
200     ii[3].reset(&one);
201     ii[4].reset(&two);
202     ii[5].reset(&two);
203     ii[6].reset(&two);
204     const unsigned si = sizeof(ii)/sizeof(ii[0]);
205     count_equal::count = 0;
206     r = std::unique(Iter(ii), Iter(ii+si), count_equal());
207     assert(base(r) == ii + 3);
208     assert(ii[0] == 0);
209     assert(*ii[1] == 1);
210     assert(*ii[2] == 2);
211     assert(count_equal::count == si-1);
212 }
213 
214 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
215 
216 int main()
217 {
218     test<forward_iterator<int*> >();
219     test<bidirectional_iterator<int*> >();
220     test<random_access_iterator<int*> >();
221     test<int*>();
222 
223 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
224 
225     test1<forward_iterator<Ptr*> >();
226     test1<bidirectional_iterator<Ptr*> >();
227     test1<random_access_iterator<Ptr*> >();
228     test1<Ptr*>();
229 
230 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
231 }
232