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
17class move_only
18{
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 > 11
51constexpr 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
60int 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

source code of libcxx/test/std/utilities/utility/forward/move.pass.cpp