• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // constexpr optional(const optional<T>& rhs);
13 
14 #include <optional>
15 #include <type_traits>
16 #include <cassert>
17 
18 #include "test_macros.h"
19 #include "archetypes.h"
20 
21 using std::optional;
22 
23 template <class T, class ...InitArgs>
test(InitArgs &&...args)24 void test(InitArgs&&... args)
25 {
26     const optional<T> rhs(std::forward<InitArgs>(args)...);
27     bool rhs_engaged = static_cast<bool>(rhs);
28     optional<T> lhs = rhs;
29     assert(static_cast<bool>(lhs) == rhs_engaged);
30     if (rhs_engaged)
31         assert(*lhs == *rhs);
32 }
33 
34 template <class T, class ...InitArgs>
constexpr_test(InitArgs &&...args)35 constexpr bool constexpr_test(InitArgs&&... args)
36 {
37     static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
38     const optional<T> rhs(std::forward<InitArgs>(args)...);
39     optional<T> lhs = rhs;
40     return (lhs.has_value() == rhs.has_value()) &&
41            (lhs.has_value() ? *lhs == *rhs : true);
42 }
43 
test_throwing_ctor()44 void test_throwing_ctor() {
45 #ifndef TEST_HAS_NO_EXCEPTIONS
46     struct Z {
47         Z() : count(0) {}
48         Z(Z const& o) : count(o.count + 1)
49         { if (count == 2) throw 6; }
50         int count;
51     };
52     const Z z;
53     const optional<Z> rhs(z);
54     try
55     {
56         optional<Z> lhs(rhs);
57         assert(false);
58     }
59     catch (int i)
60     {
61         assert(i == 6);
62     }
63 #endif
64 }
65 
66 template <class T, class ...InitArgs>
test_ref(InitArgs &&...args)67 void test_ref(InitArgs&&... args)
68 {
69     const optional<T> rhs(std::forward<InitArgs>(args)...);
70     bool rhs_engaged = static_cast<bool>(rhs);
71     optional<T> lhs = rhs;
72     assert(static_cast<bool>(lhs) == rhs_engaged);
73     if (rhs_engaged)
74         assert(&(*lhs) == &(*rhs));
75 }
76 
77 
test_reference_extension()78 void test_reference_extension()
79 {
80 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
81     using T = TestTypes::TestType;
82     T::reset();
83     {
84         T t;
85         T::reset_constructors();
86         test_ref<T&>();
87         test_ref<T&>(t);
88         assert(T::alive == 1);
89         assert(T::constructed == 0);
90         assert(T::assigned == 0);
91         assert(T::destroyed == 0);
92     }
93     assert(T::destroyed == 1);
94     assert(T::alive == 0);
95     {
96         T t;
97         const T& ct = t;
98         T::reset_constructors();
99         test_ref<T const&>();
100         test_ref<T const&>(t);
101         test_ref<T const&>(ct);
102         assert(T::alive == 1);
103         assert(T::constructed == 0);
104         assert(T::assigned == 0);
105         assert(T::destroyed == 0);
106     }
107     assert(T::alive == 0);
108     assert(T::destroyed == 1);
109     {
110         static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
111         static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
112     }
113 #endif
114 }
115 
main(int,char **)116 int main(int, char**)
117 {
118     test<int>();
119     test<int>(3);
120     static_assert(constexpr_test<int>(), "" );
121     static_assert(constexpr_test<int>(3), "" );
122 
123     {
124         const optional<const int> o(42);
125         optional<const int> o2(o);
126         assert(*o2 == 42);
127     }
128     {
129         using T = TestTypes::TestType;
130         T::reset();
131         const optional<T> rhs;
132         assert(T::alive == 0);
133         const optional<T> lhs(rhs);
134         assert(lhs.has_value() == false);
135         assert(T::alive == 0);
136     }
137     TestTypes::TestType::reset();
138     {
139         using T = TestTypes::TestType;
140         T::reset();
141         const optional<T> rhs(42);
142         assert(T::alive == 1);
143         assert(T::value_constructed == 1);
144         assert(T::copy_constructed == 0);
145         const optional<T> lhs(rhs);
146         assert(lhs.has_value());
147         assert(T::copy_constructed == 1);
148         assert(T::alive == 2);
149     }
150     TestTypes::TestType::reset();
151     {
152         using namespace ConstexprTestTypes;
153         test<TestType>();
154         test<TestType>(42);
155     }
156     {
157         using namespace TrivialTestTypes;
158         test<TestType>();
159         test<TestType>(42);
160     }
161     {
162         test_throwing_ctor();
163     }
164     {
165         test_reference_extension();
166     }
167     {
168         constexpr std::optional<int> o1{4};
169         constexpr std::optional<int> o2 = o1;
170         static_assert( *o2 == 4, "" );
171     }
172 
173   return 0;
174 }
175