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 24struct CopyOnly { 25 CopyOnly() {} 26 CopyOnly(CopyOnly const&) noexcept {} 27 CopyOnly& operator=(CopyOnly const&) { return *this; } 28}; 29 30struct MoveOnly { 31 MoveOnly() {} 32 MoveOnly(MoveOnly&&) {} 33 MoveOnly& operator=(MoveOnly&&) noexcept { return *this; } 34}; 35 36struct NoexceptMoveOnly { 37 NoexceptMoveOnly() {} 38 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} 39 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } 40}; 41 42struct NotMoveConstructible { 43 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } 44private: 45 NotMoveConstructible(NotMoveConstructible&&); 46}; 47 48struct NotMoveAssignable { 49 NotMoveAssignable(NotMoveAssignable&&); 50private: 51 NotMoveAssignable& operator=(NotMoveAssignable&&); 52}; 53 54template <class Tp> 55auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); 56 57template <class Tp> 58auto can_swap_test(...) -> std::false_type; 59 60template <class Tp> 61constexpr bool can_swap() { 62 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; 63} 64#endif 65 66int 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