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