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 // <optional>
11 
12 // optional(optional<T>&& rhs) noexcept(is_nothrow_move_constructible<T>::value);
13 
14 #include <experimental/optional>
15 #include <type_traits>
16 #include <cassert>
17 
18 #if _LIBCPP_STD_VER > 11
19 
20 using std::experimental::optional;
21 
22 template <class T>
23 void
test(optional<T> & rhs,bool is_going_to_throw=false)24 test(optional<T>& rhs, bool is_going_to_throw = false)
25 {
26     static_assert(std::is_nothrow_move_constructible<optional<T>>::value ==
27                   std::is_nothrow_move_constructible<T>::value, "");
28     bool rhs_engaged = static_cast<bool>(rhs);
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 }
40 
41 class X
42 {
43     int i_;
44 public:
X(int i)45     X(int i) : i_(i) {}
X(X && x)46     X(X&& x) : i_(x.i_) {x.i_ = 0;}
~X()47     ~X() {i_ = 0;}
operator ==(const X & x,const X & y)48     friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
49 };
50 
51 class Y
52 {
53     int i_;
54 public:
Y(int i)55     Y(int i) : i_(i) {}
Y(Y && x)56     Y(Y&& x) noexcept : i_(x.i_) {x.i_ = 0;}
57 
operator ==(const Y & x,const Y & y)58     friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
59 };
60 
61 int count = 0;
62 
63 class Z
64 {
65     int i_;
66 public:
Z(int i)67     Z(int i) : i_(i) {}
Z(Z &&)68     Z(Z&&)
69     {
70         if (++count == 2)
71             throw 6;
72     }
73 
operator ==(const Z & x,const Z & y)74     friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
75 };
76 
77 
78 #endif  // _LIBCPP_STD_VER > 11
79 
main()80 int main()
81 {
82 #if _LIBCPP_STD_VER > 11
83     {
84         typedef int T;
85         optional<T> rhs;
86         test(rhs);
87     }
88     {
89         typedef int T;
90         optional<T> rhs(3);
91         test(rhs);
92     }
93     {
94         typedef X T;
95         optional<T> rhs;
96         test(rhs);
97     }
98     {
99         typedef X T;
100         optional<T> rhs(X(3));
101         test(rhs);
102     }
103     {
104         typedef Y T;
105         optional<T> rhs;
106         test(rhs);
107     }
108     {
109         typedef Y T;
110         optional<T> rhs(Y(3));
111         test(rhs);
112     }
113     {
114         typedef Z T;
115         optional<T> rhs;
116         test(rhs);
117     }
118     {
119         typedef Z T;
120         optional<T> rhs(Z(3));
121         test(rhs, true);
122     }
123 #endif  // _LIBCPP_STD_VER > 11
124 }
125