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// constexpr optional(T&& v);
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
22class X
23{
24    int i_;
25public:
26    X(int i) : i_(i) {}
27    X(X&& x) : i_(x.i_) {}
28
29    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
30};
31
32class Y
33{
34    int i_;
35public:
36    constexpr Y(int i) : i_(i) {}
37    constexpr Y(Y&& x) : i_(x.i_) {}
38
39    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
40};
41
42class Z
43{
44    int i_;
45public:
46    Z(int i) : i_(i) {}
47    Z(Z&&) {throw 6;}
48};
49
50#endif  // _LIBCPP_STD_VER > 11
51
52int main()
53{
54#if _LIBCPP_STD_VER > 11
55    {
56        typedef int T;
57        constexpr optional<T> opt(T(5));
58        static_assert(static_cast<bool>(opt) == true, "");
59        static_assert(*opt == 5, "");
60
61        struct test_constexpr_ctor
62            : public optional<T>
63        {
64            constexpr test_constexpr_ctor(T&&) {}
65        };
66    }
67    {
68        typedef double T;
69        constexpr optional<T> opt(T(3));
70        static_assert(static_cast<bool>(opt) == true, "");
71        static_assert(*opt == 3, "");
72
73        struct test_constexpr_ctor
74            : public optional<T>
75        {
76            constexpr test_constexpr_ctor(T&&) {}
77        };
78    }
79    {
80        typedef X T;
81        optional<T> opt(T(3));
82        assert(static_cast<bool>(opt) == true);
83        assert(*opt == 3);
84    }
85    {
86        typedef Y T;
87        constexpr optional<T> opt(T(3));
88        static_assert(static_cast<bool>(opt) == true, "");
89        static_assert(*opt == 3, "");
90
91        struct test_constexpr_ctor
92            : public optional<T>
93        {
94            constexpr test_constexpr_ctor(T&&) {}
95        };
96    }
97    {
98        typedef Z T;
99        try
100        {
101            optional<T> opt(T(3));
102            assert(false);
103        }
104        catch (int i)
105        {
106            assert(i == 6);
107        }
108    }
109#endif  // _LIBCPP_STD_VER > 11
110}
111