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