1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <utility> 11 12 // template<class T> 13 // requires MoveAssignable<T> && MoveConstructible<T> 14 // void 15 // swap(T& a, T& b); 16 17 #include <utility> 18 #include <cassert> 19 #include <memory> 20 21 #include "test_macros.h" 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 struct MoveOnly { 31 MoveOnly() {} 32 MoveOnly(MoveOnly&&) {} 33 MoveOnly& operator=(MoveOnly&&) noexcept { return *this; } 34 }; 35 36 struct NoexceptMoveOnly { 37 NoexceptMoveOnly() {} 38 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} 39 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } 40 }; 41 42 struct NotMoveConstructible { 43 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } 44 private: 45 NotMoveConstructible(NotMoveConstructible&&); 46 }; 47 48 struct NotMoveAssignable { 49 NotMoveAssignable(NotMoveAssignable&&); 50 private: 51 NotMoveAssignable& operator=(NotMoveAssignable&&); 52 }; 53 54 template <class Tp> 55 auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); 56 57 template <class Tp> 58 auto can_swap_test(...) -> std::false_type; 59 60 template <class Tp> 61 constexpr bool can_swap() { 62 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; 63 } 64 #endif 65 66 int main() 67 { 68 69 { 70 int i = 1; 71 int j = 2; 72 std::swap(i, j); 73 assert(i == 2); 74 assert(j == 1); 75 } 76 #if TEST_STD_VER >= 11 77 { 78 79 std::unique_ptr<int> i(new int(1)); 80 std::unique_ptr<int> j(new int(2)); 81 std::swap(i, j); 82 assert(*i == 2); 83 assert(*j == 1); 84 85 } 86 { 87 // test that the swap 88 static_assert(can_swap<CopyOnly&>(), ""); 89 static_assert(can_swap<MoveOnly&>(), ""); 90 static_assert(can_swap<NoexceptMoveOnly&>(), ""); 91 92 static_assert(!can_swap<NotMoveConstructible&>(), ""); 93 static_assert(!can_swap<NotMoveAssignable&>(), ""); 94 95 CopyOnly c; 96 MoveOnly m; 97 NoexceptMoveOnly nm; 98 static_assert(!noexcept(std::swap(c, c)), ""); 99 static_assert(!noexcept(std::swap(m, m)), ""); 100 static_assert(noexcept(std::swap(nm, nm)), ""); 101 } 102 #endif 103 } 104