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