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