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