1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 // template<InputIterator InIter, class OutIter>
12 // requires OutputIterator<OutIter, RvalueOf<InIter::value_type>::type>
13 // && EqualityComparable<InIter::value_type>
14 // && HasAssign<InIter::value_type, InIter::reference>
15 // && Constructible<InIter::value_type, InIter::reference>
16 // constexpr OutIter // constexpr after C++17
17 // unique_copy(InIter first, InIter last, OutIter result);
23 #include "test_macros.h"
24 #include "test_iterators.h"
26 struct AssignableFromMoveOnly
{
27 AssignableFromMoveOnly(int i
) : data(i
) {}
28 AssignableFromMoveOnly() : data(0) {}
30 AssignableFromMoveOnly
& operator=(MoveOnly
const& m
) {
34 bool operator==(AssignableFromMoveOnly
const& rhs
) const { return data
== rhs
.data
; }
38 TEST_CONSTEXPR
bool test_constexpr() {
39 int ia
[] = {0, 1, 2, 2, 4};
40 int ib
[] = {0, 0, 0, 0, 0};
41 const int expected
[] = {0, 1, 2, 4};
43 auto it
= std::unique_copy(std::begin(ia
), std::end(ia
), std::begin(ib
));
44 return it
== (std::begin(ib
) + std::size(expected
))
45 && *it
== 0 // don't overwrite final value in output
46 && std::equal(std::begin(ib
), it
, std::begin(expected
), std::end(expected
))
51 template <class InIter
, class OutIter
>
56 const unsigned sa
= sizeof(ia
)/sizeof(ia
[0]);
58 OutIter r
= std::unique_copy(InIter(ia
), InIter(ia
+sa
), OutIter(ja
));
59 assert(base(r
) == ja
+ sa
);
62 const int ib
[] = {0, 1};
63 const unsigned sb
= sizeof(ib
)/sizeof(ib
[0]);
65 r
= std::unique_copy(InIter(ib
), InIter(ib
+sb
), OutIter(jb
));
66 assert(base(r
) == jb
+ sb
);
70 const int ic
[] = {0, 0};
71 const unsigned sc
= sizeof(ic
)/sizeof(ic
[0]);
73 r
= std::unique_copy(InIter(ic
), InIter(ic
+sc
), OutIter(jc
));
74 assert(base(r
) == jc
+ 1);
77 const int id
[] = {0, 0, 1};
78 const unsigned sd
= sizeof(id
)/sizeof(id
[0]);
80 r
= std::unique_copy(InIter(id
), InIter(id
+sd
), OutIter(jd
));
81 assert(base(r
) == jd
+ 2);
85 const int ie
[] = {0, 0, 1, 0};
86 const unsigned se
= sizeof(ie
)/sizeof(ie
[0]);
88 r
= std::unique_copy(InIter(ie
), InIter(ie
+se
), OutIter(je
));
89 assert(base(r
) == je
+ 3);
94 const int ig
[] = {0, 0, 1, 1};
95 const unsigned sg
= sizeof(ig
)/sizeof(ig
[0]);
97 r
= std::unique_copy(InIter(ig
), InIter(ig
+sg
), OutIter(jg
));
98 assert(base(r
) == jg
+ 2);
102 const int ih
[] = {0, 1, 1};
103 const unsigned sh
= sizeof(ih
)/sizeof(ih
[0]);
105 r
= std::unique_copy(InIter(ih
), InIter(ih
+sh
), OutIter(jh
));
106 assert(base(r
) == jh
+ 2);
110 const int ii
[] = {0, 1, 1, 1, 2, 2, 2};
111 const unsigned si
= sizeof(ii
)/sizeof(ii
[0]);
113 r
= std::unique_copy(InIter(ii
), InIter(ii
+si
), OutIter(ji
));
114 assert(base(r
) == ji
+ 3);
120 int main(int, char**)
122 test
<cpp17_input_iterator
<const int*>, cpp17_input_iterator
<int*> >();
123 test
<cpp17_input_iterator
<const int*>, cpp17_output_iterator
<int*> >();
124 test
<cpp17_input_iterator
<const int*>, forward_iterator
<int*> >();
125 test
<cpp17_input_iterator
<const int*>, bidirectional_iterator
<int*> >();
126 test
<cpp17_input_iterator
<const int*>, random_access_iterator
<int*> >();
127 test
<cpp17_input_iterator
<const int*>, int*>();
129 test
<forward_iterator
<const int*>, cpp17_output_iterator
<int*> >();
130 test
<forward_iterator
<const int*>, forward_iterator
<int*> >();
131 test
<forward_iterator
<const int*>, bidirectional_iterator
<int*> >();
132 test
<forward_iterator
<const int*>, random_access_iterator
<int*> >();
133 test
<forward_iterator
<const int*>, int*>();
135 test
<bidirectional_iterator
<const int*>, cpp17_output_iterator
<int*> >();
136 test
<bidirectional_iterator
<const int*>, forward_iterator
<int*> >();
137 test
<bidirectional_iterator
<const int*>, bidirectional_iterator
<int*> >();
138 test
<bidirectional_iterator
<const int*>, random_access_iterator
<int*> >();
139 test
<bidirectional_iterator
<const int*>, int*>();
141 test
<random_access_iterator
<const int*>, cpp17_output_iterator
<int*> >();
142 test
<random_access_iterator
<const int*>, forward_iterator
<int*> >();
143 test
<random_access_iterator
<const int*>, bidirectional_iterator
<int*> >();
144 test
<random_access_iterator
<const int*>, random_access_iterator
<int*> >();
145 test
<random_access_iterator
<const int*>, int*>();
147 test
<const int*, cpp17_output_iterator
<int*> >();
148 test
<const int*, forward_iterator
<int*> >();
149 test
<const int*, bidirectional_iterator
<int*> >();
150 test
<const int*, random_access_iterator
<int*> >();
151 test
<const int*, int*>();
155 MoveOnly in
[5] = {1, 3, 3, 3, 1};
156 AssignableFromMoveOnly out
[3] = {};
157 auto result
= std::unique_copy(in
, in
+ 5, out
);
158 AssignableFromMoveOnly expected
[3] = {1, 3, 1};
159 assert(std::equal(out
, out
+ 3, expected
));
160 assert(result
== out
+ 3);
163 #if TEST_STD_VER > 17
164 static_assert(test_constexpr());