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