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__anon2d80b29b0111::Listenable76   Listenable() { ++listener->construct0; }
Listenable__anon2d80b29b0111::Listenable77   explicit Listenable(int /*unused*/) { ++listener->construct1; }
Listenable__anon2d80b29b0111::Listenable78   Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }
Listenable__anon2d80b29b0111::Listenable79   Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }
Listenable__anon2d80b29b0111::Listenable80   Listenable(const Listenable& /*unused*/) { ++listener->copy; }
Listenable__anon2d80b29b0111::Listenable81   Listenable(const volatile Listenable& /*unused*/) {
82     ++listener->volatile_copy;
83   }
Listenable__anon2d80b29b0111::Listenable84   Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; }
Listenable__anon2d80b29b0111::Listenable85   Listenable(Listenable&& /*unused*/) { ++listener->move; }
operator =__anon2d80b29b0111::Listenable86   Listenable& operator=(const Listenable& /*unused*/) {
87     ++listener->copy_assign;
88     return *this;
89   }
operator =__anon2d80b29b0111::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 =__anon2d80b29b0111::Listenable96   void operator=(const volatile Listenable& /*unused*/) volatile {
97     ++listener->volatile_copy_assign;
98   }
operator =__anon2d80b29b0111::Listenable99   void operator=(volatile Listenable&& /*unused*/) volatile {
100     ++listener->volatile_move_assign;
101   }
~Listenable__anon2d80b29b0111::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__anon2d80b29b0111::ConstexprType126   constexpr ConstexprType() : x(kCtorDefault) {}
ConstexprType__anon2d80b29b0111::ConstexprType127   constexpr explicit ConstexprType(int i) : x(kCtorInt) {}
128 #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
ConstexprType__anon2d80b29b0111::ConstexprType129   constexpr ConstexprType(std::initializer_list<int> il)
130       : x(kCtorInitializerList) {}
131 #endif
ConstexprType__anon2d80b29b0111::ConstexprType132   constexpr ConstexprType(const char*)  // NOLINT(runtime/explicit)
133       : x(kCtorConstChar) {}
134   int x;
135 };
136 
137 struct Copyable {
Copyable__anon2d80b29b0111::Copyable138   Copyable() {}
Copyable__anon2d80b29b0111::Copyable139   Copyable(const Copyable&) {}
operator =__anon2d80b29b0111::Copyable140   Copyable& operator=(const Copyable&) { return *this; }
141 };
142 
143 struct MoveableThrow {
MoveableThrow__anon2d80b29b0111::MoveableThrow144   MoveableThrow() {}
MoveableThrow__anon2d80b29b0111::MoveableThrow145   MoveableThrow(MoveableThrow&&) {}
operator =__anon2d80b29b0111::MoveableThrow146   MoveableThrow& operator=(MoveableThrow&&) { return *this; }
147 };
148 
149 struct MoveableNoThrow {
MoveableNoThrow__anon2d80b29b0111::MoveableNoThrow150   MoveableNoThrow() {}
MoveableNoThrow__anon2d80b29b0111::MoveableNoThrow151   MoveableNoThrow(MoveableNoThrow&&) noexcept {}
operator =__anon2d80b29b0111::MoveableNoThrow152   MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }
153 };
154 
155 struct NonMovable {
NonMovable__anon2d80b29b0111::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__anon2d80b29b0111::NoDefault165   NoDefault(const NoDefault&) {}
operator =__anon2d80b29b0111::NoDefault166   NoDefault& operator=(const NoDefault&) { return *this; }
167 };
168 
169 struct ConvertsFromInPlaceT {
ConvertsFromInPlaceT__anon2d80b29b0111::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__anon2d80b29b0111::Convert412   Convert(const Implicit&)  // NOLINT(runtime/explicit)
413       : implicit(true), move(false) {}
Convert__anon2d80b29b0111::Convert414   Convert(Implicit&&)  // NOLINT(runtime/explicit)
415       : implicit(true), move(true) {}
Convert__anon2d80b29b0111::Convert416   explicit Convert(const Explicit&) : implicit(false), move(false) {}
Convert__anon2d80b29b0111::Convert417   explicit Convert(Explicit&&) : implicit(false), move(true) {}
418 
419   bool implicit;
420   bool move;
421 };
422 
423 struct ConvertFromOptional {
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional424   ConvertFromOptional(const Implicit&)  // NOLINT(runtime/explicit)
425       : implicit(true), move(false), from_optional(false) {}
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional426   ConvertFromOptional(Implicit&&)  // NOLINT(runtime/explicit)
427       : implicit(true), move(true), from_optional(false) {}
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional428   ConvertFromOptional(
429       const absl::optional<Implicit>&)  // NOLINT(runtime/explicit)
430       : implicit(true), move(false), from_optional(true) {}
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional431   ConvertFromOptional(absl::optional<Implicit>&&)  // NOLINT(runtime/explicit)
432       : implicit(true), move(true), from_optional(true) {}
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional433   explicit ConvertFromOptional(const Explicit&)
434       : implicit(false), move(false), from_optional(false) {}
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional435   explicit ConvertFromOptional(Explicit&&)
436       : implicit(false), move(true), from_optional(false) {}
ConvertFromOptional__anon2d80b29b0111::ConvertFromOptional437   explicit ConvertFromOptional(const absl::optional<Explicit>&)
438       : implicit(false), move(false), from_optional(true) {}
ConvertFromOptional__anon2d80b29b0111::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__anon2d80b29b0111::Int11242   Int1(int i) : i(i) {}  // NOLINT(runtime/explicit)
1243   int i;
1244 };
1245 
1246 struct Int2 {
1247   Int2() = default;
Int2__anon2d80b29b0111::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__anon2d80b29b0111::MoveMeNoThrow1541   MoveMeNoThrow() : x(0) {}
MoveMeNoThrow__anon2d80b29b0111::MoveMeNoThrow1542   [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
1543     ABSL_RAW_LOG(FATAL, "Should not be called.");
1544     abort();
1545   }
MoveMeNoThrow__anon2d80b29b0111::MoveMeNoThrow1546   MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
1547   int x;
1548 };
1549 
1550 struct MoveMeThrow {
MoveMeThrow__anon2d80b29b0111::MoveMeThrow1551   MoveMeThrow() : x(0) {}
MoveMeThrow__anon2d80b29b0111::MoveMeThrow1552   MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}
MoveMeThrow__anon2d80b29b0111::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__anon2d80b29b0111::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 =__anon2d80b29b0111::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