1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
13 // template <class U> optional<T>& operator=(U&& v);
16 #include <type_traits>
20 #include "test_macros.h"
21 #include "archetypes.hpp"
26 static int dtor_called;
27 ThrowAssign() = default;
28 ThrowAssign(int) { TEST_THROW(42); }
29 ThrowAssign& operator=(int) {
32 ~ThrowAssign() { ++dtor_called; }
34 int ThrowAssign::dtor_called = 0;
36 template <class T, class Arg = T, bool Expect = true>
37 void assert_assignable() {
38 static_assert(std::is_assignable<optional<T>&, Arg>::value == Expect, "");
39 static_assert(!std::is_assignable<const optional<T>&, Arg>::value, "");
43 explicit MismatchType(int) {}
44 explicit MismatchType(char*) {}
45 explicit MismatchType(int*) = delete;
46 MismatchType& operator=(int) { return *this; }
47 MismatchType& operator=(int*) { return *this; }
48 MismatchType& operator=(char*) = delete;
51 struct FromOptionalType {
52 using Opt = std::optional<FromOptionalType>;
53 FromOptionalType() = default;
54 FromOptionalType(FromOptionalType const&) = delete;
55 template <class Dummy = void>
56 constexpr FromOptionalType(Opt&) { Dummy::BARK; }
57 template <class Dummy = void>
58 constexpr FromOptionalType& operator=(Opt&) { Dummy::BARK; return *this; }
62 using I = TestTypes::TestType;
63 using E = ExplicitTestTypes::TestType;
64 assert_assignable<int>();
65 assert_assignable<int, int&>();
66 assert_assignable<int, int const&>();
68 assert_assignable<I, I const&>();
69 assert_assignable<I, I&&>();
70 assert_assignable<I, int>();
71 assert_assignable<I, void*, false>();
73 assert_assignable<E, E const&>();
74 assert_assignable<E, E &&>();
75 assert_assignable<E, int>();
76 assert_assignable<E, void*, false>();
78 assert_assignable<MismatchType, int>();
79 assert_assignable<MismatchType, int*, false>();
80 assert_assignable<MismatchType, char*, false>();
81 // Type constructible from optional
82 assert_assignable<FromOptionalType, std::optional<FromOptionalType>&, false>();
85 void test_with_test_type()
87 using T = TestTypes::TestType;
92 assert(T::alive == 1);
93 assert(T::constructed == 1);
94 assert(T::value_constructed == 1);
95 assert(T::assigned == 0);
96 assert(T::destroyed == 0);
97 assert(static_cast<bool>(opt) == true);
102 T::reset_constructors();
104 assert(T::alive == 1);
105 assert(T::constructed == 0);
106 assert(T::assigned == 1);
107 assert(T::value_assigned == 1);
108 assert(T::destroyed == 0);
109 assert(static_cast<bool>(opt) == true);
110 assert(*opt == T(3));
112 { // test default argument
114 T::reset_constructors();
116 assert(T::alive == 1);
117 assert(T::constructed == 2);
118 assert(T::value_constructed == 1);
119 assert(T::move_constructed == 1);
120 assert(T::assigned == 0);
121 assert(T::destroyed == 1);
122 assert(static_cast<bool>(opt) == true);
123 assert(*opt == T(1, 2));
125 { // test default argument
127 T::reset_constructors();
129 assert(T::alive == 1);
130 assert(T::constructed == 1);
131 assert(T::value_constructed == 1);
132 assert(T::assigned == 1);
133 assert(T::move_assigned == 1);
134 assert(T::destroyed == 1);
135 assert(static_cast<bool>(opt) == true);
136 assert(*opt == T(1, 2));
138 { // test default argument
140 T::reset_constructors();
142 assert(T::alive == 1);
143 assert(T::constructed == 2);
144 assert(T::value_constructed == 1);
145 assert(T::move_constructed == 1);
146 assert(T::assigned == 0);
147 assert(T::destroyed == 1);
148 assert(static_cast<bool>(opt) == true);
149 assert(*opt == T(1));
151 { // test default argument
153 T::reset_constructors();
155 assert(static_cast<bool>(opt) == false);
156 assert(T::alive == 0);
157 assert(T::constructed == 0);
158 assert(T::assigned == 0);
159 assert(T::destroyed == 1);
163 template <class T, class Value = int>
164 void test_with_type() {
168 assert(static_cast<bool>(opt) == true);
169 assert(*opt == T(3));
172 optional<T> opt(Value(42));
174 assert(static_cast<bool>(opt) == true);
175 assert(*opt == T(3));
178 optional<T> opt(Value(42));
181 assert(static_cast<bool>(opt) == true);
182 assert(*opt == T(3));
184 { // test default argument
187 assert(static_cast<bool>(opt) == true);
188 assert(*opt == T(1));
190 { // test default argument
191 optional<T> opt(Value(42));
193 assert(static_cast<bool>(opt) == false);
198 void test_with_type_multi() {
200 { // test default argument
203 assert(static_cast<bool>(opt) == true);
204 assert(*opt == T(1, 2));
206 { // test default argument
209 assert(static_cast<bool>(opt) == true);
210 assert(*opt == T(1, 2));
216 #ifndef TEST_HAS_NO_EXCEPTIONS
217 using T = ThrowAssign;
219 using T = ThrowAssign;
225 assert(static_cast<bool>(opt) == false);
227 assert(T::dtor_called == 0);
230 optional<T> opt(std::in_place);
235 assert(static_cast<bool>(opt) == true);
236 assert(T::dtor_called == 0);
238 assert(T::dtor_called == 1);
242 enum MyEnum { Zero, One, Two, Three, FortyTwo = 42 };
244 using Fn = void(*)();
249 // Test with instrumented type
250 test_with_test_type();
251 // Test with various scalar types
252 test_with_type<int>();
253 test_with_type<MyEnum, MyEnum>();
254 test_with_type<int, MyEnum>();
255 test_with_type<Fn, Fn>();
256 // Test types with multi argument constructors
257 test_with_type_multi<ConstexprTestTypes::TestType>();
258 test_with_type_multi<TrivialTestTypes::TestType>();
259 // Test move only types
261 optional<std::unique_ptr<int>> opt;
262 opt = std::unique_ptr<int>(new int(3));
263 assert(static_cast<bool>(opt) == true);
267 optional<std::unique_ptr<int>> opt(std::unique_ptr<int>(new int(2)));
268 opt = std::unique_ptr<int>(new int(3));
269 assert(static_cast<bool>(opt) == true);