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