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


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:19