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 // test move 11 12 // UNSUPPORTED: c++98, c++03 13 14 #include <utility> 15 #include <type_traits> 16 #include <cassert> 17 18 #include "test_macros.h" 19 20 class move_only 21 { 22 move_only(const move_only&); 23 move_only& operator=(const move_only&); 24 public: 25 move_only(move_only&&) {} 26 move_only& operator=(move_only&&) {return *this;} 27 28 move_only() {} 29 }; 30 31 move_only source() {return move_only();} 32 const move_only csource() {return move_only();} 33 34 void test(move_only) {} 35 36 int x = 42; 37 const int& cx = x; 38 39 template <class QualInt> 40 QualInt get() noexcept { return static_cast<QualInt>(x); } 41 42 43 int copy_ctor = 0; 44 int move_ctor = 0; 45 46 struct A { 47 A() {} 48 A(const A&) {++copy_ctor;} 49 A(A&&) {++move_ctor;} 50 A& operator=(const A&) = delete; 51 }; 52 53 constexpr bool test_constexpr_move() { 54 #if TEST_STD_VER > 11 55 int y = 42; 56 const int cy = y; 57 return std::move(y) == 42 58 && std::move(cy) == 42 59 && std::move(static_cast<int&&>(y)) == 42 60 && std::move(static_cast<int const&&>(y)) == 42; 61 #else 62 return true; 63 #endif 64 } 65 66 int main() 67 { 68 { // Test return type and noexcept. 69 static_assert(std::is_same<decltype(std::move(x)), int&&>::value, ""); 70 static_assert(noexcept(std::move(x)), ""); 71 static_assert(std::is_same<decltype(std::move(cx)), const int&&>::value, ""); 72 static_assert(noexcept(std::move(cx)), ""); 73 static_assert(std::is_same<decltype(std::move(42)), int&&>::value, ""); 74 static_assert(noexcept(std::move(42)), ""); 75 static_assert(std::is_same<decltype(std::move(get<const int&&>())), const int&&>::value, ""); 76 static_assert(noexcept(std::move(get<int const&&>())), ""); 77 } 78 { // test copy and move semantics 79 A a; 80 const A ca = A(); 81 82 assert(copy_ctor == 0); 83 assert(move_ctor == 0); 84 85 A a2 = a; 86 assert(copy_ctor == 1); 87 assert(move_ctor == 0); 88 89 A a3 = std::move(a); 90 assert(copy_ctor == 1); 91 assert(move_ctor == 1); 92 93 A a4 = ca; 94 assert(copy_ctor == 2); 95 assert(move_ctor == 1); 96 97 A a5 = std::move(ca); 98 assert(copy_ctor == 3); 99 assert(move_ctor == 1); 100 } 101 { // test on a move only type 102 move_only mo; 103 test(std::move(mo)); 104 test(source()); 105 } 106 #if TEST_STD_VER > 11 107 { 108 constexpr int y = 42; 109 static_assert(std::move(y) == 42, ""); 110 static_assert(test_constexpr_move(), ""); 111 } 112 #endif 113 #if TEST_STD_VER == 11 && defined(_LIBCPP_VERSION) 114 // Test that std::forward is constexpr in C++11. This is an extension 115 // provided by both libc++ and libstdc++. 116 { 117 constexpr int y = 42; 118 static_assert(std::move(y) == 42, ""); 119 } 120 #endif 121 } 122