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// template <class... Args>
13//   constexpr explicit optional(in_place_t, Args&&... args);
14
15#include <experimental/optional>
16#include <type_traits>
17#include <cassert>
18
19#if _LIBCPP_STD_VER > 11
20
21using std::experimental::optional;
22using std::experimental::in_place_t;
23using std::experimental::in_place;
24
25class X
26{
27    int i_;
28    int j_ = 0;
29public:
30    X() : i_(0) {}
31    X(int i) : i_(i) {}
32    X(int i, int j) : i_(i), j_(j) {}
33
34    ~X() {}
35
36    friend bool operator==(const X& x, const X& y)
37        {return x.i_ == y.i_ && x.j_ == y.j_;}
38};
39
40class Y
41{
42    int i_;
43    int j_ = 0;
44public:
45    constexpr Y() : i_(0) {}
46    constexpr Y(int i) : i_(i) {}
47    constexpr Y(int i, int j) : i_(i), j_(j) {}
48
49    friend constexpr bool operator==(const Y& x, const Y& y)
50        {return x.i_ == y.i_ && x.j_ == y.j_;}
51};
52
53class Z
54{
55    int i_;
56public:
57    Z(int i) : i_(i) {throw 6;}
58};
59
60
61#endif  // _LIBCPP_STD_VER > 11
62
63int main()
64{
65#if _LIBCPP_STD_VER > 11
66    {
67        constexpr optional<int> opt(in_place, 5);
68        static_assert(static_cast<bool>(opt) == true, "");
69        static_assert(*opt == 5, "");
70
71        struct test_constexpr_ctor
72            : public optional<int>
73        {
74            constexpr test_constexpr_ctor(in_place_t, int i)
75                : optional<int>(in_place, i) {}
76        };
77
78    }
79    {
80        const optional<X> opt(in_place);
81        assert(static_cast<bool>(opt) == true);
82        assert(*opt == X());
83    }
84    {
85        const optional<X> opt(in_place, 5);
86        assert(static_cast<bool>(opt) == true);
87        assert(*opt == X(5));
88    }
89    {
90        const optional<X> opt(in_place, 5, 4);
91        assert(static_cast<bool>(opt) == true);
92        assert(*opt == X(5, 4));
93    }
94    {
95        constexpr optional<Y> opt(in_place);
96        static_assert(static_cast<bool>(opt) == true, "");
97        static_assert(*opt == Y(), "");
98
99        struct test_constexpr_ctor
100            : public optional<Y>
101        {
102            constexpr test_constexpr_ctor(in_place_t)
103                : optional<Y>(in_place) {}
104        };
105
106    }
107    {
108        constexpr optional<Y> opt(in_place, 5);
109        static_assert(static_cast<bool>(opt) == true, "");
110        static_assert(*opt == Y(5), "");
111
112        struct test_constexpr_ctor
113            : public optional<Y>
114        {
115            constexpr test_constexpr_ctor(in_place_t, int i)
116                : optional<Y>(in_place, i) {}
117        };
118
119    }
120    {
121        constexpr optional<Y> opt(in_place, 5, 4);
122        static_assert(static_cast<bool>(opt) == true, "");
123        static_assert(*opt == Y(5, 4), "");
124
125        struct test_constexpr_ctor
126            : public optional<Y>
127        {
128            constexpr test_constexpr_ctor(in_place_t, int i, int j)
129                : optional<Y>(in_place, i, j) {}
130        };
131
132    }
133    {
134        try
135        {
136            const optional<Z> opt(in_place, 1);
137            assert(false);
138        }
139        catch (int i)
140        {
141            assert(i == 6);
142        }
143    }
144#endif  // _LIBCPP_STD_VER > 11
145}
146