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