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