118 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// test move10 11#include <utility>12#include <type_traits>13#include <cassert>14 15#include "test_macros.h"16 17class move_only18{19 move_only(const move_only&);20 move_only& operator=(const move_only&);21public:22 move_only(move_only&&) {}23 move_only& operator=(move_only&&) {return *this;}24 25 move_only() {}26};27 28move_only source() {return move_only();}29const move_only csource() {return move_only();}30 31void test(move_only) {}32 33int x = 42;34const int& cx = x;35 36template <class QualInt>37QualInt get() TEST_NOEXCEPT { return static_cast<QualInt>(x); }38 39 40int copy_ctor = 0;41int move_ctor = 0;42 43struct 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 > 1151constexpr bool test_constexpr_move() {52 int y = 42;53 const int cy = y;54 return std::move(y) == 4255 && std::move(cy) == 4256 && std::move(static_cast<int&&>(y)) == 4257 && std::move(static_cast<int const&&>(y)) == 42;58}59#endif60int 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 semantics73 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 type96 move_only mo;97 test(std::move(mo));98 test(source());99 }100#if TEST_STD_VER > 11101 {102 constexpr int y = 42;103 static_assert(std::move(y) == 42, "");104 static_assert(test_constexpr_move(), "");105 }106#endif107#if TEST_STD_VER == 11 && defined(_LIBCPP_VERSION)108 // Test that std::forward is constexpr in C++11. This is an extension109 // provided by both libc++ and libstdc++.110 {111 constexpr int y = 42;112 static_assert(std::move(y) == 42, "");113 }114#endif115 116 return 0;117}118