1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/types/optional.h"
16
17 // This test is a no-op when absl::optional is an alias for std::optional.
18 #if !defined(ABSL_USES_STD_OPTIONAL)
19
20 #include <string>
21 #include <type_traits>
22 #include <utility>
23
24 #include "gtest/gtest.h"
25 #include "absl/base/config.h"
26 #include "absl/base/internal/raw_logging.h"
27 #include "absl/meta/type_traits.h"
28 #include "absl/strings/string_view.h"
29
30 struct Hashable {};
31
32 namespace std {
33 template <>
34 struct hash<Hashable> {
operator ()std::hash35 size_t operator()(const Hashable&) { return 0; }
36 };
37 } // namespace std
38
39 struct NonHashable {};
40
41 namespace {
42
TypeQuals(std::string &)43 std::string TypeQuals(std::string&) { return "&"; }
TypeQuals(std::string &&)44 std::string TypeQuals(std::string&&) { return "&&"; }
TypeQuals(const std::string &)45 std::string TypeQuals(const std::string&) { return "c&"; }
TypeQuals(const std::string &&)46 std::string TypeQuals(const std::string&&) { return "c&&"; }
47
48 struct StructorListener {
49 int construct0 = 0;
50 int construct1 = 0;
51 int construct2 = 0;
52 int listinit = 0;
53 int copy = 0;
54 int move = 0;
55 int copy_assign = 0;
56 int move_assign = 0;
57 int destruct = 0;
58 int volatile_copy = 0;
59 int volatile_move = 0;
60 int volatile_copy_assign = 0;
61 int volatile_move_assign = 0;
62 };
63
64 // Suppress MSVC warnings.
65 // 4521: multiple copy constructors specified
66 // 4522: multiple assignment operators specified
67 // We wrote multiple of them to test that the correct overloads are selected.
68 #ifdef _MSC_VER
69 #pragma warning( push )
70 #pragma warning( disable : 4521)
71 #pragma warning( disable : 4522)
72 #endif
73 struct Listenable {
74 static StructorListener* listener;
75
Listenable__anon65d666410111::Listenable76 Listenable() { ++listener->construct0; }
Listenable__anon65d666410111::Listenable77 explicit Listenable(int /*unused*/) { ++listener->construct1; }
Listenable__anon65d666410111::Listenable78 Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }
Listenable__anon65d666410111::Listenable79 Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }
Listenable__anon65d666410111::Listenable80 Listenable(const Listenable& /*unused*/) { ++listener->copy; }
Listenable__anon65d666410111::Listenable81 Listenable(const volatile Listenable& /*unused*/) {
82 ++listener->volatile_copy;
83 }
Listenable__anon65d666410111::Listenable84 Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; }
Listenable__anon65d666410111::Listenable85 Listenable(Listenable&& /*unused*/) { ++listener->move; }
operator =__anon65d666410111::Listenable86 Listenable& operator=(const Listenable& /*unused*/) {
87 ++listener->copy_assign;
88 return *this;
89 }
operator =__anon65d666410111::Listenable90 Listenable& operator=(Listenable&& /*unused*/) {
91 ++listener->move_assign;
92 return *this;
93 }
94 // use void return type instead of volatile T& to work around GCC warning
95 // when the assignment's returned reference is ignored.
operator =__anon65d666410111::Listenable96 void operator=(const volatile Listenable& /*unused*/) volatile {
97 ++listener->volatile_copy_assign;
98 }
operator =__anon65d666410111::Listenable99 void operator=(volatile Listenable&& /*unused*/) volatile {
100 ++listener->volatile_move_assign;
101 }
~Listenable__anon65d666410111::Listenable102 ~Listenable() { ++listener->destruct; }
103 };
104 #ifdef _MSC_VER
105 #pragma warning( pop )
106 #endif
107
108 StructorListener* Listenable::listener = nullptr;
109
110 // ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST is defined to 1 when the standard
111 // library implementation doesn't marked initializer_list's default constructor
112 // constexpr. The C++11 standard doesn't specify constexpr on it, but C++14
113 // added it. However, libstdc++ 4.7 marked it constexpr.
114 #if defined(_LIBCPP_VERSION) && \
115 (_LIBCPP_STD_VER <= 11 || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR))
116 #define ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST 1
117 #endif
118
119 struct ConstexprType {
120 enum CtorTypes {
121 kCtorDefault,
122 kCtorInt,
123 kCtorInitializerList,
124 kCtorConstChar
125 };
ConstexprType__anon65d666410111::ConstexprType126 constexpr ConstexprType() : x(kCtorDefault) {}
ConstexprType__anon65d666410111::ConstexprType127 constexpr explicit ConstexprType(int i) : x(kCtorInt) {}
128 #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
ConstexprType__anon65d666410111::ConstexprType129 constexpr ConstexprType(std::initializer_list<int> il)
130 : x(kCtorInitializerList) {}
131 #endif
ConstexprType__anon65d666410111::ConstexprType132 constexpr ConstexprType(const char*) // NOLINT(runtime/explicit)
133 : x(kCtorConstChar) {}
134 int x;
135 };
136
137 struct Copyable {
Copyable__anon65d666410111::Copyable138 Copyable() {}
Copyable__anon65d666410111::Copyable139 Copyable(const Copyable&) {}
operator =__anon65d666410111::Copyable140 Copyable& operator=(const Copyable&) { return *this; }
141 };
142
143 struct MoveableThrow {
MoveableThrow__anon65d666410111::MoveableThrow144 MoveableThrow() {}
MoveableThrow__anon65d666410111::MoveableThrow145 MoveableThrow(MoveableThrow&&) {}
operator =__anon65d666410111::MoveableThrow146 MoveableThrow& operator=(MoveableThrow&&) { return *this; }
147 };
148
149 struct MoveableNoThrow {
MoveableNoThrow__anon65d666410111::MoveableNoThrow150 MoveableNoThrow() {}
MoveableNoThrow__anon65d666410111::MoveableNoThrow151 MoveableNoThrow(MoveableNoThrow&&) noexcept {}
operator =__anon65d666410111::MoveableNoThrow152 MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }
153 };
154
155 struct NonMovable {
NonMovable__anon65d666410111::NonMovable156 NonMovable() {}
157 NonMovable(const NonMovable&) = delete;
158 NonMovable& operator=(const NonMovable&) = delete;
159 NonMovable(NonMovable&&) = delete;
160 NonMovable& operator=(NonMovable&&) = delete;
161 };
162
163 struct NoDefault {
164 NoDefault() = delete;
NoDefault__anon65d666410111::NoDefault165 NoDefault(const NoDefault&) {}
operator =__anon65d666410111::NoDefault166 NoDefault& operator=(const NoDefault&) { return *this; }
167 };
168
169 struct ConvertsFromInPlaceT {
ConvertsFromInPlaceT__anon65d666410111::ConvertsFromInPlaceT170 ConvertsFromInPlaceT(absl::in_place_t) {} // NOLINT
171 };
172
TEST(optionalTest,DefaultConstructor)173 TEST(optionalTest, DefaultConstructor) {
174 absl::optional<int> empty;
175 EXPECT_FALSE(empty);
176 constexpr absl::optional<int> cempty;
177 static_assert(!cempty.has_value(), "");
178 EXPECT_TRUE(
179 std::is_nothrow_default_constructible<absl::optional<int>>::value);
180 }
181
TEST(optionalTest,nulloptConstructor)182 TEST(optionalTest, nulloptConstructor) {
183 absl::optional<int> empty(absl::nullopt);
184 EXPECT_FALSE(empty);
185 constexpr absl::optional<int> cempty{absl::nullopt};
186 static_assert(!cempty.has_value(), "");
187 EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>,
188 absl::nullopt_t>::value));
189 }
190
TEST(optionalTest,CopyConstructor)191 TEST(optionalTest, CopyConstructor) {
192 {
193 absl::optional<int> empty, opt42 = 42;
194 absl::optional<int> empty_copy(empty);
195 EXPECT_FALSE(empty_copy);
196 absl::optional<int> opt42_copy(opt42);
197 EXPECT_TRUE(opt42_copy);
198 EXPECT_EQ(42, *opt42_copy);
199 }
200 {
201 absl::optional<const int> empty, opt42 = 42;
202 absl::optional<const int> empty_copy(empty);
203 EXPECT_FALSE(empty_copy);
204 absl::optional<const int> opt42_copy(opt42);
205 EXPECT_TRUE(opt42_copy);
206 EXPECT_EQ(42, *opt42_copy);
207 }
208 {
209 absl::optional<volatile int> empty, opt42 = 42;
210 absl::optional<volatile int> empty_copy(empty);
211 EXPECT_FALSE(empty_copy);
212 absl::optional<volatile int> opt42_copy(opt42);
213 EXPECT_TRUE(opt42_copy);
214 EXPECT_EQ(42, *opt42_copy);
215 }
216 // test copyablility
217 EXPECT_TRUE(std::is_copy_constructible<absl::optional<int>>::value);
218 EXPECT_TRUE(std::is_copy_constructible<absl::optional<Copyable>>::value);
219 EXPECT_FALSE(
220 std::is_copy_constructible<absl::optional<MoveableThrow>>::value);
221 EXPECT_FALSE(
222 std::is_copy_constructible<absl::optional<MoveableNoThrow>>::value);
223 EXPECT_FALSE(std::is_copy_constructible<absl::optional<NonMovable>>::value);
224
225 EXPECT_FALSE(
226 absl::is_trivially_copy_constructible<absl::optional<Copyable>>::value);
227 #if defined(ABSL_USES_STD_OPTIONAL) && defined(__GLIBCXX__)
228 // libstdc++ std::optional implementation (as of 7.2) has a bug: when T is
229 // trivially copyable, optional<T> is not trivially copyable (due to one of
230 // its base class is unconditionally nontrivial).
231 #define ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG 1
232 #endif
233 #ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
234 EXPECT_TRUE(
235 absl::is_trivially_copy_constructible<absl::optional<int>>::value);
236 EXPECT_TRUE(
237 absl::is_trivially_copy_constructible<absl::optional<const int>>::value);
238 #ifndef _MSC_VER
239 // See defect report "Trivial copy/move constructor for class with volatile
240 // member" at
241 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094
242 // A class with non-static data member of volatile-qualified type should still
243 // have a trivial copy constructor if the data member is trivial.
244 // Also a cv-qualified scalar type should be trivially copyable.
245 EXPECT_TRUE(absl::is_trivially_copy_constructible<
246 absl::optional<volatile int>>::value);
247 #endif // _MSC_VER
248 #endif // ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
249
250 // constexpr copy constructor for trivially copyable types
251 {
252 constexpr absl::optional<int> o1;
253 constexpr absl::optional<int> o2 = o1;
254 static_assert(!o2, "");
255 }
256 {
257 constexpr absl::optional<int> o1 = 42;
258 constexpr absl::optional<int> o2 = o1;
259 static_assert(o2, "");
260 static_assert(*o2 == 42, "");
261 }
262 {
263 struct TrivialCopyable {
264 constexpr TrivialCopyable() : x(0) {}
265 constexpr explicit TrivialCopyable(int i) : x(i) {}
266 int x;
267 };
268 constexpr absl::optional<TrivialCopyable> o1(42);
269 constexpr absl::optional<TrivialCopyable> o2 = o1;
270 static_assert(o2, "");
271 static_assert((*o2).x == 42, "");
272 #ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
273 EXPECT_TRUE(absl::is_trivially_copy_constructible<
274 absl::optional<TrivialCopyable>>::value);
275 EXPECT_TRUE(absl::is_trivially_copy_constructible<
276 absl::optional<const TrivialCopyable>>::value);
277 #endif
278 // When testing with VS 2017 15.3, there seems to be a bug in MSVC
279 // std::optional when T is volatile-qualified. So skipping this test.
280 // Bug report:
281 // https://connect.microsoft.com/VisualStudio/feedback/details/3142534
282 #if defined(ABSL_USES_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911
283 #define ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG 1
284 #endif
285 #ifndef ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG
286 EXPECT_FALSE(std::is_copy_constructible<
287 absl::optional<volatile TrivialCopyable>>::value);
288 #endif
289 }
290 }
291
TEST(optionalTest,MoveConstructor)292 TEST(optionalTest, MoveConstructor) {
293 absl::optional<int> empty, opt42 = 42;
294 absl::optional<int> empty_move(std::move(empty));
295 EXPECT_FALSE(empty_move);
296 absl::optional<int> opt42_move(std::move(opt42));
297 EXPECT_TRUE(opt42_move);
298 EXPECT_EQ(42, opt42_move);
299 // test movability
300 EXPECT_TRUE(std::is_move_constructible<absl::optional<int>>::value);
301 EXPECT_TRUE(std::is_move_constructible<absl::optional<Copyable>>::value);
302 EXPECT_TRUE(std::is_move_constructible<absl::optional<MoveableThrow>>::value);
303 EXPECT_TRUE(
304 std::is_move_constructible<absl::optional<MoveableNoThrow>>::value);
305 EXPECT_FALSE(std::is_move_constructible<absl::optional<NonMovable>>::value);
306 // test noexcept
307 EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value);
308 #ifndef ABSL_USES_STD_OPTIONAL
309 EXPECT_EQ(
310 absl::default_allocator_is_nothrow::value,
311 std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value);
312 #endif
313 EXPECT_TRUE(std::is_nothrow_move_constructible<
314 absl::optional<MoveableNoThrow>>::value);
315 }
316
TEST(optionalTest,Destructor)317 TEST(optionalTest, Destructor) {
318 struct Trivial {};
319
320 struct NonTrivial {
321 NonTrivial(const NonTrivial&) {}
322 NonTrivial& operator=(const NonTrivial&) { return *this; }
323 ~NonTrivial() {}
324 };
325
326 EXPECT_TRUE(std::is_trivially_destructible<absl::optional<int>>::value);
327 EXPECT_TRUE(std::is_trivially_destructible<absl::optional<Trivial>>::value);
328 EXPECT_FALSE(
329 std::is_trivially_destructible<absl::optional<NonTrivial>>::value);
330 }
331
TEST(optionalTest,InPlaceConstructor)332 TEST(optionalTest, InPlaceConstructor) {
333 constexpr absl::optional<ConstexprType> opt0{absl::in_place_t()};
334 static_assert(opt0, "");
335 static_assert((*opt0).x == ConstexprType::kCtorDefault, "");
336 constexpr absl::optional<ConstexprType> opt1{absl::in_place_t(), 1};
337 static_assert(opt1, "");
338 static_assert((*opt1).x == ConstexprType::kCtorInt, "");
339 #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
340 constexpr absl::optional<ConstexprType> opt2{absl::in_place_t(), {1, 2}};
341 static_assert(opt2, "");
342 static_assert((*opt2).x == ConstexprType::kCtorInitializerList, "");
343 #endif
344
345 EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
346 absl::in_place_t>::value));
347 EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
348 const absl::in_place_t&>::value));
349 EXPECT_TRUE(
350 (std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
351 absl::in_place_t, absl::in_place_t>::value));
352
353 EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
354 absl::in_place_t>::value));
355 EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
356 absl::in_place_t&&>::value));
357 }
358
359 // template<U=T> optional(U&&);
TEST(optionalTest,ValueConstructor)360 TEST(optionalTest, ValueConstructor) {
361 constexpr absl::optional<int> opt0(0);
362 static_assert(opt0, "");
363 static_assert(*opt0 == 0, "");
364 EXPECT_TRUE((std::is_convertible<int, absl::optional<int>>::value));
365 // Copy initialization ( = "abc") won't work due to optional(optional&&)
366 // is not constexpr. Use list initialization instead. This invokes
367 // absl::optional<ConstexprType>::absl::optional<U>(U&&), with U = const char
368 // (&) [4], which direct-initializes the ConstexprType value held by the
369 // optional via ConstexprType::ConstexprType(const char*).
370 constexpr absl::optional<ConstexprType> opt1 = {"abc"};
371 static_assert(opt1, "");
372 static_assert(ConstexprType::kCtorConstChar == (*opt1).x, "");
373 EXPECT_TRUE(
374 (std::is_convertible<const char*, absl::optional<ConstexprType>>::value));
375 // direct initialization
376 constexpr absl::optional<ConstexprType> opt2{2};
377 static_assert(opt2, "");
378 static_assert(ConstexprType::kCtorInt == (*opt2).x, "");
379 EXPECT_FALSE(
380 (std::is_convertible<int, absl::optional<ConstexprType>>::value));
381
382 // this invokes absl::optional<int>::optional(int&&)
383 // NOTE: this has different behavior than assignment, e.g.
384 // "opt3 = {};" clears the optional rather than setting the value to 0
385 // According to C++17 standard N4659 [over.ics.list] 16.3.3.1.5, (9.2)- "if
386 // the initializer list has no elements, the implicit conversion is the
387 // identity conversion", so `optional(int&&)` should be a better match than
388 // `optional(optional&&)` which is a user-defined conversion.
389 // Note: GCC 7 has a bug with this overload selection when compiled with
390 // `-std=c++17`.
391 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7 && \
392 __cplusplus == 201703L
393 #define ABSL_GCC7_OVER_ICS_LIST_BUG 1
394 #endif
395 #ifndef ABSL_GCC7_OVER_ICS_LIST_BUG
396 constexpr absl::optional<int> opt3({});
397 static_assert(opt3, "");
398 static_assert(*opt3 == 0, "");
399 #endif
400
401 // this invokes the move constructor with a default constructed optional
402 // because non-template function is a better match than template function.
403 absl::optional<ConstexprType> opt4({});
404 EXPECT_FALSE(opt4);
405 }
406
407 struct Implicit {};
408
409 struct Explicit {};
410
411 struct Convert {
Convert__anon65d666410111::Convert412 Convert(const Implicit&) // NOLINT(runtime/explicit)
413 : implicit(true), move(false) {}
Convert__anon65d666410111::Convert414 Convert(Implicit&&) // NOLINT(runtime/explicit)
415 : implicit(true), move(true) {}
Convert__anon65d666410111::Convert416 explicit Convert(const Explicit&) : implicit(false), move(false) {}
Convert__anon65d666410111::Convert417 explicit Convert(Explicit&&) : implicit(false), move(true) {}
418
419 bool implicit;
420 bool move;
421 };
422
423 struct ConvertFromOptional {
ConvertFromOptional__anon65d666410111::ConvertFromOptional424 ConvertFromOptional(const Implicit&) // NOLINT(runtime/explicit)
425 : implicit(true), move(false), from_optional(false) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional426 ConvertFromOptional(Implicit&&) // NOLINT(runtime/explicit)
427 : implicit(true), move(true), from_optional(false) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional428 ConvertFromOptional(
429 const absl::optional<Implicit>&) // NOLINT(runtime/explicit)
430 : implicit(true), move(false), from_optional(true) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional431 ConvertFromOptional(absl::optional<Implicit>&&) // NOLINT(runtime/explicit)
432 : implicit(true), move(true), from_optional(true) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional433 explicit ConvertFromOptional(const Explicit&)
434 : implicit(false), move(false), from_optional(false) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional435 explicit ConvertFromOptional(Explicit&&)
436 : implicit(false), move(true), from_optional(false) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional437 explicit ConvertFromOptional(const absl::optional<Explicit>&)
438 : implicit(false), move(false), from_optional(true) {}
ConvertFromOptional__anon65d666410111::ConvertFromOptional439 explicit ConvertFromOptional(absl::optional<Explicit>&&)
440 : implicit(false), move(true), from_optional(true) {}
441
442 bool implicit;
443 bool move;
444 bool from_optional;
445 };
446
TEST(optionalTest,ConvertingConstructor)447 TEST(optionalTest, ConvertingConstructor) {
448 absl::optional<Implicit> i_empty;
449 absl::optional<Implicit> i(absl::in_place);
450 absl::optional<Explicit> e_empty;
451 absl::optional<Explicit> e(absl::in_place);
452 {
453 // implicitly constructing absl::optional<Convert> from
454 // absl::optional<Implicit>
455 absl::optional<Convert> empty = i_empty;
456 EXPECT_FALSE(empty);
457 absl::optional<Convert> opt_copy = i;
458 EXPECT_TRUE(opt_copy);
459 EXPECT_TRUE(opt_copy->implicit);
460 EXPECT_FALSE(opt_copy->move);
461 absl::optional<Convert> opt_move = absl::optional<Implicit>(absl::in_place);
462 EXPECT_TRUE(opt_move);
463 EXPECT_TRUE(opt_move->implicit);
464 EXPECT_TRUE(opt_move->move);
465 }
466 {
467 // explicitly constructing absl::optional<Convert> from
468 // absl::optional<Explicit>
469 absl::optional<Convert> empty(e_empty);
470 EXPECT_FALSE(empty);
471 absl::optional<Convert> opt_copy(e);
472 EXPECT_TRUE(opt_copy);
473 EXPECT_FALSE(opt_copy->implicit);
474 EXPECT_FALSE(opt_copy->move);
475 EXPECT_FALSE((std::is_convertible<const absl::optional<Explicit>&,
476 absl::optional<Convert>>::value));
477 absl::optional<Convert> opt_move{absl::optional<Explicit>(absl::in_place)};
478 EXPECT_TRUE(opt_move);
479 EXPECT_FALSE(opt_move->implicit);
480 EXPECT_TRUE(opt_move->move);
481 EXPECT_FALSE((std::is_convertible<absl::optional<Explicit>&&,
482 absl::optional<Convert>>::value));
483 }
484 {
485 // implicitly constructing absl::optional<ConvertFromOptional> from
486 // absl::optional<Implicit> via
487 // ConvertFromOptional(absl::optional<Implicit>&&) check that
488 // ConvertFromOptional(Implicit&&) is NOT called
489 static_assert(
490 std::is_convertible<absl::optional<Implicit>,
491 absl::optional<ConvertFromOptional>>::value,
492 "");
493 absl::optional<ConvertFromOptional> opt0 = i_empty;
494 EXPECT_TRUE(opt0);
495 EXPECT_TRUE(opt0->implicit);
496 EXPECT_FALSE(opt0->move);
497 EXPECT_TRUE(opt0->from_optional);
498 absl::optional<ConvertFromOptional> opt1 = absl::optional<Implicit>();
499 EXPECT_TRUE(opt1);
500 EXPECT_TRUE(opt1->implicit);
501 EXPECT_TRUE(opt1->move);
502 EXPECT_TRUE(opt1->from_optional);
503 }
504 {
505 // implicitly constructing absl::optional<ConvertFromOptional> from
506 // absl::optional<Explicit> via
507 // ConvertFromOptional(absl::optional<Explicit>&&) check that
508 // ConvertFromOptional(Explicit&&) is NOT called
509 absl::optional<ConvertFromOptional> opt0(e_empty);
510 EXPECT_TRUE(opt0);
511 EXPECT_FALSE(opt0->implicit);
512 EXPECT_FALSE(opt0->move);
513 EXPECT_TRUE(opt0->from_optional);
514 EXPECT_FALSE(
515 (std::is_convertible<const absl::optional<Explicit>&,
516 absl::optional<ConvertFromOptional>>::value));
517 absl::optional<ConvertFromOptional> opt1{absl::optional<Explicit>()};
518 EXPECT_TRUE(opt1);
519 EXPECT_FALSE(opt1->implicit);
520 EXPECT_TRUE(opt1->move);
521 EXPECT_TRUE(opt1->from_optional);
522 EXPECT_FALSE(
523 (std::is_convertible<absl::optional<Explicit>&&,
524 absl::optional<ConvertFromOptional>>::value));
525 }
526 }
527
TEST(optionalTest,StructorBasic)528 TEST(optionalTest, StructorBasic) {
529 StructorListener listener;
530 Listenable::listener = &listener;
531 {
532 absl::optional<Listenable> empty;
533 EXPECT_FALSE(empty);
534 absl::optional<Listenable> opt0(absl::in_place);
535 EXPECT_TRUE(opt0);
536 absl::optional<Listenable> opt1(absl::in_place, 1);
537 EXPECT_TRUE(opt1);
538 absl::optional<Listenable> opt2(absl::in_place, 1, 2);
539 EXPECT_TRUE(opt2);
540 }
541 EXPECT_EQ(1, listener.construct0);
542 EXPECT_EQ(1, listener.construct1);
543 EXPECT_EQ(1, listener.construct2);
544 EXPECT_EQ(3, listener.destruct);
545 }
546
TEST(optionalTest,CopyMoveStructor)547 TEST(optionalTest, CopyMoveStructor) {
548 StructorListener listener;
549 Listenable::listener = &listener;
550 absl::optional<Listenable> original(absl::in_place);
551 EXPECT_EQ(1, listener.construct0);
552 EXPECT_EQ(0, listener.copy);
553 EXPECT_EQ(0, listener.move);
554 absl::optional<Listenable> copy(original);
555 EXPECT_EQ(1, listener.construct0);
556 EXPECT_EQ(1, listener.copy);
557 EXPECT_EQ(0, listener.move);
558 absl::optional<Listenable> move(std::move(original));
559 EXPECT_EQ(1, listener.construct0);
560 EXPECT_EQ(1, listener.copy);
561 EXPECT_EQ(1, listener.move);
562 }
563
TEST(optionalTest,ListInit)564 TEST(optionalTest, ListInit) {
565 StructorListener listener;
566 Listenable::listener = &listener;
567 absl::optional<Listenable> listinit1(absl::in_place, {1});
568 absl::optional<Listenable> listinit2(absl::in_place, {1, 2});
569 EXPECT_EQ(2, listener.listinit);
570 }
571
TEST(optionalTest,AssignFromNullopt)572 TEST(optionalTest, AssignFromNullopt) {
573 absl::optional<int> opt(1);
574 opt = absl::nullopt;
575 EXPECT_FALSE(opt);
576
577 StructorListener listener;
578 Listenable::listener = &listener;
579 absl::optional<Listenable> opt1(absl::in_place);
580 opt1 = absl::nullopt;
581 EXPECT_FALSE(opt1);
582 EXPECT_EQ(1, listener.construct0);
583 EXPECT_EQ(1, listener.destruct);
584
585 EXPECT_TRUE((
586 std::is_nothrow_assignable<absl::optional<int>, absl::nullopt_t>::value));
587 EXPECT_TRUE((std::is_nothrow_assignable<absl::optional<Listenable>,
588 absl::nullopt_t>::value));
589 }
590
TEST(optionalTest,CopyAssignment)591 TEST(optionalTest, CopyAssignment) {
592 const absl::optional<int> empty, opt1 = 1, opt2 = 2;
593 absl::optional<int> empty_to_opt1, opt1_to_opt2, opt2_to_empty;
594
595 EXPECT_FALSE(empty_to_opt1);
596 empty_to_opt1 = empty;
597 EXPECT_FALSE(empty_to_opt1);
598 empty_to_opt1 = opt1;
599 EXPECT_TRUE(empty_to_opt1);
600 EXPECT_EQ(1, empty_to_opt1.value());
601
602 EXPECT_FALSE(opt1_to_opt2);
603 opt1_to_opt2 = opt1;
604 EXPECT_TRUE(opt1_to_opt2);
605 EXPECT_EQ(1, opt1_to_opt2.value());
606 opt1_to_opt2 = opt2;
607 EXPECT_TRUE(opt1_to_opt2);
608 EXPECT_EQ(2, opt1_to_opt2.value());
609
610 EXPECT_FALSE(opt2_to_empty);
611 opt2_to_empty = opt2;
612 EXPECT_TRUE(opt2_to_empty);
613 EXPECT_EQ(2, opt2_to_empty.value());
614 opt2_to_empty = empty;
615 EXPECT_FALSE(opt2_to_empty);
616
617 EXPECT_FALSE(absl::is_copy_assignable<absl::optional<const int>>::value);
618 EXPECT_TRUE(absl::is_copy_assignable<absl::optional<Copyable>>::value);
619 EXPECT_FALSE(absl::is_copy_assignable<absl::optional<MoveableThrow>>::value);
620 EXPECT_FALSE(
621 absl::is_copy_assignable<absl::optional<MoveableNoThrow>>::value);
622 EXPECT_FALSE(absl::is_copy_assignable<absl::optional<NonMovable>>::value);
623
624 EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value);
625 EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value);
626
627 struct Trivial {
628 int i;
629 };
630 struct NonTrivial {
631 NonTrivial& operator=(const NonTrivial&) { return *this; }
632 int i;
633 };
634
635 EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
636 EXPECT_FALSE(absl::is_copy_assignable<const Trivial>::value);
637 EXPECT_FALSE(absl::is_copy_assignable<volatile Trivial>::value);
638 EXPECT_TRUE(absl::is_copy_assignable<NonTrivial>::value);
639 EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value);
640
641 // std::optional doesn't support volatile nontrivial types.
642 #ifndef ABSL_USES_STD_OPTIONAL
643 {
644 StructorListener listener;
645 Listenable::listener = &listener;
646
647 absl::optional<volatile Listenable> empty, set(absl::in_place);
648 EXPECT_EQ(1, listener.construct0);
649 absl::optional<volatile Listenable> empty_to_empty, empty_to_set,
650 set_to_empty(absl::in_place), set_to_set(absl::in_place);
651 EXPECT_EQ(3, listener.construct0);
652 empty_to_empty = empty; // no effect
653 empty_to_set = set; // copy construct
654 set_to_empty = empty; // destruct
655 set_to_set = set; // copy assign
656 EXPECT_EQ(1, listener.volatile_copy);
657 EXPECT_EQ(0, listener.volatile_move);
658 EXPECT_EQ(1, listener.destruct);
659 EXPECT_EQ(1, listener.volatile_copy_assign);
660 }
661 #endif // ABSL_USES_STD_OPTIONAL
662 }
663
TEST(optionalTest,MoveAssignment)664 TEST(optionalTest, MoveAssignment) {
665 {
666 StructorListener listener;
667 Listenable::listener = &listener;
668
669 absl::optional<Listenable> empty1, empty2, set1(absl::in_place),
670 set2(absl::in_place);
671 EXPECT_EQ(2, listener.construct0);
672 absl::optional<Listenable> empty_to_empty, empty_to_set,
673 set_to_empty(absl::in_place), set_to_set(absl::in_place);
674 EXPECT_EQ(4, listener.construct0);
675 empty_to_empty = std::move(empty1);
676 empty_to_set = std::move(set1);
677 set_to_empty = std::move(empty2);
678 set_to_set = std::move(set2);
679 EXPECT_EQ(0, listener.copy);
680 EXPECT_EQ(1, listener.move);
681 EXPECT_EQ(1, listener.destruct);
682 EXPECT_EQ(1, listener.move_assign);
683 }
684 // std::optional doesn't support volatile nontrivial types.
685 #ifndef ABSL_USES_STD_OPTIONAL
686 {
687 StructorListener listener;
688 Listenable::listener = &listener;
689
690 absl::optional<volatile Listenable> empty1, empty2, set1(absl::in_place),
691 set2(absl::in_place);
692 EXPECT_EQ(2, listener.construct0);
693 absl::optional<volatile Listenable> empty_to_empty, empty_to_set,
694 set_to_empty(absl::in_place), set_to_set(absl::in_place);
695 EXPECT_EQ(4, listener.construct0);
696 empty_to_empty = std::move(empty1); // no effect
697 empty_to_set = std::move(set1); // move construct
698 set_to_empty = std::move(empty2); // destruct
699 set_to_set = std::move(set2); // move assign
700 EXPECT_EQ(0, listener.volatile_copy);
701 EXPECT_EQ(1, listener.volatile_move);
702 EXPECT_EQ(1, listener.destruct);
703 EXPECT_EQ(1, listener.volatile_move_assign);
704 }
705 #endif // ABSL_USES_STD_OPTIONAL
706 EXPECT_FALSE(absl::is_move_assignable<absl::optional<const int>>::value);
707 EXPECT_TRUE(absl::is_move_assignable<absl::optional<Copyable>>::value);
708 EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableThrow>>::value);
709 EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableNoThrow>>::value);
710 EXPECT_FALSE(absl::is_move_assignable<absl::optional<NonMovable>>::value);
711
712 EXPECT_FALSE(
713 std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value);
714 EXPECT_TRUE(
715 std::is_nothrow_move_assignable<absl::optional<MoveableNoThrow>>::value);
716 }
717
718 struct NoConvertToOptional {
719 // disable implicit conversion from const NoConvertToOptional&
720 // to absl::optional<NoConvertToOptional>.
721 NoConvertToOptional(const NoConvertToOptional&) = delete;
722 };
723
724 struct CopyConvert {
725 CopyConvert(const NoConvertToOptional&);
726 CopyConvert& operator=(const CopyConvert&) = delete;
727 CopyConvert& operator=(const NoConvertToOptional&);
728 };
729
730 struct CopyConvertFromOptional {
731 CopyConvertFromOptional(const NoConvertToOptional&);
732 CopyConvertFromOptional(const absl::optional<NoConvertToOptional>&);
733 CopyConvertFromOptional& operator=(const CopyConvertFromOptional&) = delete;
734 CopyConvertFromOptional& operator=(const NoConvertToOptional&);
735 CopyConvertFromOptional& operator=(
736 const absl::optional<NoConvertToOptional>&);
737 };
738
739 struct MoveConvert {
740 MoveConvert(NoConvertToOptional&&);
741 MoveConvert& operator=(const MoveConvert&) = delete;
742 MoveConvert& operator=(NoConvertToOptional&&);
743 };
744
745 struct MoveConvertFromOptional {
746 MoveConvertFromOptional(NoConvertToOptional&&);
747 MoveConvertFromOptional(absl::optional<NoConvertToOptional>&&);
748 MoveConvertFromOptional& operator=(const MoveConvertFromOptional&) = delete;
749 MoveConvertFromOptional& operator=(NoConvertToOptional&&);
750 MoveConvertFromOptional& operator=(absl::optional<NoConvertToOptional>&&);
751 };
752
753 // template <typename U = T> absl::optional<T>& operator=(U&& v);
TEST(optionalTest,ValueAssignment)754 TEST(optionalTest, ValueAssignment) {
755 absl::optional<int> opt;
756 EXPECT_FALSE(opt);
757 opt = 42;
758 EXPECT_TRUE(opt);
759 EXPECT_EQ(42, opt.value());
760 opt = absl::nullopt;
761 EXPECT_FALSE(opt);
762 opt = 42;
763 EXPECT_TRUE(opt);
764 EXPECT_EQ(42, opt.value());
765 opt = 43;
766 EXPECT_TRUE(opt);
767 EXPECT_EQ(43, opt.value());
768 opt = {}; // this should clear optional
769 EXPECT_FALSE(opt);
770
771 opt = {44};
772 EXPECT_TRUE(opt);
773 EXPECT_EQ(44, opt.value());
774
775 // U = const NoConvertToOptional&
776 EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvert>&,
777 const NoConvertToOptional&>::value));
778 // U = const absl::optional<NoConvertToOptional>&
779 EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvertFromOptional>&,
780 const NoConvertToOptional&>::value));
781 // U = const NoConvertToOptional& triggers SFINAE because
782 // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
783 EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvert>&,
784 const NoConvertToOptional&>::value));
785 // U = NoConvertToOptional
786 EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvert>&,
787 NoConvertToOptional&&>::value));
788 // U = const NoConvertToOptional& triggers SFINAE because
789 // std::is_constructible_v<MoveConvertFromOptional, const
790 // NoConvertToOptional&> is false
791 EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,
792 const NoConvertToOptional&>::value));
793 // U = NoConvertToOptional
794 EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,
795 NoConvertToOptional&&>::value));
796 // U = const absl::optional<NoConvertToOptional>&
797 EXPECT_TRUE(
798 (std::is_assignable<absl::optional<CopyConvertFromOptional>&,
799 const absl::optional<NoConvertToOptional>&>::value));
800 // U = absl::optional<NoConvertToOptional>
801 EXPECT_TRUE(
802 (std::is_assignable<absl::optional<MoveConvertFromOptional>&,
803 absl::optional<NoConvertToOptional>&&>::value));
804 }
805
806 // template <typename U> absl::optional<T>& operator=(const absl::optional<U>&
807 // rhs); template <typename U> absl::optional<T>& operator=(absl::optional<U>&&
808 // rhs);
TEST(optionalTest,ConvertingAssignment)809 TEST(optionalTest, ConvertingAssignment) {
810 absl::optional<int> opt_i;
811 absl::optional<char> opt_c('c');
812 opt_i = opt_c;
813 EXPECT_TRUE(opt_i);
814 EXPECT_EQ(*opt_c, *opt_i);
815 opt_i = absl::optional<char>();
816 EXPECT_FALSE(opt_i);
817 opt_i = absl::optional<char>('d');
818 EXPECT_TRUE(opt_i);
819 EXPECT_EQ('d', *opt_i);
820
821 absl::optional<std::string> opt_str;
822 absl::optional<const char*> opt_cstr("abc");
823 opt_str = opt_cstr;
824 EXPECT_TRUE(opt_str);
825 EXPECT_EQ(std::string("abc"), *opt_str);
826 opt_str = absl::optional<const char*>();
827 EXPECT_FALSE(opt_str);
828 opt_str = absl::optional<const char*>("def");
829 EXPECT_TRUE(opt_str);
830 EXPECT_EQ(std::string("def"), *opt_str);
831
832 // operator=(const absl::optional<U>&) with U = NoConvertToOptional
833 EXPECT_TRUE(
834 (std::is_assignable<absl::optional<CopyConvert>,
835 const absl::optional<NoConvertToOptional>&>::value));
836 // operator=(const absl::optional<U>&) with U = NoConvertToOptional
837 // triggers SFINAE because
838 // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
839 EXPECT_FALSE(
840 (std::is_assignable<absl::optional<MoveConvert>&,
841 const absl::optional<NoConvertToOptional>&>::value));
842 // operator=(absl::optional<U>&&) with U = NoConvertToOptional
843 EXPECT_TRUE(
844 (std::is_assignable<absl::optional<MoveConvert>&,
845 absl::optional<NoConvertToOptional>&&>::value));
846 // operator=(const absl::optional<U>&) with U = NoConvertToOptional triggers
847 // SFINAE because std::is_constructible_v<MoveConvertFromOptional, const
848 // NoConvertToOptional&> is false. operator=(U&&) with U = const
849 // absl::optional<NoConverToOptional>& triggers SFINAE because
850 // std::is_constructible<MoveConvertFromOptional,
851 // absl::optional<NoConvertToOptional>&&> is true.
852 EXPECT_FALSE(
853 (std::is_assignable<absl::optional<MoveConvertFromOptional>&,
854 const absl::optional<NoConvertToOptional>&>::value));
855 }
856
TEST(optionalTest,ResetAndHasValue)857 TEST(optionalTest, ResetAndHasValue) {
858 StructorListener listener;
859 Listenable::listener = &listener;
860 absl::optional<Listenable> opt;
861 EXPECT_FALSE(opt);
862 EXPECT_FALSE(opt.has_value());
863 opt.emplace();
864 EXPECT_TRUE(opt);
865 EXPECT_TRUE(opt.has_value());
866 opt.reset();
867 EXPECT_FALSE(opt);
868 EXPECT_FALSE(opt.has_value());
869 EXPECT_EQ(1, listener.destruct);
870 opt.reset();
871 EXPECT_FALSE(opt);
872 EXPECT_FALSE(opt.has_value());
873
874 constexpr absl::optional<int> empty;
875 static_assert(!empty.has_value(), "");
876 constexpr absl::optional<int> nonempty(1);
877 static_assert(nonempty.has_value(), "");
878 }
879
TEST(optionalTest,Emplace)880 TEST(optionalTest, Emplace) {
881 StructorListener listener;
882 Listenable::listener = &listener;
883 absl::optional<Listenable> opt;
884 EXPECT_FALSE(opt);
885 opt.emplace(1);
886 EXPECT_TRUE(opt);
887 opt.emplace(1, 2);
888 EXPECT_EQ(1, listener.construct1);
889 EXPECT_EQ(1, listener.construct2);
890 EXPECT_EQ(1, listener.destruct);
891
892 absl::optional<std::string> o;
893 EXPECT_TRUE((std::is_same<std::string&, decltype(o.emplace("abc"))>::value));
894 std::string& ref = o.emplace("abc");
895 EXPECT_EQ(&ref, &o.value());
896 }
897
TEST(optionalTest,ListEmplace)898 TEST(optionalTest, ListEmplace) {
899 StructorListener listener;
900 Listenable::listener = &listener;
901 absl::optional<Listenable> opt;
902 EXPECT_FALSE(opt);
903 opt.emplace({1});
904 EXPECT_TRUE(opt);
905 opt.emplace({1, 2});
906 EXPECT_EQ(2, listener.listinit);
907 EXPECT_EQ(1, listener.destruct);
908
909 absl::optional<Listenable> o;
910 EXPECT_TRUE((std::is_same<Listenable&, decltype(o.emplace({1}))>::value));
911 Listenable& ref = o.emplace({1});
912 EXPECT_EQ(&ref, &o.value());
913 }
914
TEST(optionalTest,Swap)915 TEST(optionalTest, Swap) {
916 absl::optional<int> opt_empty, opt1 = 1, opt2 = 2;
917 EXPECT_FALSE(opt_empty);
918 EXPECT_TRUE(opt1);
919 EXPECT_EQ(1, opt1.value());
920 EXPECT_TRUE(opt2);
921 EXPECT_EQ(2, opt2.value());
922 swap(opt_empty, opt1);
923 EXPECT_FALSE(opt1);
924 EXPECT_TRUE(opt_empty);
925 EXPECT_EQ(1, opt_empty.value());
926 EXPECT_TRUE(opt2);
927 EXPECT_EQ(2, opt2.value());
928 swap(opt_empty, opt1);
929 EXPECT_FALSE(opt_empty);
930 EXPECT_TRUE(opt1);
931 EXPECT_EQ(1, opt1.value());
932 EXPECT_TRUE(opt2);
933 EXPECT_EQ(2, opt2.value());
934 swap(opt1, opt2);
935 EXPECT_FALSE(opt_empty);
936 EXPECT_TRUE(opt1);
937 EXPECT_EQ(2, opt1.value());
938 EXPECT_TRUE(opt2);
939 EXPECT_EQ(1, opt2.value());
940
941 EXPECT_TRUE(noexcept(opt1.swap(opt2)));
942 EXPECT_TRUE(noexcept(swap(opt1, opt2)));
943 }
944
945 template <int v>
946 struct DeletedOpAddr {
947 int value = v;
948 constexpr DeletedOpAddr() = default;
949 constexpr const DeletedOpAddr<v>* operator&() const = delete; // NOLINT
950 DeletedOpAddr<v>* operator&() = delete; // NOLINT
951 };
952
953 // The static_assert featuring a constexpr call to operator->() is commented out
954 // to document the fact that the current implementation of absl::optional<T>
955 // expects such usecases to be malformed and not compile.
TEST(optionalTest,OperatorAddr)956 TEST(optionalTest, OperatorAddr) {
957 constexpr int v = -1;
958 { // constexpr
959 constexpr absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});
960 static_assert(opt.has_value(), "");
961 // static_assert(opt->value == v, "");
962 static_assert((*opt).value == v, "");
963 }
964 { // non-constexpr
965 const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});
966 EXPECT_TRUE(opt.has_value());
967 EXPECT_TRUE(opt->value == v);
968 EXPECT_TRUE((*opt).value == v);
969 }
970 }
971
TEST(optionalTest,PointerStuff)972 TEST(optionalTest, PointerStuff) {
973 absl::optional<std::string> opt(absl::in_place, "foo");
974 EXPECT_EQ("foo", *opt);
975 const auto& opt_const = opt;
976 EXPECT_EQ("foo", *opt_const);
977 EXPECT_EQ(opt->size(), 3);
978 EXPECT_EQ(opt_const->size(), 3);
979
980 constexpr absl::optional<ConstexprType> opt1(1);
981 static_assert((*opt1).x == ConstexprType::kCtorInt, "");
982 }
983
984 // gcc has a bug pre 4.9.1 where it doesn't do correct overload resolution
985 // when overloads are const-qualified and *this is an raluve.
986 // Skip that test to make the build green again when using the old compiler.
987 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59296 is fixed in 4.9.1.
988 #if defined(__GNUC__) && !defined(__clang__)
989 #define GCC_VERSION (__GNUC__ * 10000 \
990 + __GNUC_MINOR__ * 100 \
991 + __GNUC_PATCHLEVEL__)
992 #if GCC_VERSION < 40901
993 #define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
994 #endif
995 #endif
996
997 // MSVC has a bug with "cv-qualifiers in class construction", fixed in 2017. See
998 // https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#bug-fixes
999 // The compiler some incorrectly ingores the cv-qualifier when generating a
1000 // class object via a constructor call. For example:
1001 //
1002 // class optional {
1003 // constexpr T&& value() &&;
1004 // constexpr const T&& value() const &&;
1005 // }
1006 //
1007 // using COI = const absl::optional<int>;
1008 // static_assert(2 == COI(2).value(), ""); // const &&
1009 //
1010 // This should invoke the "const &&" overload but since it ignores the const
1011 // qualifier it finds the "&&" overload the best candidate.
1012 #if defined(_MSC_VER) && _MSC_VER < 1910
1013 #define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG
1014 #endif
1015
TEST(optionalTest,Value)1016 TEST(optionalTest, Value) {
1017 using O = absl::optional<std::string>;
1018 using CO = const absl::optional<std::string>;
1019 using OC = absl::optional<const std::string>;
1020 O lvalue(absl::in_place, "lvalue");
1021 CO clvalue(absl::in_place, "clvalue");
1022 OC lvalue_c(absl::in_place, "lvalue_c");
1023 EXPECT_EQ("lvalue", lvalue.value());
1024 EXPECT_EQ("clvalue", clvalue.value());
1025 EXPECT_EQ("lvalue_c", lvalue_c.value());
1026 EXPECT_EQ("xvalue", O(absl::in_place, "xvalue").value());
1027 EXPECT_EQ("xvalue_c", OC(absl::in_place, "xvalue_c").value());
1028 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
1029 EXPECT_EQ("cxvalue", CO(absl::in_place, "cxvalue").value());
1030 #endif
1031 EXPECT_EQ("&", TypeQuals(lvalue.value()));
1032 EXPECT_EQ("c&", TypeQuals(clvalue.value()));
1033 EXPECT_EQ("c&", TypeQuals(lvalue_c.value()));
1034 EXPECT_EQ("&&", TypeQuals(O(absl::in_place, "xvalue").value()));
1035 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
1036 !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1037 EXPECT_EQ("c&&", TypeQuals(CO(absl::in_place, "cxvalue").value()));
1038 #endif
1039 EXPECT_EQ("c&&", TypeQuals(OC(absl::in_place, "xvalue_c").value()));
1040
1041 // test on volatile type
1042 using OV = absl::optional<volatile int>;
1043 OV lvalue_v(absl::in_place, 42);
1044 EXPECT_EQ(42, lvalue_v.value());
1045 EXPECT_EQ(42, OV(42).value());
1046 EXPECT_TRUE((std::is_same<volatile int&, decltype(lvalue_v.value())>::value));
1047 EXPECT_TRUE((std::is_same<volatile int&&, decltype(OV(42).value())>::value));
1048
1049 // test exception throw on value()
1050 absl::optional<int> empty;
1051 #ifdef ABSL_HAVE_EXCEPTIONS
1052 EXPECT_THROW((void)empty.value(), absl::bad_optional_access);
1053 #else
1054 EXPECT_DEATH_IF_SUPPORTED((void)empty.value(), "Bad optional access");
1055 #endif
1056
1057 // test constexpr value()
1058 constexpr absl::optional<int> o1(1);
1059 static_assert(1 == o1.value(), ""); // const &
1060 #if !defined(_MSC_VER) && !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1061 using COI = const absl::optional<int>;
1062 static_assert(2 == COI(2).value(), ""); // const &&
1063 #endif
1064 }
1065
TEST(optionalTest,DerefOperator)1066 TEST(optionalTest, DerefOperator) {
1067 using O = absl::optional<std::string>;
1068 using CO = const absl::optional<std::string>;
1069 using OC = absl::optional<const std::string>;
1070 O lvalue(absl::in_place, "lvalue");
1071 CO clvalue(absl::in_place, "clvalue");
1072 OC lvalue_c(absl::in_place, "lvalue_c");
1073 EXPECT_EQ("lvalue", *lvalue);
1074 EXPECT_EQ("clvalue", *clvalue);
1075 EXPECT_EQ("lvalue_c", *lvalue_c);
1076 EXPECT_EQ("xvalue", *O(absl::in_place, "xvalue"));
1077 EXPECT_EQ("xvalue_c", *OC(absl::in_place, "xvalue_c"));
1078 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
1079 EXPECT_EQ("cxvalue", *CO(absl::in_place, "cxvalue"));
1080 #endif
1081 EXPECT_EQ("&", TypeQuals(*lvalue));
1082 EXPECT_EQ("c&", TypeQuals(*clvalue));
1083 EXPECT_EQ("&&", TypeQuals(*O(absl::in_place, "xvalue")));
1084 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
1085 !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1086 EXPECT_EQ("c&&", TypeQuals(*CO(absl::in_place, "cxvalue")));
1087 #endif
1088 EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c")));
1089
1090 // test on volatile type
1091 using OV = absl::optional<volatile int>;
1092 OV lvalue_v(absl::in_place, 42);
1093 EXPECT_EQ(42, *lvalue_v);
1094 EXPECT_EQ(42, *OV(42));
1095 EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value));
1096 EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value));
1097
1098 constexpr absl::optional<int> opt1(1);
1099 static_assert(*opt1 == 1, "");
1100 #if !defined(_MSC_VER) && !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1101 using COI = const absl::optional<int>;
1102 static_assert(*COI(2) == 2, "");
1103 #endif
1104 }
1105
TEST(optionalTest,ValueOr)1106 TEST(optionalTest, ValueOr) {
1107 absl::optional<double> opt_empty, opt_set = 1.2;
1108 EXPECT_EQ(42.0, opt_empty.value_or(42));
1109 EXPECT_EQ(1.2, opt_set.value_or(42));
1110 EXPECT_EQ(42.0, absl::optional<double>().value_or(42));
1111 EXPECT_EQ(1.2, absl::optional<double>(1.2).value_or(42));
1112
1113 constexpr absl::optional<double> copt_empty, copt_set = {1.2};
1114 static_assert(42.0 == copt_empty.value_or(42), "");
1115 static_assert(1.2 == copt_set.value_or(42), "");
1116 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG
1117 using COD = const absl::optional<double>;
1118 static_assert(42.0 == COD().value_or(42), "");
1119 static_assert(1.2 == COD(1.2).value_or(42), "");
1120 #endif
1121 }
1122
1123 // make_optional cannot be constexpr until C++17
TEST(optionalTest,make_optional)1124 TEST(optionalTest, make_optional) {
1125 auto opt_int = absl::make_optional(42);
1126 EXPECT_TRUE((std::is_same<decltype(opt_int), absl::optional<int>>::value));
1127 EXPECT_EQ(42, opt_int);
1128
1129 StructorListener listener;
1130 Listenable::listener = &listener;
1131
1132 absl::optional<Listenable> opt0 = absl::make_optional<Listenable>();
1133 EXPECT_EQ(1, listener.construct0);
1134 absl::optional<Listenable> opt1 = absl::make_optional<Listenable>(1);
1135 EXPECT_EQ(1, listener.construct1);
1136 absl::optional<Listenable> opt2 = absl::make_optional<Listenable>(1, 2);
1137 EXPECT_EQ(1, listener.construct2);
1138 absl::optional<Listenable> opt3 = absl::make_optional<Listenable>({1});
1139 absl::optional<Listenable> opt4 = absl::make_optional<Listenable>({1, 2});
1140 EXPECT_EQ(2, listener.listinit);
1141
1142 // Constexpr tests on trivially copyable types
1143 // optional<T> has trivial copy/move ctors when T is trivially copyable.
1144 // For nontrivial types with constexpr constructors, we need copy elision in
1145 // C++17 for make_optional to be constexpr.
1146 {
1147 constexpr absl::optional<int> c_opt = absl::make_optional(42);
1148 static_assert(c_opt.value() == 42, "");
1149 }
1150 {
1151 struct TrivialCopyable {
1152 constexpr TrivialCopyable() : x(0) {}
1153 constexpr explicit TrivialCopyable(int i) : x(i) {}
1154 int x;
1155 };
1156
1157 constexpr TrivialCopyable v;
1158 constexpr absl::optional<TrivialCopyable> c_opt0 = absl::make_optional(v);
1159 static_assert((*c_opt0).x == 0, "");
1160 constexpr absl::optional<TrivialCopyable> c_opt1 =
1161 absl::make_optional<TrivialCopyable>();
1162 static_assert((*c_opt1).x == 0, "");
1163 constexpr absl::optional<TrivialCopyable> c_opt2 =
1164 absl::make_optional<TrivialCopyable>(42);
1165 static_assert((*c_opt2).x == 42, "");
1166 }
1167 }
1168
1169 template <typename T, typename U>
optionalTest_Comparisons_EXPECT_LESS(T x,U y)1170 void optionalTest_Comparisons_EXPECT_LESS(T x, U y) {
1171 EXPECT_FALSE(x == y);
1172 EXPECT_TRUE(x != y);
1173 EXPECT_TRUE(x < y);
1174 EXPECT_FALSE(x > y);
1175 EXPECT_TRUE(x <= y);
1176 EXPECT_FALSE(x >= y);
1177 }
1178
1179 template <typename T, typename U>
optionalTest_Comparisons_EXPECT_SAME(T x,U y)1180 void optionalTest_Comparisons_EXPECT_SAME(T x, U y) {
1181 EXPECT_TRUE(x == y);
1182 EXPECT_FALSE(x != y);
1183 EXPECT_FALSE(x < y);
1184 EXPECT_FALSE(x > y);
1185 EXPECT_TRUE(x <= y);
1186 EXPECT_TRUE(x >= y);
1187 }
1188
1189 template <typename T, typename U>
optionalTest_Comparisons_EXPECT_GREATER(T x,U y)1190 void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) {
1191 EXPECT_FALSE(x == y);
1192 EXPECT_TRUE(x != y);
1193 EXPECT_FALSE(x < y);
1194 EXPECT_TRUE(x > y);
1195 EXPECT_FALSE(x <= y);
1196 EXPECT_TRUE(x >= y);
1197 }
1198
1199
1200 template <typename T, typename U, typename V>
TestComparisons()1201 void TestComparisons() {
1202 absl::optional<T> ae, a2{2}, a4{4};
1203 absl::optional<U> be, b2{2}, b4{4};
1204 V v3 = 3;
1205
1206 // LHS: absl::nullopt, ae, a2, v3, a4
1207 // RHS: absl::nullopt, be, b2, v3, b4
1208
1209 // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,absl::nullopt);
1210 optionalTest_Comparisons_EXPECT_SAME(absl::nullopt, be);
1211 optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b2);
1212 // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,v3);
1213 optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b4);
1214
1215 optionalTest_Comparisons_EXPECT_SAME(ae, absl::nullopt);
1216 optionalTest_Comparisons_EXPECT_SAME(ae, be);
1217 optionalTest_Comparisons_EXPECT_LESS(ae, b2);
1218 optionalTest_Comparisons_EXPECT_LESS(ae, v3);
1219 optionalTest_Comparisons_EXPECT_LESS(ae, b4);
1220
1221 optionalTest_Comparisons_EXPECT_GREATER(a2, absl::nullopt);
1222 optionalTest_Comparisons_EXPECT_GREATER(a2, be);
1223 optionalTest_Comparisons_EXPECT_SAME(a2, b2);
1224 optionalTest_Comparisons_EXPECT_LESS(a2, v3);
1225 optionalTest_Comparisons_EXPECT_LESS(a2, b4);
1226
1227 // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(v3,absl::nullopt);
1228 optionalTest_Comparisons_EXPECT_GREATER(v3, be);
1229 optionalTest_Comparisons_EXPECT_GREATER(v3, b2);
1230 optionalTest_Comparisons_EXPECT_SAME(v3, v3);
1231 optionalTest_Comparisons_EXPECT_LESS(v3, b4);
1232
1233 optionalTest_Comparisons_EXPECT_GREATER(a4, absl::nullopt);
1234 optionalTest_Comparisons_EXPECT_GREATER(a4, be);
1235 optionalTest_Comparisons_EXPECT_GREATER(a4, b2);
1236 optionalTest_Comparisons_EXPECT_GREATER(a4, v3);
1237 optionalTest_Comparisons_EXPECT_SAME(a4, b4);
1238 }
1239
1240 struct Int1 {
1241 Int1() = default;
Int1__anon65d666410111::Int11242 Int1(int i) : i(i) {} // NOLINT(runtime/explicit)
1243 int i;
1244 };
1245
1246 struct Int2 {
1247 Int2() = default;
Int2__anon65d666410111::Int21248 Int2(int i) : i(i) {} // NOLINT(runtime/explicit)
1249 int i;
1250 };
1251
1252 // comparison between Int1 and Int2
operator ==(const Int1 & lhs,const Int2 & rhs)1253 constexpr bool operator==(const Int1& lhs, const Int2& rhs) {
1254 return lhs.i == rhs.i;
1255 }
operator !=(const Int1 & lhs,const Int2 & rhs)1256 constexpr bool operator!=(const Int1& lhs, const Int2& rhs) {
1257 return !(lhs == rhs);
1258 }
operator <(const Int1 & lhs,const Int2 & rhs)1259 constexpr bool operator<(const Int1& lhs, const Int2& rhs) {
1260 return lhs.i < rhs.i;
1261 }
operator <=(const Int1 & lhs,const Int2 & rhs)1262 constexpr bool operator<=(const Int1& lhs, const Int2& rhs) {
1263 return lhs < rhs || lhs == rhs;
1264 }
operator >(const Int1 & lhs,const Int2 & rhs)1265 constexpr bool operator>(const Int1& lhs, const Int2& rhs) {
1266 return !(lhs <= rhs);
1267 }
operator >=(const Int1 & lhs,const Int2 & rhs)1268 constexpr bool operator>=(const Int1& lhs, const Int2& rhs) {
1269 return !(lhs < rhs);
1270 }
1271
TEST(optionalTest,Comparisons)1272 TEST(optionalTest, Comparisons) {
1273 TestComparisons<int, int, int>();
1274 TestComparisons<const int, int, int>();
1275 TestComparisons<Int1, int, int>();
1276 TestComparisons<int, Int2, int>();
1277 TestComparisons<Int1, Int2, int>();
1278
1279 // compare absl::optional<std::string> with const char*
1280 absl::optional<std::string> opt_str = "abc";
1281 const char* cstr = "abc";
1282 EXPECT_TRUE(opt_str == cstr);
1283 // compare absl::optional<std::string> with absl::optional<const char*>
1284 absl::optional<const char*> opt_cstr = cstr;
1285 EXPECT_TRUE(opt_str == opt_cstr);
1286 // compare absl::optional<std::string> with absl::optional<absl::string_view>
1287 absl::optional<absl::string_view> e1;
1288 absl::optional<std::string> e2;
1289 EXPECT_TRUE(e1 == e2);
1290 }
1291
1292
TEST(optionalTest,SwapRegression)1293 TEST(optionalTest, SwapRegression) {
1294 StructorListener listener;
1295 Listenable::listener = &listener;
1296
1297 {
1298 absl::optional<Listenable> a;
1299 absl::optional<Listenable> b(absl::in_place);
1300 a.swap(b);
1301 }
1302
1303 EXPECT_EQ(1, listener.construct0);
1304 EXPECT_EQ(1, listener.move);
1305 EXPECT_EQ(2, listener.destruct);
1306
1307 {
1308 absl::optional<Listenable> a(absl::in_place);
1309 absl::optional<Listenable> b;
1310 a.swap(b);
1311 }
1312
1313 EXPECT_EQ(2, listener.construct0);
1314 EXPECT_EQ(2, listener.move);
1315 EXPECT_EQ(4, listener.destruct);
1316 }
1317
TEST(optionalTest,BigStringLeakCheck)1318 TEST(optionalTest, BigStringLeakCheck) {
1319 constexpr size_t n = 1 << 16;
1320
1321 using OS = absl::optional<std::string>;
1322
1323 OS a;
1324 OS b = absl::nullopt;
1325 OS c = std::string(n, 'c');
1326 std::string sd(n, 'd');
1327 OS d = sd;
1328 OS e(absl::in_place, n, 'e');
1329 OS f;
1330 f.emplace(n, 'f');
1331
1332 OS ca(a);
1333 OS cb(b);
1334 OS cc(c);
1335 OS cd(d);
1336 OS ce(e);
1337
1338 OS oa;
1339 OS ob = absl::nullopt;
1340 OS oc = std::string(n, 'c');
1341 std::string sod(n, 'd');
1342 OS od = sod;
1343 OS oe(absl::in_place, n, 'e');
1344 OS of;
1345 of.emplace(n, 'f');
1346
1347 OS ma(std::move(oa));
1348 OS mb(std::move(ob));
1349 OS mc(std::move(oc));
1350 OS md(std::move(od));
1351 OS me(std::move(oe));
1352 OS mf(std::move(of));
1353
1354 OS aa1;
1355 OS ab1 = absl::nullopt;
1356 OS ac1 = std::string(n, 'c');
1357 std::string sad1(n, 'd');
1358 OS ad1 = sad1;
1359 OS ae1(absl::in_place, n, 'e');
1360 OS af1;
1361 af1.emplace(n, 'f');
1362
1363 OS aa2;
1364 OS ab2 = absl::nullopt;
1365 OS ac2 = std::string(n, 'c');
1366 std::string sad2(n, 'd');
1367 OS ad2 = sad2;
1368 OS ae2(absl::in_place, n, 'e');
1369 OS af2;
1370 af2.emplace(n, 'f');
1371
1372 aa1 = af2;
1373 ab1 = ae2;
1374 ac1 = ad2;
1375 ad1 = ac2;
1376 ae1 = ab2;
1377 af1 = aa2;
1378
1379 OS aa3;
1380 OS ab3 = absl::nullopt;
1381 OS ac3 = std::string(n, 'c');
1382 std::string sad3(n, 'd');
1383 OS ad3 = sad3;
1384 OS ae3(absl::in_place, n, 'e');
1385 OS af3;
1386 af3.emplace(n, 'f');
1387
1388 aa3 = absl::nullopt;
1389 ab3 = absl::nullopt;
1390 ac3 = absl::nullopt;
1391 ad3 = absl::nullopt;
1392 ae3 = absl::nullopt;
1393 af3 = absl::nullopt;
1394
1395 OS aa4;
1396 OS ab4 = absl::nullopt;
1397 OS ac4 = std::string(n, 'c');
1398 std::string sad4(n, 'd');
1399 OS ad4 = sad4;
1400 OS ae4(absl::in_place, n, 'e');
1401 OS af4;
1402 af4.emplace(n, 'f');
1403
1404 aa4 = OS(absl::in_place, n, 'a');
1405 ab4 = OS(absl::in_place, n, 'b');
1406 ac4 = OS(absl::in_place, n, 'c');
1407 ad4 = OS(absl::in_place, n, 'd');
1408 ae4 = OS(absl::in_place, n, 'e');
1409 af4 = OS(absl::in_place, n, 'f');
1410
1411 OS aa5;
1412 OS ab5 = absl::nullopt;
1413 OS ac5 = std::string(n, 'c');
1414 std::string sad5(n, 'd');
1415 OS ad5 = sad5;
1416 OS ae5(absl::in_place, n, 'e');
1417 OS af5;
1418 af5.emplace(n, 'f');
1419
1420 std::string saa5(n, 'a');
1421 std::string sab5(n, 'a');
1422 std::string sac5(n, 'a');
1423 std::string sad52(n, 'a');
1424 std::string sae5(n, 'a');
1425 std::string saf5(n, 'a');
1426
1427 aa5 = saa5;
1428 ab5 = sab5;
1429 ac5 = sac5;
1430 ad5 = sad52;
1431 ae5 = sae5;
1432 af5 = saf5;
1433
1434 OS aa6;
1435 OS ab6 = absl::nullopt;
1436 OS ac6 = std::string(n, 'c');
1437 std::string sad6(n, 'd');
1438 OS ad6 = sad6;
1439 OS ae6(absl::in_place, n, 'e');
1440 OS af6;
1441 af6.emplace(n, 'f');
1442
1443 aa6 = std::string(n, 'a');
1444 ab6 = std::string(n, 'b');
1445 ac6 = std::string(n, 'c');
1446 ad6 = std::string(n, 'd');
1447 ae6 = std::string(n, 'e');
1448 af6 = std::string(n, 'f');
1449
1450 OS aa7;
1451 OS ab7 = absl::nullopt;
1452 OS ac7 = std::string(n, 'c');
1453 std::string sad7(n, 'd');
1454 OS ad7 = sad7;
1455 OS ae7(absl::in_place, n, 'e');
1456 OS af7;
1457 af7.emplace(n, 'f');
1458
1459 aa7.emplace(n, 'A');
1460 ab7.emplace(n, 'B');
1461 ac7.emplace(n, 'C');
1462 ad7.emplace(n, 'D');
1463 ae7.emplace(n, 'E');
1464 af7.emplace(n, 'F');
1465 }
1466
TEST(optionalTest,MoveAssignRegression)1467 TEST(optionalTest, MoveAssignRegression) {
1468 StructorListener listener;
1469 Listenable::listener = &listener;
1470
1471 {
1472 absl::optional<Listenable> a;
1473 Listenable b;
1474 a = std::move(b);
1475 }
1476
1477 EXPECT_EQ(1, listener.construct0);
1478 EXPECT_EQ(1, listener.move);
1479 EXPECT_EQ(2, listener.destruct);
1480 }
1481
TEST(optionalTest,ValueType)1482 TEST(optionalTest, ValueType) {
1483 EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value));
1484 EXPECT_TRUE((std::is_same<absl::optional<std::string>::value_type,
1485 std::string>::value));
1486 EXPECT_FALSE(
1487 (std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value));
1488 }
1489
1490 template <typename T>
1491 struct is_hash_enabled_for {
1492 template <typename U, typename = decltype(std::hash<U>()(std::declval<U>()))>
1493 static std::true_type test(int);
1494
1495 template <typename U>
1496 static std::false_type test(...);
1497
1498 static constexpr bool value = decltype(test<T>(0))::value;
1499 };
1500
TEST(optionalTest,Hash)1501 TEST(optionalTest, Hash) {
1502 std::hash<absl::optional<int>> hash;
1503 std::set<size_t> hashcodes;
1504 hashcodes.insert(hash(absl::nullopt));
1505 for (int i = 0; i < 100; ++i) {
1506 hashcodes.insert(hash(i));
1507 }
1508 EXPECT_GT(hashcodes.size(), 90);
1509
1510 static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");
1511 static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");
1512 static_assert(
1513 absl::type_traits_internal::IsHashable<absl::optional<int>>::value, "");
1514 static_assert(
1515 absl::type_traits_internal::IsHashable<absl::optional<Hashable>>::value,
1516 "");
1517 absl::type_traits_internal::AssertHashEnabled<absl::optional<int>>();
1518 absl::type_traits_internal::AssertHashEnabled<absl::optional<Hashable>>();
1519
1520 #if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
1521 static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, "");
1522 static_assert(!absl::type_traits_internal::IsHashable<
1523 absl::optional<NonHashable>>::value,
1524 "");
1525 #endif
1526
1527 // libstdc++ std::optional is missing remove_const_t, i.e. it's using
1528 // std::hash<T> rather than std::hash<std::remove_const_t<T>>.
1529 // Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262
1530 #ifndef __GLIBCXX__
1531 static_assert(is_hash_enabled_for<absl::optional<const int>>::value, "");
1532 static_assert(is_hash_enabled_for<absl::optional<const Hashable>>::value, "");
1533 std::hash<absl::optional<const int>> c_hash;
1534 for (int i = 0; i < 100; ++i) {
1535 EXPECT_EQ(hash(i), c_hash(i));
1536 }
1537 #endif
1538 }
1539
1540 struct MoveMeNoThrow {
MoveMeNoThrow__anon65d666410111::MoveMeNoThrow1541 MoveMeNoThrow() : x(0) {}
MoveMeNoThrow__anon65d666410111::MoveMeNoThrow1542 [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
1543 ABSL_RAW_LOG(FATAL, "Should not be called.");
1544 abort();
1545 }
MoveMeNoThrow__anon65d666410111::MoveMeNoThrow1546 MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
1547 int x;
1548 };
1549
1550 struct MoveMeThrow {
MoveMeThrow__anon65d666410111::MoveMeThrow1551 MoveMeThrow() : x(0) {}
MoveMeThrow__anon65d666410111::MoveMeThrow1552 MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}
MoveMeThrow__anon65d666410111::MoveMeThrow1553 MoveMeThrow(MoveMeThrow&& other) : x(other.x) {}
1554 int x;
1555 };
1556
TEST(optionalTest,NoExcept)1557 TEST(optionalTest, NoExcept) {
1558 static_assert(
1559 std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value,
1560 "");
1561 #ifndef ABSL_USES_STD_OPTIONAL
1562 static_assert(absl::default_allocator_is_nothrow::value ==
1563 std::is_nothrow_move_constructible<
1564 absl::optional<MoveMeThrow>>::value,
1565 "");
1566 #endif
1567 std::vector<absl::optional<MoveMeNoThrow>> v;
1568 for (int i = 0; i < 10; ++i) v.emplace_back();
1569 }
1570
1571 struct AnyLike {
1572 AnyLike(AnyLike&&) = default;
1573 AnyLike(const AnyLike&) = default;
1574
1575 template <typename ValueType,
1576 typename T = typename std::decay<ValueType>::type,
1577 typename std::enable_if<
1578 !absl::disjunction<
1579 std::is_same<AnyLike, T>,
1580 absl::negation<std::is_copy_constructible<T>>>::value,
1581 int>::type = 0>
AnyLike__anon65d666410111::AnyLike1582 AnyLike(ValueType&&) {} // NOLINT(runtime/explicit)
1583
1584 AnyLike& operator=(AnyLike&&) = default;
1585 AnyLike& operator=(const AnyLike&) = default;
1586
1587 template <typename ValueType,
1588 typename T = typename std::decay<ValueType>::type>
1589 typename std::enable_if<
1590 absl::conjunction<absl::negation<std::is_same<AnyLike, T>>,
1591 std::is_copy_constructible<T>>::value,
1592 AnyLike&>::type
operator =__anon65d666410111::AnyLike1593 operator=(ValueType&& /* rhs */) {
1594 return *this;
1595 }
1596 };
1597
TEST(optionalTest,ConstructionConstraints)1598 TEST(optionalTest, ConstructionConstraints) {
1599 EXPECT_TRUE((std::is_constructible<AnyLike, absl::optional<AnyLike>>::value));
1600
1601 EXPECT_TRUE(
1602 (std::is_constructible<AnyLike, const absl::optional<AnyLike>&>::value));
1603
1604 EXPECT_TRUE((std::is_constructible<absl::optional<AnyLike>, AnyLike>::value));
1605 EXPECT_TRUE(
1606 (std::is_constructible<absl::optional<AnyLike>, const AnyLike&>::value));
1607
1608 EXPECT_TRUE((std::is_convertible<absl::optional<AnyLike>, AnyLike>::value));
1609
1610 EXPECT_TRUE(
1611 (std::is_convertible<const absl::optional<AnyLike>&, AnyLike>::value));
1612
1613 EXPECT_TRUE((std::is_convertible<AnyLike, absl::optional<AnyLike>>::value));
1614 EXPECT_TRUE(
1615 (std::is_convertible<const AnyLike&, absl::optional<AnyLike>>::value));
1616
1617 EXPECT_TRUE(std::is_move_constructible<absl::optional<AnyLike>>::value);
1618 EXPECT_TRUE(std::is_copy_constructible<absl::optional<AnyLike>>::value);
1619 }
1620
TEST(optionalTest,AssignmentConstraints)1621 TEST(optionalTest, AssignmentConstraints) {
1622 EXPECT_TRUE((std::is_assignable<AnyLike&, absl::optional<AnyLike>>::value));
1623 EXPECT_TRUE(
1624 (std::is_assignable<AnyLike&, const absl::optional<AnyLike>&>::value));
1625 EXPECT_TRUE((std::is_assignable<absl::optional<AnyLike>&, AnyLike>::value));
1626 EXPECT_TRUE(
1627 (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value));
1628 EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value);
1629 EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
1630 }
1631
1632 #if !defined(__EMSCRIPTEN__)
1633 struct NestedClassBug {
1634 struct Inner {
1635 bool dummy = false;
1636 };
1637 absl::optional<Inner> value;
1638 };
1639
TEST(optionalTest,InPlaceTSFINAEBug)1640 TEST(optionalTest, InPlaceTSFINAEBug) {
1641 NestedClassBug b;
1642 ((void)b);
1643 using Inner = NestedClassBug::Inner;
1644
1645 EXPECT_TRUE((std::is_default_constructible<Inner>::value));
1646 EXPECT_TRUE((std::is_constructible<Inner>::value));
1647 EXPECT_TRUE(
1648 (std::is_constructible<absl::optional<Inner>, absl::in_place_t>::value));
1649
1650 absl::optional<Inner> o(absl::in_place);
1651 EXPECT_TRUE(o.has_value());
1652 o.emplace();
1653 EXPECT_TRUE(o.has_value());
1654 }
1655 #endif // !defined(__EMSCRIPTEN__)
1656
1657 } // namespace
1658
1659 #endif // #if !defined(ABSL_USES_STD_OPTIONAL)
1660