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 // <optional>
11 
12 // template <class U, class... Args>
13 //     constexpr
14 //     explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
15 
16 #include <optional>
17 #include <type_traits>
18 #include <memory>
19 #include <vector>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 
24 using std::optional;
25 using std::in_place_t;
26 using std::in_place;
27 
28 class X
29 {
30     int i_;
31     int j_ = 0;
32 public:
X()33     X() : i_(0) {}
X(int i)34     X(int i) : i_(i) {}
X(int i,int j)35     X(int i, int j) : i_(i), j_(j) {}
36 
~X()37     ~X() {}
38 
operator ==(const X & x,const X & y)39     friend bool operator==(const X& x, const X& y)
40         {return x.i_ == y.i_ && x.j_ == y.j_;}
41 };
42 
43 class Y
44 {
45     int i_;
46     int j_ = 0;
47 public:
Y()48     constexpr Y() : i_(0) {}
Y(int i)49     constexpr Y(int i) : i_(i) {}
Y(std::initializer_list<int> il)50     constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
51 
operator ==(const Y & x,const Y & y)52     friend constexpr bool operator==(const Y& x, const Y& y)
53         {return x.i_ == y.i_ && x.j_ == y.j_;}
54 };
55 
56 class Z
57 {
58     int i_;
59     int j_ = 0;
60 public:
Z()61     Z() : i_(0) {}
Z(int i)62     Z(int i) : i_(i) {}
Z(std::initializer_list<int> il)63     Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
64         {TEST_THROW(6);}
65 
operator ==(const Z & x,const Z & y)66     friend bool operator==(const Z& x, const Z& y)
67         {return x.i_ == y.i_ && x.j_ == y.j_;}
68 };
69 
main(int,char **)70 int main(int, char**)
71 {
72     {
73         static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
74         static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
75     }
76     {
77         optional<std::vector<int>> opt(in_place, {3, 1});
78         assert(static_cast<bool>(opt) == true);
79         assert((*opt == std::vector<int>{3, 1}));
80         assert(opt->size() == 2);
81     }
82     {
83         optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
84         assert(static_cast<bool>(opt) == true);
85         assert((*opt == std::vector<int>{3, 1}));
86         assert(opt->size() == 2);
87     }
88     {
89         static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
90         constexpr optional<Y> opt(in_place, {3, 1});
91         static_assert(static_cast<bool>(opt) == true, "");
92         static_assert(*opt == Y{3, 1}, "");
93 
94         struct test_constexpr_ctor
95             : public optional<Y>
96         {
97             constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i)
98                 : optional<Y>(in_place, i) {}
99         };
100 
101     }
102 #ifndef TEST_HAS_NO_EXCEPTIONS
103     {
104         static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
105         try
106         {
107             optional<Z> opt(in_place, {3, 1});
108             assert(false);
109         }
110         catch (int i)
111         {
112             assert(i == 6);
113         }
114     }
115 #endif
116 
117   return 0;
118 }
119