]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / optional / optional.object / optional.object.assign / move.pass.cpp
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 // UNSUPPORTED: c++98, c++03, c++11, c++14
11 // <optional>
12
13 // optional<T>& operator=(optional<T>&& rhs)
14 //     noexcept(is_nothrow_move_assignable<T>::value &&
15 //              is_nothrow_move_constructible<T>::value);
16
17 #include <optional>
18 #include <type_traits>
19 #include <cassert>
20
21 #include "test_macros.h"
22 #include "archetypes.hpp"
23
24 using std::optional;
25
26 struct X
27 {
28     static bool throw_now;
29     static int alive;
30
31     X() { ++alive; }
32     X(X&&)
33     {
34         if (throw_now)
35             TEST_THROW(6);
36         ++alive;
37     }
38
39     X& operator=(X&&)
40     {
41         if (throw_now)
42             TEST_THROW(42);
43         return *this;
44     }
45
46     ~X() { assert(alive > 0); --alive; }
47 };
48
49 struct Y {};
50
51 bool X::throw_now = false;
52 int X::alive = 0;
53
54 int main()
55 {
56     {
57         static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
58         optional<int> opt;
59         constexpr optional<int> opt2;
60         opt = std::move(opt2);
61         static_assert(static_cast<bool>(opt2) == false, "");
62         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
63     }
64     {
65         optional<int> opt;
66         constexpr optional<int> opt2(2);
67         opt = std::move(opt2);
68         static_assert(static_cast<bool>(opt2) == true, "");
69         static_assert(*opt2 == 2, "");
70         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
71         assert(*opt == *opt2);
72     }
73     {
74         optional<int> opt(3);
75         constexpr optional<int> opt2;
76         opt = std::move(opt2);
77         static_assert(static_cast<bool>(opt2) == false, "");
78         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
79     }
80     {
81         using T = TestTypes::TestType;
82         T::reset();
83         optional<T> opt(3);
84         optional<T> opt2;
85         assert(T::alive == 1);
86         opt = std::move(opt2);
87         assert(T::alive == 0);
88         assert(static_cast<bool>(opt2) == false);
89         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
90     }
91     {
92         optional<int> opt(3);
93         constexpr optional<int> opt2(2);
94         opt = std::move(opt2);
95         static_assert(static_cast<bool>(opt2) == true, "");
96         static_assert(*opt2 == 2, "");
97         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
98         assert(*opt == *opt2);
99     }
100 #ifndef TEST_HAS_NO_EXCEPTIONS
101     {
102         static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
103         X::alive = 0;
104         X::throw_now = false;
105         optional<X> opt;
106         optional<X> opt2(X{});
107         assert(X::alive == 1);
108         assert(static_cast<bool>(opt2) == true);
109         try
110         {
111             X::throw_now = true;
112             opt = std::move(opt2);
113             assert(false);
114         }
115         catch (int i)
116         {
117             assert(i == 6);
118             assert(static_cast<bool>(opt) == false);
119         }
120         assert(X::alive == 1);
121     }
122     assert(X::alive == 0);
123     {
124         static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
125         X::throw_now = false;
126         optional<X> opt(X{});
127         optional<X> opt2(X{});
128         assert(X::alive == 2);
129         assert(static_cast<bool>(opt2) == true);
130         try
131         {
132             X::throw_now = true;
133             opt = std::move(opt2);
134             assert(false);
135         }
136         catch (int i)
137         {
138             assert(i == 42);
139             assert(static_cast<bool>(opt) == true);
140         }
141         assert(X::alive == 2);
142     }
143     assert(X::alive == 0);
144 #endif // TEST_HAS_NO_EXCEPTIONS
145     {
146         static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
147     }
148     {
149         struct ThrowsMove {
150           ThrowsMove() noexcept {}
151           ThrowsMove(ThrowsMove const&) noexcept {}
152           ThrowsMove(ThrowsMove &&) noexcept(false) {}
153           ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; }
154           ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
155         };
156         static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, "");
157         struct ThrowsMoveAssign {
158           ThrowsMoveAssign() noexcept {}
159           ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
160           ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
161           ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; }
162           ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; }
163         };
164         static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, "");
165         struct NoThrowMove {
166           NoThrowMove() noexcept(false) {}
167           NoThrowMove(NoThrowMove const&) noexcept(false) {}
168           NoThrowMove(NoThrowMove &&) noexcept {}
169           NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; }
170           NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
171         };
172         static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, "");
173     }
174 }