1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: c++03, c++11, c++14
10 
11 // <optional>
12 
13 // template <class... Args>
14 //   constexpr explicit optional(in_place_t, Args&&... args);
15 
16 #include <optional>
17 #include <type_traits>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 
22 using std::optional;
23 using std::in_place_t;
24 using std::in_place;
25 
26 class X
27 {
28     int i_;
29     int j_ = 0;
30 public:
X()31     X() : i_(0) {}
X(int i)32     X(int i) : i_(i) {}
X(int i,int j)33     X(int i, int j) : i_(i), j_(j) {}
34 
~X()35     ~X() {}
36 
operator ==(const X & x,const X & y)37     friend bool operator==(const X& x, const X& y)
38         {return x.i_ == y.i_ && x.j_ == y.j_;}
39 };
40 
41 class Y
42 {
43     int i_;
44     int j_ = 0;
45 public:
Y()46     constexpr Y() : i_(0) {}
Y(int i)47     constexpr Y(int i) : i_(i) {}
Y(int i,int j)48     constexpr Y(int i, int j) : i_(i), j_(j) {}
49 
operator ==(const Y & x,const Y & y)50     friend constexpr bool operator==(const Y& x, const Y& y)
51         {return x.i_ == y.i_ && x.j_ == y.j_;}
52 };
53 
54 class Z
55 {
56 public:
Z(int)57     Z(int) {TEST_THROW(6);}
58 };
59 
60 
main(int,char **)61 int main(int, char**)
62 {
63     {
64         constexpr optional<int> opt(in_place, 5);
65         static_assert(static_cast<bool>(opt) == true, "");
66         static_assert(*opt == 5, "");
67 
68         struct test_constexpr_ctor
69             : public optional<int>
70         {
71             constexpr test_constexpr_ctor(in_place_t, int i)
72                 : optional<int>(in_place, i) {}
73         };
74 
75     }
76     {
77         optional<const int> opt(in_place, 5);
78         assert(*opt == 5);
79     }
80     {
81         const optional<X> opt(in_place);
82         assert(static_cast<bool>(opt) == true);
83         assert(*opt == X());
84     }
85     {
86         const optional<X> opt(in_place, 5);
87         assert(static_cast<bool>(opt) == true);
88         assert(*opt == X(5));
89     }
90     {
91         const optional<X> opt(in_place, 5, 4);
92         assert(static_cast<bool>(opt) == true);
93         assert(*opt == X(5, 4));
94     }
95     {
96         constexpr optional<Y> opt(in_place);
97         static_assert(static_cast<bool>(opt) == true, "");
98         static_assert(*opt == Y(), "");
99 
100         struct test_constexpr_ctor
101             : public optional<Y>
102         {
103             constexpr test_constexpr_ctor(in_place_t)
104                 : optional<Y>(in_place) {}
105         };
106 
107     }
108     {
109         constexpr optional<Y> opt(in_place, 5);
110         static_assert(static_cast<bool>(opt) == true, "");
111         static_assert(*opt == Y(5), "");
112 
113         struct test_constexpr_ctor
114             : public optional<Y>
115         {
116             constexpr test_constexpr_ctor(in_place_t, int i)
117                 : optional<Y>(in_place, i) {}
118         };
119 
120     }
121     {
122         constexpr optional<Y> opt(in_place, 5, 4);
123         static_assert(static_cast<bool>(opt) == true, "");
124         static_assert(*opt == Y(5, 4), "");
125 
126         struct test_constexpr_ctor
127             : public optional<Y>
128         {
129             constexpr test_constexpr_ctor(in_place_t, int i, int j)
130                 : optional<Y>(in_place, i, j) {}
131         };
132 
133     }
134 #ifndef TEST_HAS_NO_EXCEPTIONS
135     {
136         try
137         {
138             const optional<Z> opt(in_place, 1);
139             assert(false);
140         }
141         catch (int i)
142         {
143             assert(i == 6);
144         }
145     }
146 #endif
147 
148   return 0;
149 }
150