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 // UNSUPPORTED: c++03 && !stdlib=libc++ 10 // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000 11 12 // <algorithm> 13 14 // template<InputIterator InIter, typename OutIter> 15 // requires OutputIterator<OutIter, RvalueOf<InIter::reference>::type> 16 // OutIter 17 // move(InIter first, InIter last, OutIter result); 18 19 #include <algorithm> 20 #include <cassert> 21 #include <iterator> 22 #include <memory> 23 24 #include "MoveOnly.h" 25 #include "test_iterators.h" 26 #include "test_macros.h" 27 28 class PaddedBase { 29 public: 30 TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {} 31 32 std::int16_t a_; 33 std::int8_t b_; 34 }; 35 36 class Derived : public PaddedBase { 37 public: 38 TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {} 39 40 std::int8_t c_; 41 }; 42 43 template <class InIter> 44 struct Test { 45 template <class OutIter> 46 TEST_CONSTEXPR_CXX20 void operator()() { 47 const unsigned N = 1000; 48 int ia[N] = {}; 49 for (unsigned i = 0; i < N; ++i) 50 ia[i] = i; 51 int ib[N] = {0}; 52 53 OutIter r = std::move(InIter(ia), InIter(ia+N), OutIter(ib)); 54 assert(base(r) == ib+N); 55 for (unsigned i = 0; i < N; ++i) 56 assert(ia[i] == ib[i]); 57 } 58 }; 59 60 struct TestOutIters { 61 template <class InIter> 62 TEST_CONSTEXPR_CXX20 void operator()() { 63 types::for_each( 64 types::concatenate_t<types::cpp17_input_iterator_list<int*>, types::type_list<cpp17_output_iterator<int*> > >(), 65 Test<InIter>()); 66 } 67 }; 68 69 template <class InIter> 70 struct Test1 { 71 template <class OutIter> 72 TEST_CONSTEXPR_CXX23 void operator()() { 73 const unsigned N = 100; 74 std::unique_ptr<int> ia[N]; 75 for (unsigned i = 0; i < N; ++i) 76 ia[i].reset(new int(i)); 77 std::unique_ptr<int> ib[N]; 78 79 OutIter r = std::move(InIter(ia), InIter(ia+N), OutIter(ib)); 80 assert(base(r) == ib+N); 81 for (unsigned i = 0; i < N; ++i) 82 assert(*ib[i] == static_cast<int>(i)); 83 } 84 }; 85 86 struct Test1OutIters { 87 template <class InIter> 88 TEST_CONSTEXPR_CXX23 void operator()() { 89 types::for_each(types::concatenate_t<types::cpp17_input_iterator_list<std::unique_ptr<int>*>, 90 types::type_list<cpp17_output_iterator<std::unique_ptr<int>*> > >(), 91 Test1<InIter>()); 92 } 93 }; 94 95 TEST_CONSTEXPR_CXX20 bool test() { 96 types::for_each(types::cpp17_input_iterator_list<int*>(), TestOutIters()); 97 if (TEST_STD_VER >= 23 || !TEST_IS_CONSTANT_EVALUATED) 98 types::for_each(types::cpp17_input_iterator_list<std::unique_ptr<int>*>(), Test1OutIters()); 99 100 { // Make sure that padding bits aren't copied 101 Derived src(1, 2, 3); 102 Derived dst(4, 5, 6); 103 std::move(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst)); 104 assert(dst.a_ == 1); 105 assert(dst.b_ == 2); 106 assert(dst.c_ == 6); 107 } 108 109 { // Make sure that overlapping ranges can be copied 110 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 111 std::move(a + 3, a + 10, a); 112 int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10}; 113 assert(std::equal(a, a + 10, expected)); 114 } 115 116 // Make sure that the algorithm works with move-only types 117 { 118 // When non-trivial 119 { 120 MoveOnly from[3] = {1, 2, 3}; 121 MoveOnly to[3] = {}; 122 std::move(std::begin(from), std::end(from), std::begin(to)); 123 assert(to[0] == MoveOnly(1)); 124 assert(to[1] == MoveOnly(2)); 125 assert(to[2] == MoveOnly(3)); 126 } 127 // When trivial 128 { 129 TrivialMoveOnly from[3] = {1, 2, 3}; 130 TrivialMoveOnly to[3] = {}; 131 std::move(std::begin(from), std::end(from), std::begin(to)); 132 assert(to[0] == TrivialMoveOnly(1)); 133 assert(to[1] == TrivialMoveOnly(2)); 134 assert(to[2] == TrivialMoveOnly(3)); 135 } 136 } 137 138 return true; 139 } 140 141 int main(int, char**) { 142 test(); 143 #if TEST_STD_VER >= 20 144 static_assert(test()); 145 #endif 146 147 return 0; 148 } 149