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 | // UNSUPPORTED: c++03, c++11, c++14 |
10 | // <optional> |
11 | |
12 | // template <class U> |
13 | // optional(optional<U>&& rhs); |
14 | |
15 | #include <cassert> |
16 | #include <memory> |
17 | #include <optional> |
18 | #include <type_traits> |
19 | #include <utility> |
20 | |
21 | #include "test_macros.h" |
22 | |
23 | using std::optional; |
24 | |
25 | template <class T, class U> |
26 | TEST_CONSTEXPR_CXX20 void |
27 | test(optional<U>&& rhs, bool is_going_to_throw = false) |
28 | { |
29 | bool rhs_engaged = static_cast<bool>(rhs); |
30 | #ifndef TEST_HAS_NO_EXCEPTIONS |
31 | try |
32 | { |
33 | optional<T> lhs = std::move(rhs); |
34 | assert(is_going_to_throw == false); |
35 | assert(static_cast<bool>(lhs) == rhs_engaged); |
36 | } |
37 | catch (int i) |
38 | { |
39 | assert(i == 6); |
40 | } |
41 | #else |
42 | if (is_going_to_throw) return; |
43 | optional<T> lhs = std::move(rhs); |
44 | assert(static_cast<bool>(lhs) == rhs_engaged); |
45 | #endif |
46 | } |
47 | |
48 | class X |
49 | { |
50 | int i_; |
51 | public: |
52 | TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {} |
53 | TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {} |
54 | TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;} |
55 | friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} |
56 | }; |
57 | |
58 | struct Z |
59 | { |
60 | Z(int) { TEST_THROW(6); } |
61 | }; |
62 | |
63 | template<class T, class U> |
64 | TEST_CONSTEXPR_CXX20 bool test_all() |
65 | { |
66 | { |
67 | optional<T> rhs; |
68 | test<U>(std::move(rhs)); |
69 | } |
70 | { |
71 | optional<T> rhs(short{3}); |
72 | test<U>(std::move(rhs)); |
73 | } |
74 | return true; |
75 | } |
76 | |
77 | int main(int, char**) |
78 | { |
79 | test_all<short, int>(); |
80 | test_all<int, X>(); |
81 | #if TEST_STD_VER > 17 |
82 | static_assert(test_all<short, int>()); |
83 | static_assert(test_all<int, X>()); |
84 | #endif |
85 | { |
86 | optional<int> rhs; |
87 | test<Z>(std::move(rhs)); |
88 | } |
89 | { |
90 | optional<int> rhs(3); |
91 | test<Z>(std::move(rhs), true); |
92 | } |
93 | |
94 | static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "" ); |
95 | |
96 | return 0; |
97 | } |
98 | |