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