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<InputIterator InIter, class OutIter, 13 // EquivalenceRelation<auto, InIter::value_type> Pred> 14 // requires OutputIterator<OutIter, RvalueOf<InIter::value_type>::type> 15 // && HasAssign<InIter::value_type, InIter::reference> 16 // && Constructible<InIter::value_type, InIter::reference> 17 // && CopyConstructible<Pred> 18 // constexpr OutIter // constexpr after C++17 19 // unique_copy(InIter first, InIter last, OutIter result, Pred pred); 20 21 #include <algorithm> 22 #include <cassert> 23 24 #include "test_macros.h" 25 #include "test_iterators.h" 26 27 #if TEST_STD_VER > 17 28 TEST_CONSTEXPR bool test_constexpr() { 29 int ia[] = {0, 1, 2, 2, 4}; 30 int ib[] = {0, 0, 0, 0, 0}; 31 const int expected[] = {0, 1, 2, 4}; 32 33 auto it = std::unique_copy(std::begin(ia), std::end(ia), std::begin(ib), 34 [](int a, int b) {return a == b; }); 35 return it == (std::begin(ib) + std::size(expected)) 36 && *it == 0 // don't overwrite final value in output 37 && std::equal(std::begin(ib), it, std::begin(expected), std::end(expected)) 38 ; 39 } 40 #endif 41 42 struct count_equal 43 { 44 static unsigned count; 45 template <class T> 46 bool operator()(const T& x, const T& y) 47 {++count; return x == y;} 48 }; 49 50 unsigned count_equal::count = 0; 51 52 template <class InIter, class OutIter> 53 void 54 test() 55 { 56 const int ia[] = {0}; 57 const unsigned sa = sizeof(ia)/sizeof(ia[0]); 58 int ja[sa] = {-1}; 59 count_equal::count = 0; 60 OutIter r = std::unique_copy(InIter(ia), InIter(ia+sa), OutIter(ja), count_equal()); 61 assert(base(r) == ja + sa); 62 assert(ja[0] == 0); 63 assert(count_equal::count == sa-1); 64 65 const int ib[] = {0, 1}; 66 const unsigned sb = sizeof(ib)/sizeof(ib[0]); 67 int jb[sb] = {-1}; 68 count_equal::count = 0; 69 r = std::unique_copy(InIter(ib), InIter(ib+sb), OutIter(jb), count_equal()); 70 assert(base(r) == jb + sb); 71 assert(jb[0] == 0); 72 assert(jb[1] == 1); 73 assert(count_equal::count == sb-1); 74 75 const int ic[] = {0, 0}; 76 const unsigned sc = sizeof(ic)/sizeof(ic[0]); 77 int jc[sc] = {-1}; 78 count_equal::count = 0; 79 r = std::unique_copy(InIter(ic), InIter(ic+sc), OutIter(jc), count_equal()); 80 assert(base(r) == jc + 1); 81 assert(jc[0] == 0); 82 assert(count_equal::count == sc-1); 83 84 const int id[] = {0, 0, 1}; 85 const unsigned sd = sizeof(id)/sizeof(id[0]); 86 int jd[sd] = {-1}; 87 count_equal::count = 0; 88 r = std::unique_copy(InIter(id), InIter(id+sd), OutIter(jd), count_equal()); 89 assert(base(r) == jd + 2); 90 assert(jd[0] == 0); 91 assert(jd[1] == 1); 92 assert(count_equal::count == sd-1); 93 94 const int ie[] = {0, 0, 1, 0}; 95 const unsigned se = sizeof(ie)/sizeof(ie[0]); 96 int je[se] = {-1}; 97 count_equal::count = 0; 98 r = std::unique_copy(InIter(ie), InIter(ie+se), OutIter(je), count_equal()); 99 assert(base(r) == je + 3); 100 assert(je[0] == 0); 101 assert(je[1] == 1); 102 assert(je[2] == 0); 103 assert(count_equal::count == se-1); 104 105 const int ig[] = {0, 0, 1, 1}; 106 const unsigned sg = sizeof(ig)/sizeof(ig[0]); 107 int jg[sg] = {-1}; 108 count_equal::count = 0; 109 r = std::unique_copy(InIter(ig), InIter(ig+sg), OutIter(jg), count_equal()); 110 assert(base(r) == jg + 2); 111 assert(jg[0] == 0); 112 assert(jg[1] == 1); 113 assert(count_equal::count == sg-1); 114 115 const int ih[] = {0, 1, 1}; 116 const unsigned sh = sizeof(ih)/sizeof(ih[0]); 117 int jh[sh] = {-1}; 118 count_equal::count = 0; 119 r = std::unique_copy(InIter(ih), InIter(ih+sh), OutIter(jh), count_equal()); 120 assert(base(r) == jh + 2); 121 assert(jh[0] == 0); 122 assert(jh[1] == 1); 123 assert(count_equal::count == sh-1); 124 125 const int ii[] = {0, 1, 1, 1, 2, 2, 2}; 126 const unsigned si = sizeof(ii)/sizeof(ii[0]); 127 int ji[si] = {-1}; 128 count_equal::count = 0; 129 r = std::unique_copy(InIter(ii), InIter(ii+si), OutIter(ji), count_equal()); 130 assert(base(r) == ji + 3); 131 assert(ji[0] == 0); 132 assert(ji[1] == 1); 133 assert(ji[2] == 2); 134 assert(count_equal::count == si-1); 135 } 136 137 int main() 138 { 139 test<input_iterator<const int*>, output_iterator<int*> >(); 140 test<input_iterator<const int*>, forward_iterator<int*> >(); 141 test<input_iterator<const int*>, bidirectional_iterator<int*> >(); 142 test<input_iterator<const int*>, random_access_iterator<int*> >(); 143 test<input_iterator<const int*>, int*>(); 144 145 test<forward_iterator<const int*>, output_iterator<int*> >(); 146 test<forward_iterator<const int*>, forward_iterator<int*> >(); 147 test<forward_iterator<const int*>, bidirectional_iterator<int*> >(); 148 test<forward_iterator<const int*>, random_access_iterator<int*> >(); 149 test<forward_iterator<const int*>, int*>(); 150 151 test<bidirectional_iterator<const int*>, output_iterator<int*> >(); 152 test<bidirectional_iterator<const int*>, forward_iterator<int*> >(); 153 test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >(); 154 test<bidirectional_iterator<const int*>, random_access_iterator<int*> >(); 155 test<bidirectional_iterator<const int*>, int*>(); 156 157 test<random_access_iterator<const int*>, output_iterator<int*> >(); 158 test<random_access_iterator<const int*>, forward_iterator<int*> >(); 159 test<random_access_iterator<const int*>, bidirectional_iterator<int*> >(); 160 test<random_access_iterator<const int*>, random_access_iterator<int*> >(); 161 test<random_access_iterator<const int*>, int*>(); 162 163 test<const int*, output_iterator<int*> >(); 164 test<const int*, forward_iterator<int*> >(); 165 test<const int*, bidirectional_iterator<int*> >(); 166 test<const int*, random_access_iterator<int*> >(); 167 test<const int*, int*>(); 168 169 #if TEST_STD_VER > 17 170 static_assert(test_constexpr()); 171 #endif 172 } 173