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 // <utility> 10 11 // template<ValueType T, size_t N> 12 // requires Swappable<T> 13 // void 14 // swap(T (&a)[N], T (&b)[N]); 15 16 #include <utility> 17 #include <cassert> 18 #include <memory> 19 20 #include "test_macros.h" 21 22 23 #if TEST_STD_VER >= 11 24 struct CopyOnly { 25 CopyOnly() {} 26 CopyOnly(CopyOnly const&) noexcept {} 27 CopyOnly& operator=(CopyOnly const&) { return *this; } 28 }; 29 30 31 struct NoexceptMoveOnly { 32 NoexceptMoveOnly() {} 33 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} 34 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } 35 }; 36 37 struct NotMoveConstructible { 38 NotMoveConstructible() {} 39 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } 40 private: 41 NotMoveConstructible(NotMoveConstructible&&); 42 }; 43 44 template <class Tp> 45 auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); 46 47 template <class Tp> 48 auto can_swap_test(...) -> std::false_type; 49 50 template <class Tp> 51 constexpr bool can_swap() { 52 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; 53 } 54 #endif 55 56 #if TEST_STD_VER > 17 57 constexpr bool test_swap_constexpr() 58 { 59 int i[3] = {1, 2, 3}; 60 int j[3] = {4, 5, 6}; 61 std::swap(i, j); 62 return i[0] == 4 && 63 i[1] == 5 && 64 i[2] == 6 && 65 j[0] == 1 && 66 j[1] == 2 && 67 j[2] == 3; 68 } 69 #endif // TEST_STD_VER > 17 70 71 int main(int, char**) 72 { 73 { 74 int i[3] = {1, 2, 3}; 75 int j[3] = {4, 5, 6}; 76 std::swap(i, j); 77 assert(i[0] == 4); 78 assert(i[1] == 5); 79 assert(i[2] == 6); 80 assert(j[0] == 1); 81 assert(j[1] == 2); 82 assert(j[2] == 3); 83 } 84 #if TEST_STD_VER >= 11 85 { 86 std::unique_ptr<int> i[3]; 87 for (int k = 0; k < 3; ++k) 88 i[k].reset(new int(k+1)); 89 std::unique_ptr<int> j[3]; 90 for (int k = 0; k < 3; ++k) 91 j[k].reset(new int(k+4)); 92 std::swap(i, j); 93 assert(*i[0] == 4); 94 assert(*i[1] == 5); 95 assert(*i[2] == 6); 96 assert(*j[0] == 1); 97 assert(*j[1] == 2); 98 assert(*j[2] == 3); 99 } 100 { 101 using CA = CopyOnly[42]; 102 using MA = NoexceptMoveOnly[42]; 103 using NA = NotMoveConstructible[42]; 104 static_assert(can_swap<CA&>(), ""); 105 static_assert(can_swap<MA&>(), ""); 106 static_assert(!can_swap<NA&>(), ""); 107 108 CA ca; 109 MA ma; 110 static_assert(!noexcept(std::swap(ca, ca)), ""); 111 static_assert(noexcept(std::swap(ma, ma)), ""); 112 } 113 #endif 114 115 #if TEST_STD_VER > 17 116 static_assert(test_swap_constexpr()); 117 #endif // TEST_STD_VER > 17 118 119 return 0; 120 } 121