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, c++11, c++14, c++17 10 11 // <algorithm> 12 13 // template<class ForwardIterator> 14 // constexpr ForwardIterator 15 // shift_left(ForwardIterator first, ForwardIterator last, 16 // typename iterator_traits<ForwardIterator>::difference_type n); 17 18 #include <algorithm> 19 #include <cassert> 20 21 #include "test_macros.h" 22 #include "test_iterators.h" 23 #include "MoveOnly.h" 24 25 template<class T, class Iter> 26 constexpr bool test() 27 { 28 int orig[] = {3,1,4,1,5, 9,2,6,5,3, 5,8,9,7,9}; 29 T work[] = {3,1,4,1,5, 9,2,6,5,3, 5,8,9,7,9}; 30 31 for (int n = 0; n <= 15; ++n) { 32 for (int k = 0; k <= n+2; ++k) { 33 std::copy(orig, orig+n, work); 34 Iter it = std::shift_left(Iter(work), Iter(work+n), k); 35 if (0 <= k && k < n) { 36 assert(it == Iter(work+n-k)); 37 assert(std::equal(orig+k, orig+n, work, work+n-k)); 38 } else { 39 assert(it == Iter(work)); 40 assert(std::equal(orig, orig+n, work, work+n)); 41 } 42 } 43 } 44 45 // n == 0 46 { 47 T input[] = { 0, 1, 2 }; 48 const T expected[] = { 0, 1, 2 }; 49 Iter b = Iter(std::begin(input)); 50 Iter e = Iter(std::end(input)); 51 Iter it = std::shift_left(b, e, 0); 52 assert(std::equal(std::begin(expected), std::end(expected), b, e)); 53 assert(it == e); 54 } 55 56 // n > 0 && n < len 57 { 58 T input[] = { 0, 1, 2 }; 59 const T expected[] = { 1, 2 }; 60 Iter b = Iter(std::begin(input)); 61 Iter e = Iter(std::end(input)); 62 Iter it = std::shift_left(b, e, 1); 63 assert(std::equal(std::begin(expected), std::end(expected), b, it)); 64 } 65 { 66 T input[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 67 const T expected[] = { 3, 4, 5, 6, 7, 8 }; 68 Iter b = Iter(std::begin(input)); 69 Iter e = Iter(std::end(input)); 70 Iter it = std::shift_left(b, e, 2); 71 assert(std::equal(std::begin(expected), std::end(expected), b, it)); 72 } 73 { 74 T input[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 75 const T expected[] = { 7, 8 }; 76 Iter b = Iter(std::begin(input)); 77 Iter e = Iter(std::end(input)); 78 Iter it = std::shift_left(b, e, 6); 79 assert(std::equal(std::begin(expected), std::end(expected), b, it)); 80 } 81 82 // n == len 83 { 84 T input[] = { 0, 1, 2 }; 85 const T expected[] = { 0, 1, 2 }; 86 Iter b = Iter(std::begin(input)); 87 Iter e = Iter(std::end(input)); 88 Iter it = std::shift_left(b, e, std::size(input)); 89 assert(std::equal(std::begin(expected), std::end(expected), b, e)); 90 assert(it == b); 91 } 92 93 // n > len 94 { 95 T input[] = { 0, 1, 2 }; 96 const T expected[] = { 0, 1, 2 }; 97 Iter b = Iter(std::begin(input)); 98 Iter e = Iter(std::end(input)); 99 Iter it = std::shift_left(b, e, std::size(input) + 1); 100 assert(std::equal(std::begin(expected), std::end(expected), b, e)); 101 assert(it == b); 102 } 103 104 return true; 105 } 106 107 int main(int, char**) 108 { 109 test<int, forward_iterator<int*>>(); 110 test<int, bidirectional_iterator<int*>>(); 111 test<int, random_access_iterator<int*>>(); 112 test<int, int*>(); 113 test<MoveOnly, forward_iterator<MoveOnly*>>(); 114 test<MoveOnly, bidirectional_iterator<MoveOnly*>>(); 115 test<MoveOnly, random_access_iterator<MoveOnly*>>(); 116 test<MoveOnly, MoveOnly*>(); 117 118 static_assert(test<int, forward_iterator<int*>>()); 119 static_assert(test<int, bidirectional_iterator<int*>>()); 120 static_assert(test<int, random_access_iterator<int*>>()); 121 static_assert(test<int, int*>()); 122 static_assert(test<MoveOnly, forward_iterator<MoveOnly*>>()); 123 static_assert(test<MoveOnly, bidirectional_iterator<MoveOnly*>>()); 124 static_assert(test<MoveOnly, random_access_iterator<MoveOnly*>>()); 125 static_assert(test<MoveOnly, MoveOnly*>()); 126 127 return 0; 128 } 129