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