• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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__anon565f22760111::Listenable76   Listenable() { ++listener->construct0; }
Listenable__anon565f22760111::Listenable77   explicit Listenable(int /*unused*/) { ++listener->construct1; }
Listenable__anon565f22760111::Listenable78   Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }
Listenable__anon565f22760111::Listenable79   Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }
Listenable__anon565f22760111::Listenable80   Listenable(const Listenable& /*unused*/) { ++listener->copy; }
Listenable__anon565f22760111::Listenable81   Listenable(const volatile Listenable& /*unused*/) {
82     ++listener->volatile_copy;
83   }
Listenable__anon565f22760111::Listenable84   Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; }
Listenable__anon565f22760111::Listenable85   Listenable(Listenable&& /*unused*/) { ++listener->move; }
operator =__anon565f22760111::Listenable86   Listenable& operator=(const Listenable& /*unused*/) {
87     ++listener->copy_assign;
88     return *this;
89   }
operator =__anon565f22760111::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 =__anon565f22760111::Listenable96   void operator=(const volatile Listenable& /*unused*/) volatile {
97     ++listener->volatile_copy_assign;
98   }
operator =__anon565f22760111::Listenable99   void operator=(volatile Listenable&& /*unused*/) volatile {
100     ++listener->volatile_move_assign;
101   }
~Listenable__anon565f22760111::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__anon565f22760111::ConstexprType126   constexpr ConstexprType() : x(kCtorDefault) {}
ConstexprType__anon565f22760111::ConstexprType127   constexpr explicit ConstexprType(int i) : x(kCtorInt) {}
128 #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
ConstexprType__anon565f22760111::ConstexprType129   constexpr ConstexprType(std::initializer_list<int> il)
130       : x(kCtorInitializerList) {}
131 #endif
ConstexprType__anon565f22760111::ConstexprType132   constexpr ConstexprType(const char*)  // NOLINT(runtime/explicit)
133       : x(kCtorConstChar) {}
134   int x;
135 };
136 
137 struct Copyable {
Copyable__anon565f22760111::Copyable138   Copyable() {}
Copyable__anon565f22760111::Copyable139   Copyable(const Copyable&) {}
operator =__anon565f22760111::Copyable140   Copyable& operator=(const Copyable&) { return *this; }
141 };
142 
143 struct MoveableThrow {
MoveableThrow__anon565f22760111::MoveableThrow144   MoveableThrow() {}
MoveableThrow__anon565f22760111::MoveableThrow145   MoveableThrow(MoveableThrow&&) {}
operator =__anon565f22760111::MoveableThrow146   MoveableThrow& operator=(MoveableThrow&&) { return *this; }
147 };
148 
149 struct MoveableNoThrow {
MoveableNoThrow__anon565f22760111::MoveableNoThrow150   MoveableNoThrow() {}
MoveableNoThrow__anon565f22760111::MoveableNoThrow151   MoveableNoThrow(MoveableNoThrow&&) noexcept {}
operator =__anon565f22760111::MoveableNoThrow152   MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }
153 };
154 
155 struct NonMovable {
NonMovable__anon565f22760111::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__anon565f22760111::NoDefault165   NoDefault(const NoDefault&) {}
operator =__anon565f22760111::NoDefault166   NoDefault& operator=(const NoDefault&) { return *this; }
167 };
168 
169 struct ConvertsFromInPlaceT {
ConvertsFromInPlaceT__anon565f22760111::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__anon565f22760111::Convert412   Convert(const Implicit&)  // NOLINT(runtime/explicit)
413       : implicit(true), move(false) {}
Convert__anon565f22760111::Convert414   Convert(Implicit&&)  // NOLINT(runtime/explicit)
415       : implicit(true), move(true) {}
Convert__anon565f22760111::Convert416   explicit Convert(const Explicit&) : implicit(false), move(false) {}
Convert__anon565f22760111::Convert417   explicit Convert(Explicit&&) : implicit(false), move(true) {}
418 
419   bool implicit;
420   bool move;
421 };
422 
423 struct ConvertFromOptional {
ConvertFromOptional__anon565f22760111::ConvertFromOptional424   ConvertFromOptional(const Implicit&)  // NOLINT(runtime/explicit)
425       : implicit(true), move(false), from_optional(false) {}
ConvertFromOptional__anon565f22760111::ConvertFromOptional426   ConvertFromOptional(Implicit&&)  // NOLINT(runtime/explicit)
427       : implicit(true), move(true), from_optional(false) {}
ConvertFromOptional__anon565f22760111::ConvertFromOptional428   ConvertFromOptional(
429       const absl::optional<Implicit>&)  // NOLINT(runtime/explicit)
430       : implicit(true), move(false), from_optional(true) {}
ConvertFromOptional__anon565f22760111::ConvertFromOptional431   ConvertFromOptional(absl::optional<Implicit>&&)  // NOLINT(runtime/explicit)
432       : implicit(true), move(true), from_optional(true) {}
ConvertFromOptional__anon565f22760111::ConvertFromOptional433   explicit ConvertFromOptional(const Explicit&)
434       : implicit(false), move(false), from_optional(false) {}
ConvertFromOptional__anon565f22760111::ConvertFromOptional435   explicit ConvertFromOptional(Explicit&&)
436       : implicit(false), move(true), from_optional(false) {}
ConvertFromOptional__anon565f22760111::ConvertFromOptional437   explicit ConvertFromOptional(const absl::optional<Explicit>&)
438       : implicit(false), move(false), from_optional(true) {}
ConvertFromOptional__anon565f22760111::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((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(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
1061     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1062   using COI = const absl::optional<int>;
1063   static_assert(2 == COI(2).value(), "");  // const &&
1064 #endif
1065 }
1066 
TEST(optionalTest,DerefOperator)1067 TEST(optionalTest, DerefOperator) {
1068   using O = absl::optional<std::string>;
1069   using CO = const absl::optional<std::string>;
1070   using OC = absl::optional<const std::string>;
1071   O lvalue(absl::in_place, "lvalue");
1072   CO clvalue(absl::in_place, "clvalue");
1073   OC lvalue_c(absl::in_place, "lvalue_c");
1074   EXPECT_EQ("lvalue", *lvalue);
1075   EXPECT_EQ("clvalue", *clvalue);
1076   EXPECT_EQ("lvalue_c", *lvalue_c);
1077   EXPECT_EQ("xvalue", *O(absl::in_place, "xvalue"));
1078   EXPECT_EQ("xvalue_c", *OC(absl::in_place, "xvalue_c"));
1079 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
1080   EXPECT_EQ("cxvalue", *CO(absl::in_place, "cxvalue"));
1081 #endif
1082   EXPECT_EQ("&", TypeQuals(*lvalue));
1083   EXPECT_EQ("c&", TypeQuals(*clvalue));
1084   EXPECT_EQ("&&", TypeQuals(*O(absl::in_place, "xvalue")));
1085 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
1086     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1087   EXPECT_EQ("c&&", TypeQuals(*CO(absl::in_place, "cxvalue")));
1088 #endif
1089   EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c")));
1090 
1091   // test on volatile type
1092   using OV = absl::optional<volatile int>;
1093   OV lvalue_v(absl::in_place, 42);
1094   EXPECT_EQ(42, *lvalue_v);
1095   EXPECT_EQ(42, *OV(42));
1096   EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value));
1097   EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value));
1098 
1099   constexpr absl::optional<int> opt1(1);
1100   static_assert(*opt1 == 1, "");
1101 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
1102     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
1103   using COI = const absl::optional<int>;
1104   static_assert(*COI(2) == 2, "");
1105 #endif
1106 }
1107 
TEST(optionalTest,ValueOr)1108 TEST(optionalTest, ValueOr) {
1109   absl::optional<double> opt_empty, opt_set = 1.2;
1110   EXPECT_EQ(42.0, opt_empty.value_or(42));
1111   EXPECT_EQ(1.2, opt_set.value_or(42));
1112   EXPECT_EQ(42.0, absl::optional<double>().value_or(42));
1113   EXPECT_EQ(1.2, absl::optional<double>(1.2).value_or(42));
1114 
1115   constexpr absl::optional<double> copt_empty, copt_set = {1.2};
1116   static_assert(42.0 == copt_empty.value_or(42), "");
1117   static_assert(1.2 == copt_set.value_or(42), "");
1118 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG
1119   using COD = const absl::optional<double>;
1120   static_assert(42.0 == COD().value_or(42), "");
1121   static_assert(1.2 == COD(1.2).value_or(42), "");
1122 #endif
1123 }
1124 
1125 // make_optional cannot be constexpr until C++17
TEST(optionalTest,make_optional)1126 TEST(optionalTest, make_optional) {
1127   auto opt_int = absl::make_optional(42);
1128   EXPECT_TRUE((std::is_same<decltype(opt_int), absl::optional<int>>::value));
1129   EXPECT_EQ(42, opt_int);
1130 
1131   StructorListener listener;
1132   Listenable::listener = &listener;
1133 
1134   absl::optional<Listenable> opt0 = absl::make_optional<Listenable>();
1135   EXPECT_EQ(1, listener.construct0);
1136   absl::optional<Listenable> opt1 = absl::make_optional<Listenable>(1);
1137   EXPECT_EQ(1, listener.construct1);
1138   absl::optional<Listenable> opt2 = absl::make_optional<Listenable>(1, 2);
1139   EXPECT_EQ(1, listener.construct2);
1140   absl::optional<Listenable> opt3 = absl::make_optional<Listenable>({1});
1141   absl::optional<Listenable> opt4 = absl::make_optional<Listenable>({1, 2});
1142   EXPECT_EQ(2, listener.listinit);
1143 
1144   // Constexpr tests on trivially copyable types
1145   // optional<T> has trivial copy/move ctors when T is trivially copyable.
1146   // For nontrivial types with constexpr constructors, we need copy elision in
1147   // C++17 for make_optional to be constexpr.
1148   {
1149     constexpr absl::optional<int> c_opt = absl::make_optional(42);
1150     static_assert(c_opt.value() == 42, "");
1151   }
1152   {
1153     struct TrivialCopyable {
1154       constexpr TrivialCopyable() : x(0) {}
1155       constexpr explicit TrivialCopyable(int i) : x(i) {}
1156       int x;
1157     };
1158 
1159     constexpr TrivialCopyable v;
1160     constexpr absl::optional<TrivialCopyable> c_opt0 = absl::make_optional(v);
1161     static_assert((*c_opt0).x == 0, "");
1162     constexpr absl::optional<TrivialCopyable> c_opt1 =
1163         absl::make_optional<TrivialCopyable>();
1164     static_assert((*c_opt1).x == 0, "");
1165     constexpr absl::optional<TrivialCopyable> c_opt2 =
1166         absl::make_optional<TrivialCopyable>(42);
1167     static_assert((*c_opt2).x == 42, "");
1168   }
1169 }
1170 
1171 template <typename T, typename U>
optionalTest_Comparisons_EXPECT_LESS(T x,U y)1172 void optionalTest_Comparisons_EXPECT_LESS(T x, U y) {
1173   EXPECT_FALSE(x == y);
1174   EXPECT_TRUE(x != y);
1175   EXPECT_TRUE(x < y);
1176   EXPECT_FALSE(x > y);
1177   EXPECT_TRUE(x <= y);
1178   EXPECT_FALSE(x >= y);
1179 }
1180 
1181 template <typename T, typename U>
optionalTest_Comparisons_EXPECT_SAME(T x,U y)1182 void optionalTest_Comparisons_EXPECT_SAME(T x, U y) {
1183   EXPECT_TRUE(x == y);
1184   EXPECT_FALSE(x != y);
1185   EXPECT_FALSE(x < y);
1186   EXPECT_FALSE(x > y);
1187   EXPECT_TRUE(x <= y);
1188   EXPECT_TRUE(x >= y);
1189 }
1190 
1191 template <typename T, typename U>
optionalTest_Comparisons_EXPECT_GREATER(T x,U y)1192 void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) {
1193   EXPECT_FALSE(x == y);
1194   EXPECT_TRUE(x != y);
1195   EXPECT_FALSE(x < y);
1196   EXPECT_TRUE(x > y);
1197   EXPECT_FALSE(x <= y);
1198   EXPECT_TRUE(x >= y);
1199 }
1200 
1201 
1202 template <typename T, typename U, typename V>
TestComparisons()1203 void TestComparisons() {
1204   absl::optional<T> ae, a2{2}, a4{4};
1205   absl::optional<U> be, b2{2}, b4{4};
1206   V v3 = 3;
1207 
1208   // LHS: absl::nullopt, ae, a2, v3, a4
1209   // RHS: absl::nullopt, be, b2, v3, b4
1210 
1211   // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,absl::nullopt);
1212   optionalTest_Comparisons_EXPECT_SAME(absl::nullopt, be);
1213   optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b2);
1214   // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,v3);
1215   optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b4);
1216 
1217   optionalTest_Comparisons_EXPECT_SAME(ae, absl::nullopt);
1218   optionalTest_Comparisons_EXPECT_SAME(ae, be);
1219   optionalTest_Comparisons_EXPECT_LESS(ae, b2);
1220   optionalTest_Comparisons_EXPECT_LESS(ae, v3);
1221   optionalTest_Comparisons_EXPECT_LESS(ae, b4);
1222 
1223   optionalTest_Comparisons_EXPECT_GREATER(a2, absl::nullopt);
1224   optionalTest_Comparisons_EXPECT_GREATER(a2, be);
1225   optionalTest_Comparisons_EXPECT_SAME(a2, b2);
1226   optionalTest_Comparisons_EXPECT_LESS(a2, v3);
1227   optionalTest_Comparisons_EXPECT_LESS(a2, b4);
1228 
1229   // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(v3,absl::nullopt);
1230   optionalTest_Comparisons_EXPECT_GREATER(v3, be);
1231   optionalTest_Comparisons_EXPECT_GREATER(v3, b2);
1232   optionalTest_Comparisons_EXPECT_SAME(v3, v3);
1233   optionalTest_Comparisons_EXPECT_LESS(v3, b4);
1234 
1235   optionalTest_Comparisons_EXPECT_GREATER(a4, absl::nullopt);
1236   optionalTest_Comparisons_EXPECT_GREATER(a4, be);
1237   optionalTest_Comparisons_EXPECT_GREATER(a4, b2);
1238   optionalTest_Comparisons_EXPECT_GREATER(a4, v3);
1239   optionalTest_Comparisons_EXPECT_SAME(a4, b4);
1240 }
1241 
1242 struct Int1 {
1243   Int1() = default;
Int1__anon565f22760111::Int11244   Int1(int i) : i(i) {}  // NOLINT(runtime/explicit)
1245   int i;
1246 };
1247 
1248 struct Int2 {
1249   Int2() = default;
Int2__anon565f22760111::Int21250   Int2(int i) : i(i) {}  // NOLINT(runtime/explicit)
1251   int i;
1252 };
1253 
1254 // comparison between Int1 and Int2
operator ==(const Int1 & lhs,const Int2 & rhs)1255 constexpr bool operator==(const Int1& lhs, const Int2& rhs) {
1256   return lhs.i == rhs.i;
1257 }
operator !=(const Int1 & lhs,const Int2 & rhs)1258 constexpr bool operator!=(const Int1& lhs, const Int2& rhs) {
1259   return !(lhs == rhs);
1260 }
operator <(const Int1 & lhs,const Int2 & rhs)1261 constexpr bool operator<(const Int1& lhs, const Int2& rhs) {
1262   return lhs.i < rhs.i;
1263 }
operator <=(const Int1 & lhs,const Int2 & rhs)1264 constexpr bool operator<=(const Int1& lhs, const Int2& rhs) {
1265   return lhs < rhs || lhs == rhs;
1266 }
operator >(const Int1 & lhs,const Int2 & rhs)1267 constexpr bool operator>(const Int1& lhs, const Int2& rhs) {
1268   return !(lhs <= rhs);
1269 }
operator >=(const Int1 & lhs,const Int2 & rhs)1270 constexpr bool operator>=(const Int1& lhs, const Int2& rhs) {
1271   return !(lhs < rhs);
1272 }
1273 
TEST(optionalTest,Comparisons)1274 TEST(optionalTest, Comparisons) {
1275   TestComparisons<int, int, int>();
1276   TestComparisons<const int, int, int>();
1277   TestComparisons<Int1, int, int>();
1278   TestComparisons<int, Int2, int>();
1279   TestComparisons<Int1, Int2, int>();
1280 
1281   // compare absl::optional<std::string> with const char*
1282   absl::optional<std::string> opt_str = "abc";
1283   const char* cstr = "abc";
1284   EXPECT_TRUE(opt_str == cstr);
1285   // compare absl::optional<std::string> with absl::optional<const char*>
1286   absl::optional<const char*> opt_cstr = cstr;
1287   EXPECT_TRUE(opt_str == opt_cstr);
1288   // compare absl::optional<std::string> with absl::optional<absl::string_view>
1289   absl::optional<absl::string_view> e1;
1290   absl::optional<std::string> e2;
1291   EXPECT_TRUE(e1 == e2);
1292 }
1293 
1294 
TEST(optionalTest,SwapRegression)1295 TEST(optionalTest, SwapRegression) {
1296   StructorListener listener;
1297   Listenable::listener = &listener;
1298 
1299   {
1300     absl::optional<Listenable> a;
1301     absl::optional<Listenable> b(absl::in_place);
1302     a.swap(b);
1303   }
1304 
1305   EXPECT_EQ(1, listener.construct0);
1306   EXPECT_EQ(1, listener.move);
1307   EXPECT_EQ(2, listener.destruct);
1308 
1309   {
1310     absl::optional<Listenable> a(absl::in_place);
1311     absl::optional<Listenable> b;
1312     a.swap(b);
1313   }
1314 
1315   EXPECT_EQ(2, listener.construct0);
1316   EXPECT_EQ(2, listener.move);
1317   EXPECT_EQ(4, listener.destruct);
1318 }
1319 
TEST(optionalTest,BigStringLeakCheck)1320 TEST(optionalTest, BigStringLeakCheck) {
1321   constexpr size_t n = 1 << 16;
1322 
1323   using OS = absl::optional<std::string>;
1324 
1325   OS a;
1326   OS b = absl::nullopt;
1327   OS c = std::string(n, 'c');
1328   std::string sd(n, 'd');
1329   OS d = sd;
1330   OS e(absl::in_place, n, 'e');
1331   OS f;
1332   f.emplace(n, 'f');
1333 
1334   OS ca(a);
1335   OS cb(b);
1336   OS cc(c);
1337   OS cd(d);
1338   OS ce(e);
1339 
1340   OS oa;
1341   OS ob = absl::nullopt;
1342   OS oc = std::string(n, 'c');
1343   std::string sod(n, 'd');
1344   OS od = sod;
1345   OS oe(absl::in_place, n, 'e');
1346   OS of;
1347   of.emplace(n, 'f');
1348 
1349   OS ma(std::move(oa));
1350   OS mb(std::move(ob));
1351   OS mc(std::move(oc));
1352   OS md(std::move(od));
1353   OS me(std::move(oe));
1354   OS mf(std::move(of));
1355 
1356   OS aa1;
1357   OS ab1 = absl::nullopt;
1358   OS ac1 = std::string(n, 'c');
1359   std::string sad1(n, 'd');
1360   OS ad1 = sad1;
1361   OS ae1(absl::in_place, n, 'e');
1362   OS af1;
1363   af1.emplace(n, 'f');
1364 
1365   OS aa2;
1366   OS ab2 = absl::nullopt;
1367   OS ac2 = std::string(n, 'c');
1368   std::string sad2(n, 'd');
1369   OS ad2 = sad2;
1370   OS ae2(absl::in_place, n, 'e');
1371   OS af2;
1372   af2.emplace(n, 'f');
1373 
1374   aa1 = af2;
1375   ab1 = ae2;
1376   ac1 = ad2;
1377   ad1 = ac2;
1378   ae1 = ab2;
1379   af1 = aa2;
1380 
1381   OS aa3;
1382   OS ab3 = absl::nullopt;
1383   OS ac3 = std::string(n, 'c');
1384   std::string sad3(n, 'd');
1385   OS ad3 = sad3;
1386   OS ae3(absl::in_place, n, 'e');
1387   OS af3;
1388   af3.emplace(n, 'f');
1389 
1390   aa3 = absl::nullopt;
1391   ab3 = absl::nullopt;
1392   ac3 = absl::nullopt;
1393   ad3 = absl::nullopt;
1394   ae3 = absl::nullopt;
1395   af3 = absl::nullopt;
1396 
1397   OS aa4;
1398   OS ab4 = absl::nullopt;
1399   OS ac4 = std::string(n, 'c');
1400   std::string sad4(n, 'd');
1401   OS ad4 = sad4;
1402   OS ae4(absl::in_place, n, 'e');
1403   OS af4;
1404   af4.emplace(n, 'f');
1405 
1406   aa4 = OS(absl::in_place, n, 'a');
1407   ab4 = OS(absl::in_place, n, 'b');
1408   ac4 = OS(absl::in_place, n, 'c');
1409   ad4 = OS(absl::in_place, n, 'd');
1410   ae4 = OS(absl::in_place, n, 'e');
1411   af4 = OS(absl::in_place, n, 'f');
1412 
1413   OS aa5;
1414   OS ab5 = absl::nullopt;
1415   OS ac5 = std::string(n, 'c');
1416   std::string sad5(n, 'd');
1417   OS ad5 = sad5;
1418   OS ae5(absl::in_place, n, 'e');
1419   OS af5;
1420   af5.emplace(n, 'f');
1421 
1422   std::string saa5(n, 'a');
1423   std::string sab5(n, 'a');
1424   std::string sac5(n, 'a');
1425   std::string sad52(n, 'a');
1426   std::string sae5(n, 'a');
1427   std::string saf5(n, 'a');
1428 
1429   aa5 = saa5;
1430   ab5 = sab5;
1431   ac5 = sac5;
1432   ad5 = sad52;
1433   ae5 = sae5;
1434   af5 = saf5;
1435 
1436   OS aa6;
1437   OS ab6 = absl::nullopt;
1438   OS ac6 = std::string(n, 'c');
1439   std::string sad6(n, 'd');
1440   OS ad6 = sad6;
1441   OS ae6(absl::in_place, n, 'e');
1442   OS af6;
1443   af6.emplace(n, 'f');
1444 
1445   aa6 = std::string(n, 'a');
1446   ab6 = std::string(n, 'b');
1447   ac6 = std::string(n, 'c');
1448   ad6 = std::string(n, 'd');
1449   ae6 = std::string(n, 'e');
1450   af6 = std::string(n, 'f');
1451 
1452   OS aa7;
1453   OS ab7 = absl::nullopt;
1454   OS ac7 = std::string(n, 'c');
1455   std::string sad7(n, 'd');
1456   OS ad7 = sad7;
1457   OS ae7(absl::in_place, n, 'e');
1458   OS af7;
1459   af7.emplace(n, 'f');
1460 
1461   aa7.emplace(n, 'A');
1462   ab7.emplace(n, 'B');
1463   ac7.emplace(n, 'C');
1464   ad7.emplace(n, 'D');
1465   ae7.emplace(n, 'E');
1466   af7.emplace(n, 'F');
1467 }
1468 
TEST(optionalTest,MoveAssignRegression)1469 TEST(optionalTest, MoveAssignRegression) {
1470   StructorListener listener;
1471   Listenable::listener = &listener;
1472 
1473   {
1474     absl::optional<Listenable> a;
1475     Listenable b;
1476     a = std::move(b);
1477   }
1478 
1479   EXPECT_EQ(1, listener.construct0);
1480   EXPECT_EQ(1, listener.move);
1481   EXPECT_EQ(2, listener.destruct);
1482 }
1483 
TEST(optionalTest,ValueType)1484 TEST(optionalTest, ValueType) {
1485   EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value));
1486   EXPECT_TRUE((std::is_same<absl::optional<std::string>::value_type,
1487                             std::string>::value));
1488   EXPECT_FALSE(
1489       (std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value));
1490 }
1491 
1492 template <typename T>
1493 struct is_hash_enabled_for {
1494   template <typename U, typename = decltype(std::hash<U>()(std::declval<U>()))>
1495   static std::true_type test(int);
1496 
1497   template <typename U>
1498   static std::false_type test(...);
1499 
1500   static constexpr bool value = decltype(test<T>(0))::value;
1501 };
1502 
TEST(optionalTest,Hash)1503 TEST(optionalTest, Hash) {
1504   std::hash<absl::optional<int>> hash;
1505   std::set<size_t> hashcodes;
1506   hashcodes.insert(hash(absl::nullopt));
1507   for (int i = 0; i < 100; ++i) {
1508     hashcodes.insert(hash(i));
1509   }
1510   EXPECT_GT(hashcodes.size(), 90);
1511 
1512   static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");
1513   static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");
1514   static_assert(
1515       absl::type_traits_internal::IsHashable<absl::optional<int>>::value, "");
1516   static_assert(
1517       absl::type_traits_internal::IsHashable<absl::optional<Hashable>>::value,
1518       "");
1519   absl::type_traits_internal::AssertHashEnabled<absl::optional<int>>();
1520   absl::type_traits_internal::AssertHashEnabled<absl::optional<Hashable>>();
1521 
1522 #if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
1523   static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, "");
1524   static_assert(!absl::type_traits_internal::IsHashable<
1525                     absl::optional<NonHashable>>::value,
1526                 "");
1527 #endif
1528 
1529   // libstdc++ std::optional is missing remove_const_t, i.e. it's using
1530   // std::hash<T> rather than std::hash<std::remove_const_t<T>>.
1531   // Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262
1532 #ifndef __GLIBCXX__
1533   static_assert(is_hash_enabled_for<absl::optional<const int>>::value, "");
1534   static_assert(is_hash_enabled_for<absl::optional<const Hashable>>::value, "");
1535   std::hash<absl::optional<const int>> c_hash;
1536   for (int i = 0; i < 100; ++i) {
1537     EXPECT_EQ(hash(i), c_hash(i));
1538   }
1539 #endif
1540 }
1541 
1542 struct MoveMeNoThrow {
MoveMeNoThrow__anon565f22760111::MoveMeNoThrow1543   MoveMeNoThrow() : x(0) {}
MoveMeNoThrow__anon565f22760111::MoveMeNoThrow1544   [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
1545     ABSL_RAW_LOG(FATAL, "Should not be called.");
1546     abort();
1547   }
MoveMeNoThrow__anon565f22760111::MoveMeNoThrow1548   MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
1549   int x;
1550 };
1551 
1552 struct MoveMeThrow {
MoveMeThrow__anon565f22760111::MoveMeThrow1553   MoveMeThrow() : x(0) {}
MoveMeThrow__anon565f22760111::MoveMeThrow1554   MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}
MoveMeThrow__anon565f22760111::MoveMeThrow1555   MoveMeThrow(MoveMeThrow&& other) : x(other.x) {}
1556   int x;
1557 };
1558 
TEST(optionalTest,NoExcept)1559 TEST(optionalTest, NoExcept) {
1560   static_assert(
1561       std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value,
1562       "");
1563 #ifndef ABSL_USES_STD_OPTIONAL
1564   static_assert(absl::default_allocator_is_nothrow::value ==
1565                     std::is_nothrow_move_constructible<
1566                         absl::optional<MoveMeThrow>>::value,
1567                 "");
1568 #endif
1569   std::vector<absl::optional<MoveMeNoThrow>> v;
1570   for (int i = 0; i < 10; ++i) v.emplace_back();
1571 }
1572 
1573 struct AnyLike {
1574   AnyLike(AnyLike&&) = default;
1575   AnyLike(const AnyLike&) = default;
1576 
1577   template <typename ValueType,
1578             typename T = typename std::decay<ValueType>::type,
1579             typename std::enable_if<
1580                 !absl::disjunction<
1581                     std::is_same<AnyLike, T>,
1582                     absl::negation<std::is_copy_constructible<T>>>::value,
1583                 int>::type = 0>
AnyLike__anon565f22760111::AnyLike1584   AnyLike(ValueType&&) {}  // NOLINT(runtime/explicit)
1585 
1586   AnyLike& operator=(AnyLike&&) = default;
1587   AnyLike& operator=(const AnyLike&) = default;
1588 
1589   template <typename ValueType,
1590             typename T = typename std::decay<ValueType>::type>
1591   typename std::enable_if<
1592       absl::conjunction<absl::negation<std::is_same<AnyLike, T>>,
1593                         std::is_copy_constructible<T>>::value,
1594       AnyLike&>::type
operator =__anon565f22760111::AnyLike1595   operator=(ValueType&& /* rhs */) {
1596     return *this;
1597   }
1598 };
1599 
TEST(optionalTest,ConstructionConstraints)1600 TEST(optionalTest, ConstructionConstraints) {
1601   EXPECT_TRUE((std::is_constructible<AnyLike, absl::optional<AnyLike>>::value));
1602 
1603   EXPECT_TRUE(
1604       (std::is_constructible<AnyLike, const absl::optional<AnyLike>&>::value));
1605 
1606   EXPECT_TRUE((std::is_constructible<absl::optional<AnyLike>, AnyLike>::value));
1607   EXPECT_TRUE(
1608       (std::is_constructible<absl::optional<AnyLike>, const AnyLike&>::value));
1609 
1610   EXPECT_TRUE((std::is_convertible<absl::optional<AnyLike>, AnyLike>::value));
1611 
1612   EXPECT_TRUE(
1613       (std::is_convertible<const absl::optional<AnyLike>&, AnyLike>::value));
1614 
1615   EXPECT_TRUE((std::is_convertible<AnyLike, absl::optional<AnyLike>>::value));
1616   EXPECT_TRUE(
1617       (std::is_convertible<const AnyLike&, absl::optional<AnyLike>>::value));
1618 
1619   EXPECT_TRUE(std::is_move_constructible<absl::optional<AnyLike>>::value);
1620   EXPECT_TRUE(std::is_copy_constructible<absl::optional<AnyLike>>::value);
1621 }
1622 
TEST(optionalTest,AssignmentConstraints)1623 TEST(optionalTest, AssignmentConstraints) {
1624   EXPECT_TRUE((std::is_assignable<AnyLike&, absl::optional<AnyLike>>::value));
1625   EXPECT_TRUE(
1626       (std::is_assignable<AnyLike&, const absl::optional<AnyLike>&>::value));
1627   EXPECT_TRUE((std::is_assignable<absl::optional<AnyLike>&, AnyLike>::value));
1628   EXPECT_TRUE(
1629       (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value));
1630   EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value);
1631   EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
1632 }
1633 
1634 #if !defined(__EMSCRIPTEN__)
1635 struct NestedClassBug {
1636   struct Inner {
1637     bool dummy = false;
1638   };
1639   absl::optional<Inner> value;
1640 };
1641 
TEST(optionalTest,InPlaceTSFINAEBug)1642 TEST(optionalTest, InPlaceTSFINAEBug) {
1643   NestedClassBug b;
1644   ((void)b);
1645   using Inner = NestedClassBug::Inner;
1646 
1647   EXPECT_TRUE((std::is_default_constructible<Inner>::value));
1648   EXPECT_TRUE((std::is_constructible<Inner>::value));
1649   EXPECT_TRUE(
1650       (std::is_constructible<absl::optional<Inner>, absl::in_place_t>::value));
1651 
1652   absl::optional<Inner> o(absl::in_place);
1653   EXPECT_TRUE(o.has_value());
1654   o.emplace();
1655   EXPECT_TRUE(o.has_value());
1656 }
1657 #endif  // !defined(__EMSCRIPTEN__)
1658 
1659 }  // namespace
1660 
1661 #endif  // #if !defined(ABSL_USES_STD_OPTIONAL)
1662