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++98, c++03, c++11, c++14
10 
11 // XFAIL: dylib-has-no-bad_optional_access && !no-exceptions
12 
13 // <optional>
14 
15 // constexpr optional(T&& v);
16 
17 #include <optional>
18 #include <type_traits>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 #include "archetypes.h"
23 
24 
25 using std::optional;
26 
27 
28 class Z
29 {
30 public:
31     Z(int) {}
32     Z(Z&&) {TEST_THROW(6);}
33 };
34 
35 
36 int main(int, char**)
37 {
38     {
39         typedef int T;
40         constexpr optional<T> opt(T(5));
41         static_assert(static_cast<bool>(opt) == true, "");
42         static_assert(*opt == 5, "");
43 
44         struct test_constexpr_ctor
45             : public optional<T>
46         {
47             constexpr test_constexpr_ctor(T&&) {}
48         };
49     }
50     {
51         typedef double T;
52         constexpr optional<T> opt(T(3));
53         static_assert(static_cast<bool>(opt) == true, "");
54         static_assert(*opt == 3, "");
55 
56         struct test_constexpr_ctor
57             : public optional<T>
58         {
59             constexpr test_constexpr_ctor(T&&) {}
60         };
61     }
62     {
63         const int x = 42;
64         optional<const int> o(std::move(x));
65         assert(*o == 42);
66     }
67     {
68         typedef TestTypes::TestType T;
69         T::reset();
70         optional<T> opt = T{3};
71         assert(T::alive == 1);
72         assert(T::move_constructed == 1);
73         assert(static_cast<bool>(opt) == true);
74         assert(opt.value().value == 3);
75     }
76     {
77         typedef ExplicitTestTypes::TestType T;
78         static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
79         T::reset();
80         optional<T> opt(T{3});
81         assert(T::alive == 1);
82         assert(T::move_constructed == 1);
83         assert(static_cast<bool>(opt) == true);
84         assert(opt.value().value == 3);
85     }
86     {
87         typedef TestTypes::TestType T;
88         T::reset();
89         optional<T> opt = {3};
90         assert(T::alive == 1);
91         assert(T::value_constructed == 1);
92         assert(T::copy_constructed == 0);
93         assert(T::move_constructed == 0);
94         assert(static_cast<bool>(opt) == true);
95         assert(opt.value().value == 3);
96     }
97     {
98         typedef ConstexprTestTypes::TestType T;
99         constexpr optional<T> opt = {T(3)};
100         static_assert(static_cast<bool>(opt) == true, "");
101         static_assert(opt.value().value == 3, "");
102 
103         struct test_constexpr_ctor
104             : public optional<T>
105         {
106             constexpr test_constexpr_ctor(const T&) {}
107         };
108     }
109     {
110         typedef ConstexprTestTypes::TestType T;
111         constexpr optional<T> opt = {3};
112         static_assert(static_cast<bool>(opt) == true, "");
113         static_assert(opt.value().value == 3, "");
114 
115         struct test_constexpr_ctor
116             : public optional<T>
117         {
118             constexpr test_constexpr_ctor(const T&) {}
119         };
120     }
121     {
122         typedef ExplicitConstexprTestTypes::TestType T;
123         static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
124         constexpr optional<T> opt(T{3});
125         static_assert(static_cast<bool>(opt) == true, "");
126         static_assert(opt.value().value == 3, "");
127 
128         struct test_constexpr_ctor
129             : public optional<T>
130         {
131             constexpr test_constexpr_ctor(T&&) {}
132         };
133 
134     }
135 #ifndef TEST_HAS_NO_EXCEPTIONS
136     {
137         struct Z {
138             Z(int) {}
139             Z(Z&&) {throw 6;}
140         };
141         typedef Z T;
142         try
143         {
144             T t(3);
145             optional<T> opt(std::move(t));
146             assert(false);
147         }
148         catch (int i)
149         {
150             assert(i == 6);
151         }
152     }
153 #endif
154 
155   return 0;
156 }
157