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 
21 using std::experimental::optional;
22 using std::experimental::in_place_t;
23 using std::experimental::in_place;
24 
25 class X
26 {
27     int i_;
28     int j_ = 0;
29 public:
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 
40 class Y
41 {
42     int i_;
43     int j_ = 0;
44 public:
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 
53 class Z
54 {
55     int i_;
56 public:
57     Z(int i) : i_(i) {throw 6;}
58 };
59 
60 
61 #endif  // _LIBCPP_STD_VER > 11
62 
63 int 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