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>
13//   requires OutputIterator<Iter, Iter::reference>
14//         && EqualityComparable<Iter::value_type>
15//   Iter
16//   unique(Iter first, Iter last);
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
26template <class Iter>
27void
28test()
29{
30    int ia[] = {0};
31    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
32    Iter r = std::unique(Iter(ia), Iter(ia+sa));
33    assert(base(r) == ia + sa);
34    assert(ia[0] == 0);
35
36    int ib[] = {0, 1};
37    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
38    r = std::unique(Iter(ib), Iter(ib+sb));
39    assert(base(r) == ib + sb);
40    assert(ib[0] == 0);
41    assert(ib[1] == 1);
42
43    int ic[] = {0, 0};
44    const unsigned sc = sizeof(ic)/sizeof(ic[0]);
45    r = std::unique(Iter(ic), Iter(ic+sc));
46    assert(base(r) == ic + 1);
47    assert(ic[0] == 0);
48
49    int id[] = {0, 0, 1};
50    const unsigned sd = sizeof(id)/sizeof(id[0]);
51    r = std::unique(Iter(id), Iter(id+sd));
52    assert(base(r) == id + 2);
53    assert(id[0] == 0);
54    assert(id[1] == 1);
55
56    int ie[] = {0, 0, 1, 0};
57    const unsigned se = sizeof(ie)/sizeof(ie[0]);
58    r = std::unique(Iter(ie), Iter(ie+se));
59    assert(base(r) == ie + 3);
60    assert(ie[0] == 0);
61    assert(ie[1] == 1);
62    assert(ie[2] == 0);
63
64    int ig[] = {0, 0, 1, 1};
65    const unsigned sg = sizeof(ig)/sizeof(ig[0]);
66    r = std::unique(Iter(ig), Iter(ig+sg));
67    assert(base(r) == ig + 2);
68    assert(ig[0] == 0);
69    assert(ig[1] == 1);
70
71    int ih[] = {0, 1, 1};
72    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
73    r = std::unique(Iter(ih), Iter(ih+sh));
74    assert(base(r) == ih + 2);
75    assert(ih[0] == 0);
76    assert(ih[1] == 1);
77
78    int ii[] = {0, 1, 1, 1, 2, 2, 2};
79    const unsigned si = sizeof(ii)/sizeof(ii[0]);
80    r = std::unique(Iter(ii), Iter(ii+si));
81    assert(base(r) == ii + 3);
82    assert(ii[0] == 0);
83    assert(ii[1] == 1);
84    assert(ii[2] == 2);
85}
86
87#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
88
89struct do_nothing
90{
91    void operator()(void*) const {}
92};
93
94typedef std::unique_ptr<int, do_nothing> Ptr;
95
96template <class Iter>
97void
98test1()
99{
100    int one = 1;
101    int two = 2;
102    Ptr ia[1];
103    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
104    Iter r = std::unique(Iter(ia), Iter(ia+sa));
105    assert(base(r) == ia + sa);
106    assert(ia[0] == 0);
107
108    Ptr ib[2];
109    ib[1].reset(&one);
110    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
111    r = std::unique(Iter(ib), Iter(ib+sb));
112    assert(base(r) == ib + sb);
113    assert(ib[0] == 0);
114    assert(*ib[1] == 1);
115
116    Ptr ic[2];
117    const unsigned sc = sizeof(ic)/sizeof(ic[0]);
118    r = std::unique(Iter(ic), Iter(ic+sc));
119    assert(base(r) == ic + 1);
120    assert(ic[0] == 0);
121
122    Ptr id[3];
123    id[2].reset(&one);
124    const unsigned sd = sizeof(id)/sizeof(id[0]);
125    r = std::unique(Iter(id), Iter(id+sd));
126    assert(base(r) == id + 2);
127    assert(id[0] == 0);
128    assert(*id[1] == 1);
129
130    Ptr ie[4];
131    ie[2].reset(&one);
132    const unsigned se = sizeof(ie)/sizeof(ie[0]);
133    r = std::unique(Iter(ie), Iter(ie+se));
134    assert(base(r) == ie + 3);
135    assert(ie[0] == 0);
136    assert(*ie[1] == 1);
137    assert(ie[2] == 0);
138
139    Ptr ig[4];
140    ig[2].reset(&one);
141    ig[3].reset(&one);
142    const unsigned sg = sizeof(ig)/sizeof(ig[0]);
143    r = std::unique(Iter(ig), Iter(ig+sg));
144    assert(base(r) == ig + 2);
145    assert(ig[0] == 0);
146    assert(*ig[1] == 1);
147
148    Ptr ih[3];
149    ih[1].reset(&one);
150    ih[2].reset(&one);
151    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
152    r = std::unique(Iter(ih), Iter(ih+sh));
153    assert(base(r) == ih + 2);
154    assert(ih[0] == 0);
155    assert(*ih[1] == 1);
156
157    Ptr ii[7];
158    ii[1].reset(&one);
159    ii[2].reset(&one);
160    ii[3].reset(&one);
161    ii[4].reset(&two);
162    ii[5].reset(&two);
163    ii[6].reset(&two);
164    const unsigned si = sizeof(ii)/sizeof(ii[0]);
165    r = std::unique(Iter(ii), Iter(ii+si));
166    assert(base(r) == ii + 3);
167    assert(ii[0] == 0);
168    assert(*ii[1] == 1);
169    assert(*ii[2] == 2);
170}
171
172#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
173
174int main()
175{
176    test<forward_iterator<int*> >();
177    test<bidirectional_iterator<int*> >();
178    test<random_access_iterator<int*> >();
179    test<int*>();
180
181#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
182
183    test1<forward_iterator<Ptr*> >();
184    test1<bidirectional_iterator<Ptr*> >();
185    test1<random_access_iterator<Ptr*> >();
186    test1<Ptr*>();
187
188#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
189}
190