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