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
20using std::experimental::optional;
21
22template <class T>
23void
24test(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
41class X
42{
43    int i_;
44public:
45    X(int i) : i_(i) {}
46    X(X&& x) : i_(x.i_) {x.i_ = 0;}
47    ~X() {i_ = 0;}
48    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
49};
50
51class Y
52{
53    int i_;
54public:
55    Y(int i) : i_(i) {}
56    Y(Y&& x) noexcept : i_(x.i_) {x.i_ = 0;}
57
58    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
59};
60
61int count = 0;
62
63class Z
64{
65    int i_;
66public:
67    Z(int i) : i_(i) {}
68    Z(Z&&)
69    {
70        if (++count == 2)
71            throw 6;
72    }
73
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
80int 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