optional_test.cc
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "absl/types/optional.h"
00016 
00017 #include <string>
00018 #include <type_traits>
00019 #include <utility>
00020 
00021 #include "gtest/gtest.h"
00022 #include "absl/base/config.h"
00023 #include "absl/base/internal/raw_logging.h"
00024 #include "absl/meta/type_traits.h"
00025 #include "absl/strings/string_view.h"
00026 
00027 struct Hashable {};
00028 
00029 namespace std {
00030 template <>
00031 struct hash<Hashable> {
00032   size_t operator()(const Hashable&) { return 0; }
00033 };
00034 }  // namespace std
00035 
00036 struct NonHashable {};
00037 
00038 namespace {
00039 
00040 std::string TypeQuals(std::string&) { return "&"; }
00041 std::string TypeQuals(std::string&&) { return "&&"; }
00042 std::string TypeQuals(const std::string&) { return "c&"; }
00043 std::string TypeQuals(const std::string&&) { return "c&&"; }
00044 
00045 struct StructorListener {
00046   int construct0 = 0;
00047   int construct1 = 0;
00048   int construct2 = 0;
00049   int listinit = 0;
00050   int copy = 0;
00051   int move = 0;
00052   int copy_assign = 0;
00053   int move_assign = 0;
00054   int destruct = 0;
00055   int volatile_copy = 0;
00056   int volatile_move = 0;
00057   int volatile_copy_assign = 0;
00058   int volatile_move_assign = 0;
00059 };
00060 
00061 // Suppress MSVC warnings.
00062 // 4521: multiple copy constructors specified
00063 // 4522: multiple assignment operators specified
00064 // We wrote multiple of them to test that the correct overloads are selected.
00065 #ifdef _MSC_VER
00066 #pragma warning( push )
00067 #pragma warning( disable : 4521)
00068 #pragma warning( disable : 4522)
00069 #endif
00070 struct Listenable {
00071   static StructorListener* listener;
00072 
00073   Listenable() { ++listener->construct0; }
00074   explicit Listenable(int /*unused*/) { ++listener->construct1; }
00075   Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }
00076   Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }
00077   Listenable(const Listenable& /*unused*/) { ++listener->copy; }
00078   Listenable(const volatile Listenable& /*unused*/) {
00079     ++listener->volatile_copy;
00080   }
00081   Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; }
00082   Listenable(Listenable&& /*unused*/) { ++listener->move; }
00083   Listenable& operator=(const Listenable& /*unused*/) {
00084     ++listener->copy_assign;
00085     return *this;
00086   }
00087   Listenable& operator=(Listenable&& /*unused*/) {
00088     ++listener->move_assign;
00089     return *this;
00090   }
00091   // use void return type instead of volatile T& to work around GCC warning
00092   // when the assignment's returned reference is ignored.
00093   void operator=(const volatile Listenable& /*unused*/) volatile {
00094     ++listener->volatile_copy_assign;
00095   }
00096   void operator=(volatile Listenable&& /*unused*/) volatile {
00097     ++listener->volatile_move_assign;
00098   }
00099   ~Listenable() { ++listener->destruct; }
00100 };
00101 #ifdef _MSC_VER
00102 #pragma warning( pop )
00103 #endif
00104 
00105 StructorListener* Listenable::listener = nullptr;
00106 
00107 // ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST is defined to 1 when the standard
00108 // library implementation doesn't marked initializer_list's default constructor
00109 // constexpr. The C++11 standard doesn't specify constexpr on it, but C++14
00110 // added it. However, libstdc++ 4.7 marked it constexpr.
00111 #if defined(_LIBCPP_VERSION) && \
00112     (_LIBCPP_STD_VER <= 11 || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR))
00113 #define ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST 1
00114 #endif
00115 
00116 struct ConstexprType {
00117   enum CtorTypes {
00118     kCtorDefault,
00119     kCtorInt,
00120     kCtorInitializerList,
00121     kCtorConstChar
00122   };
00123   constexpr ConstexprType() : x(kCtorDefault) {}
00124   constexpr explicit ConstexprType(int i) : x(kCtorInt) {}
00125 #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
00126   constexpr ConstexprType(std::initializer_list<int> il)
00127       : x(kCtorInitializerList) {}
00128 #endif
00129   constexpr ConstexprType(const char*)  // NOLINT(runtime/explicit)
00130       : x(kCtorConstChar) {}
00131   int x;
00132 };
00133 
00134 struct Copyable {
00135   Copyable() {}
00136   Copyable(const Copyable&) {}
00137   Copyable& operator=(const Copyable&) { return *this; }
00138 };
00139 
00140 struct MoveableThrow {
00141   MoveableThrow() {}
00142   MoveableThrow(MoveableThrow&&) {}
00143   MoveableThrow& operator=(MoveableThrow&&) { return *this; }
00144 };
00145 
00146 struct MoveableNoThrow {
00147   MoveableNoThrow() {}
00148   MoveableNoThrow(MoveableNoThrow&&) noexcept {}
00149   MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }
00150 };
00151 
00152 struct NonMovable {
00153   NonMovable() {}
00154   NonMovable(const NonMovable&) = delete;
00155   NonMovable& operator=(const NonMovable&) = delete;
00156   NonMovable(NonMovable&&) = delete;
00157   NonMovable& operator=(NonMovable&&) = delete;
00158 };
00159 
00160 struct NoDefault {
00161   NoDefault() = delete;
00162   NoDefault(const NoDefault&) {}
00163   NoDefault& operator=(const NoDefault&) { return *this; }
00164 };
00165 
00166 struct ConvertsFromInPlaceT {
00167   ConvertsFromInPlaceT(absl::in_place_t) {}  // NOLINT
00168 };
00169 
00170 TEST(optionalTest, DefaultConstructor) {
00171   absl::optional<int> empty;
00172   EXPECT_FALSE(empty);
00173   constexpr absl::optional<int> cempty;
00174   static_assert(!cempty.has_value(), "");
00175   EXPECT_TRUE(
00176       std::is_nothrow_default_constructible<absl::optional<int>>::value);
00177 }
00178 
00179 TEST(optionalTest, nulloptConstructor) {
00180   absl::optional<int> empty(absl::nullopt);
00181   EXPECT_FALSE(empty);
00182   constexpr absl::optional<int> cempty{absl::nullopt};
00183   static_assert(!cempty.has_value(), "");
00184   EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>,
00185                                              absl::nullopt_t>::value));
00186 }
00187 
00188 TEST(optionalTest, CopyConstructor) {
00189   {
00190     absl::optional<int> empty, opt42 = 42;
00191     absl::optional<int> empty_copy(empty);
00192     EXPECT_FALSE(empty_copy);
00193     absl::optional<int> opt42_copy(opt42);
00194     EXPECT_TRUE(opt42_copy);
00195     EXPECT_EQ(42, *opt42_copy);
00196   }
00197   {
00198     absl::optional<const int> empty, opt42 = 42;
00199     absl::optional<const int> empty_copy(empty);
00200     EXPECT_FALSE(empty_copy);
00201     absl::optional<const int> opt42_copy(opt42);
00202     EXPECT_TRUE(opt42_copy);
00203     EXPECT_EQ(42, *opt42_copy);
00204   }
00205   {
00206     absl::optional<volatile int> empty, opt42 = 42;
00207     absl::optional<volatile int> empty_copy(empty);
00208     EXPECT_FALSE(empty_copy);
00209     absl::optional<volatile int> opt42_copy(opt42);
00210     EXPECT_TRUE(opt42_copy);
00211     EXPECT_EQ(42, *opt42_copy);
00212   }
00213   // test copyablility
00214   EXPECT_TRUE(std::is_copy_constructible<absl::optional<int>>::value);
00215   EXPECT_TRUE(std::is_copy_constructible<absl::optional<Copyable>>::value);
00216   EXPECT_FALSE(
00217       std::is_copy_constructible<absl::optional<MoveableThrow>>::value);
00218   EXPECT_FALSE(
00219       std::is_copy_constructible<absl::optional<MoveableNoThrow>>::value);
00220   EXPECT_FALSE(std::is_copy_constructible<absl::optional<NonMovable>>::value);
00221 
00222   EXPECT_FALSE(
00223       absl::is_trivially_copy_constructible<absl::optional<Copyable>>::value);
00224 #if defined(ABSL_HAVE_STD_OPTIONAL) && defined(__GLIBCXX__)
00225   // libstdc++ std::optional implementation (as of 7.2) has a bug: when T is
00226   // trivially copyable, optional<T> is not trivially copyable (due to one of
00227   // its base class is unconditionally nontrivial).
00228 #define ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG 1
00229 #endif
00230 #ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
00231   EXPECT_TRUE(
00232       absl::is_trivially_copy_constructible<absl::optional<int>>::value);
00233   EXPECT_TRUE(
00234       absl::is_trivially_copy_constructible<absl::optional<const int>>::value);
00235 #ifndef _MSC_VER
00236   // See defect report "Trivial copy/move constructor for class with volatile
00237   // member" at
00238   // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094
00239   // A class with non-static data member of volatile-qualified type should still
00240   // have a trivial copy constructor if the data member is trivial.
00241   // Also a cv-qualified scalar type should be trivially copyable.
00242   EXPECT_TRUE(absl::is_trivially_copy_constructible<
00243               absl::optional<volatile int>>::value);
00244 #endif  // _MSC_VER
00245 #endif  // ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
00246 
00247   // constexpr copy constructor for trivially copyable types
00248   {
00249     constexpr absl::optional<int> o1;
00250     constexpr absl::optional<int> o2 = o1;
00251     static_assert(!o2, "");
00252   }
00253   {
00254     constexpr absl::optional<int> o1 = 42;
00255     constexpr absl::optional<int> o2 = o1;
00256     static_assert(o2, "");
00257     static_assert(*o2 == 42, "");
00258   }
00259   {
00260     struct TrivialCopyable {
00261       constexpr TrivialCopyable() : x(0) {}
00262       constexpr explicit TrivialCopyable(int i) : x(i) {}
00263       int x;
00264     };
00265     constexpr absl::optional<TrivialCopyable> o1(42);
00266     constexpr absl::optional<TrivialCopyable> o2 = o1;
00267     static_assert(o2, "");
00268     static_assert((*o2).x == 42, "");
00269 #ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
00270     EXPECT_TRUE(absl::is_trivially_copy_constructible<
00271                 absl::optional<TrivialCopyable>>::value);
00272     EXPECT_TRUE(absl::is_trivially_copy_constructible<
00273                 absl::optional<const TrivialCopyable>>::value);
00274 #endif
00275     // When testing with VS 2017 15.3, there seems to be a bug in MSVC
00276     // std::optional when T is volatile-qualified. So skipping this test.
00277     // Bug report:
00278     // https://connect.microsoft.com/VisualStudio/feedback/details/3142534
00279 #if defined(ABSL_HAVE_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911
00280 #define ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG 1
00281 #endif
00282 #ifndef ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG
00283     EXPECT_FALSE(std::is_copy_constructible<
00284                  absl::optional<volatile TrivialCopyable>>::value);
00285 #endif
00286   }
00287 }
00288 
00289 TEST(optionalTest, MoveConstructor) {
00290   absl::optional<int> empty, opt42 = 42;
00291   absl::optional<int> empty_move(std::move(empty));
00292   EXPECT_FALSE(empty_move);
00293   absl::optional<int> opt42_move(std::move(opt42));
00294   EXPECT_TRUE(opt42_move);
00295   EXPECT_EQ(42, opt42_move);
00296   // test movability
00297   EXPECT_TRUE(std::is_move_constructible<absl::optional<int>>::value);
00298   EXPECT_TRUE(std::is_move_constructible<absl::optional<Copyable>>::value);
00299   EXPECT_TRUE(std::is_move_constructible<absl::optional<MoveableThrow>>::value);
00300   EXPECT_TRUE(
00301       std::is_move_constructible<absl::optional<MoveableNoThrow>>::value);
00302   EXPECT_FALSE(std::is_move_constructible<absl::optional<NonMovable>>::value);
00303   // test noexcept
00304   EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value);
00305 #ifndef ABSL_HAVE_STD_OPTIONAL
00306   EXPECT_EQ(
00307       absl::default_allocator_is_nothrow::value,
00308       std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value);
00309 #endif
00310   EXPECT_TRUE(std::is_nothrow_move_constructible<
00311               absl::optional<MoveableNoThrow>>::value);
00312 }
00313 
00314 TEST(optionalTest, Destructor) {
00315   struct Trivial {};
00316 
00317   struct NonTrivial {
00318     NonTrivial(const NonTrivial&) {}
00319     NonTrivial& operator=(const NonTrivial&) { return *this; }
00320     ~NonTrivial() {}
00321   };
00322 
00323   EXPECT_TRUE(std::is_trivially_destructible<absl::optional<int>>::value);
00324   EXPECT_TRUE(std::is_trivially_destructible<absl::optional<Trivial>>::value);
00325   EXPECT_FALSE(
00326       std::is_trivially_destructible<absl::optional<NonTrivial>>::value);
00327 }
00328 
00329 TEST(optionalTest, InPlaceConstructor) {
00330   constexpr absl::optional<ConstexprType> opt0{absl::in_place_t()};
00331   static_assert(opt0, "");
00332   static_assert((*opt0).x == ConstexprType::kCtorDefault, "");
00333   constexpr absl::optional<ConstexprType> opt1{absl::in_place_t(), 1};
00334   static_assert(opt1, "");
00335   static_assert((*opt1).x == ConstexprType::kCtorInt, "");
00336 #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
00337   constexpr absl::optional<ConstexprType> opt2{absl::in_place_t(), {1, 2}};
00338   static_assert(opt2, "");
00339   static_assert((*opt2).x == ConstexprType::kCtorInitializerList, "");
00340 #endif
00341 
00342   EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
00343                                       absl::in_place_t>::value));
00344   EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
00345                                       const absl::in_place_t&>::value));
00346   EXPECT_TRUE(
00347       (std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
00348                              absl::in_place_t, absl::in_place_t>::value));
00349 
00350   EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
00351                                       absl::in_place_t>::value));
00352   EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
00353                                       absl::in_place_t&&>::value));
00354 }
00355 
00356 // template<U=T> optional(U&&);
00357 TEST(optionalTest, ValueConstructor) {
00358   constexpr absl::optional<int> opt0(0);
00359   static_assert(opt0, "");
00360   static_assert(*opt0 == 0, "");
00361   EXPECT_TRUE((std::is_convertible<int, absl::optional<int>>::value));
00362   // Copy initialization ( = "abc") won't work due to optional(optional&&)
00363   // is not constexpr. Use list initialization instead. This invokes
00364   // absl::optional<ConstexprType>::absl::optional<U>(U&&), with U = const char
00365   // (&) [4], which direct-initializes the ConstexprType value held by the
00366   // optional via ConstexprType::ConstexprType(const char*).
00367   constexpr absl::optional<ConstexprType> opt1 = {"abc"};
00368   static_assert(opt1, "");
00369   static_assert(ConstexprType::kCtorConstChar == (*opt1).x, "");
00370   EXPECT_TRUE(
00371       (std::is_convertible<const char*, absl::optional<ConstexprType>>::value));
00372   // direct initialization
00373   constexpr absl::optional<ConstexprType> opt2{2};
00374   static_assert(opt2, "");
00375   static_assert(ConstexprType::kCtorInt == (*opt2).x, "");
00376   EXPECT_FALSE(
00377       (std::is_convertible<int, absl::optional<ConstexprType>>::value));
00378 
00379   // this invokes absl::optional<int>::optional(int&&)
00380   // NOTE: this has different behavior than assignment, e.g.
00381   // "opt3 = {};" clears the optional rather than setting the value to 0
00382   // According to C++17 standard N4659 [over.ics.list] 16.3.3.1.5, (9.2)- "if
00383   // the initializer list has no elements, the implicit conversion is the
00384   // identity conversion", so `optional(int&&)` should be a better match than
00385   // `optional(optional&&)` which is a user-defined conversion.
00386   // Note: GCC 7 has a bug with this overload selection when compiled with
00387   // `-std=c++17`.
00388 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7 && \
00389     __cplusplus == 201703L
00390 #define ABSL_GCC7_OVER_ICS_LIST_BUG 1
00391 #endif
00392 #ifndef ABSL_GCC7_OVER_ICS_LIST_BUG
00393   constexpr absl::optional<int> opt3({});
00394   static_assert(opt3, "");
00395   static_assert(*opt3 == 0, "");
00396 #endif
00397 
00398   // this invokes the move constructor with a default constructed optional
00399   // because non-template function is a better match than template function.
00400   absl::optional<ConstexprType> opt4({});
00401   EXPECT_FALSE(opt4);
00402 }
00403 
00404 struct Implicit {};
00405 
00406 struct Explicit {};
00407 
00408 struct Convert {
00409   Convert(const Implicit&)  // NOLINT(runtime/explicit)
00410       : implicit(true), move(false) {}
00411   Convert(Implicit&&)  // NOLINT(runtime/explicit)
00412       : implicit(true), move(true) {}
00413   explicit Convert(const Explicit&) : implicit(false), move(false) {}
00414   explicit Convert(Explicit&&) : implicit(false), move(true) {}
00415 
00416   bool implicit;
00417   bool move;
00418 };
00419 
00420 struct ConvertFromOptional {
00421   ConvertFromOptional(const Implicit&)  // NOLINT(runtime/explicit)
00422       : implicit(true), move(false), from_optional(false) {}
00423   ConvertFromOptional(Implicit&&)  // NOLINT(runtime/explicit)
00424       : implicit(true), move(true), from_optional(false) {}
00425   ConvertFromOptional(
00426       const absl::optional<Implicit>&)  // NOLINT(runtime/explicit)
00427       : implicit(true), move(false), from_optional(true) {}
00428   ConvertFromOptional(absl::optional<Implicit>&&)  // NOLINT(runtime/explicit)
00429       : implicit(true), move(true), from_optional(true) {}
00430   explicit ConvertFromOptional(const Explicit&)
00431       : implicit(false), move(false), from_optional(false) {}
00432   explicit ConvertFromOptional(Explicit&&)
00433       : implicit(false), move(true), from_optional(false) {}
00434   explicit ConvertFromOptional(const absl::optional<Explicit>&)
00435       : implicit(false), move(false), from_optional(true) {}
00436   explicit ConvertFromOptional(absl::optional<Explicit>&&)
00437       : implicit(false), move(true), from_optional(true) {}
00438 
00439   bool implicit;
00440   bool move;
00441   bool from_optional;
00442 };
00443 
00444 TEST(optionalTest, ConvertingConstructor) {
00445   absl::optional<Implicit> i_empty;
00446   absl::optional<Implicit> i(absl::in_place);
00447   absl::optional<Explicit> e_empty;
00448   absl::optional<Explicit> e(absl::in_place);
00449   {
00450     // implicitly constructing absl::optional<Convert> from
00451     // absl::optional<Implicit>
00452     absl::optional<Convert> empty = i_empty;
00453     EXPECT_FALSE(empty);
00454     absl::optional<Convert> opt_copy = i;
00455     EXPECT_TRUE(opt_copy);
00456     EXPECT_TRUE(opt_copy->implicit);
00457     EXPECT_FALSE(opt_copy->move);
00458     absl::optional<Convert> opt_move = absl::optional<Implicit>(absl::in_place);
00459     EXPECT_TRUE(opt_move);
00460     EXPECT_TRUE(opt_move->implicit);
00461     EXPECT_TRUE(opt_move->move);
00462   }
00463   {
00464     // explicitly constructing absl::optional<Convert> from
00465     // absl::optional<Explicit>
00466     absl::optional<Convert> empty(e_empty);
00467     EXPECT_FALSE(empty);
00468     absl::optional<Convert> opt_copy(e);
00469     EXPECT_TRUE(opt_copy);
00470     EXPECT_FALSE(opt_copy->implicit);
00471     EXPECT_FALSE(opt_copy->move);
00472     EXPECT_FALSE((std::is_convertible<const absl::optional<Explicit>&,
00473                                       absl::optional<Convert>>::value));
00474     absl::optional<Convert> opt_move{absl::optional<Explicit>(absl::in_place)};
00475     EXPECT_TRUE(opt_move);
00476     EXPECT_FALSE(opt_move->implicit);
00477     EXPECT_TRUE(opt_move->move);
00478     EXPECT_FALSE((std::is_convertible<absl::optional<Explicit>&&,
00479                                       absl::optional<Convert>>::value));
00480   }
00481   {
00482     // implicitly constructing absl::optional<ConvertFromOptional> from
00483     // absl::optional<Implicit> via
00484     // ConvertFromOptional(absl::optional<Implicit>&&) check that
00485     // ConvertFromOptional(Implicit&&) is NOT called
00486     static_assert(
00487         std::is_convertible<absl::optional<Implicit>,
00488                             absl::optional<ConvertFromOptional>>::value,
00489         "");
00490     absl::optional<ConvertFromOptional> opt0 = i_empty;
00491     EXPECT_TRUE(opt0);
00492     EXPECT_TRUE(opt0->implicit);
00493     EXPECT_FALSE(opt0->move);
00494     EXPECT_TRUE(opt0->from_optional);
00495     absl::optional<ConvertFromOptional> opt1 = absl::optional<Implicit>();
00496     EXPECT_TRUE(opt1);
00497     EXPECT_TRUE(opt1->implicit);
00498     EXPECT_TRUE(opt1->move);
00499     EXPECT_TRUE(opt1->from_optional);
00500   }
00501   {
00502     // implicitly constructing absl::optional<ConvertFromOptional> from
00503     // absl::optional<Explicit> via
00504     // ConvertFromOptional(absl::optional<Explicit>&&) check that
00505     // ConvertFromOptional(Explicit&&) is NOT called
00506     absl::optional<ConvertFromOptional> opt0(e_empty);
00507     EXPECT_TRUE(opt0);
00508     EXPECT_FALSE(opt0->implicit);
00509     EXPECT_FALSE(opt0->move);
00510     EXPECT_TRUE(opt0->from_optional);
00511     EXPECT_FALSE(
00512         (std::is_convertible<const absl::optional<Explicit>&,
00513                              absl::optional<ConvertFromOptional>>::value));
00514     absl::optional<ConvertFromOptional> opt1{absl::optional<Explicit>()};
00515     EXPECT_TRUE(opt1);
00516     EXPECT_FALSE(opt1->implicit);
00517     EXPECT_TRUE(opt1->move);
00518     EXPECT_TRUE(opt1->from_optional);
00519     EXPECT_FALSE(
00520         (std::is_convertible<absl::optional<Explicit>&&,
00521                              absl::optional<ConvertFromOptional>>::value));
00522   }
00523 }
00524 
00525 TEST(optionalTest, StructorBasic) {
00526   StructorListener listener;
00527   Listenable::listener = &listener;
00528   {
00529     absl::optional<Listenable> empty;
00530     EXPECT_FALSE(empty);
00531     absl::optional<Listenable> opt0(absl::in_place);
00532     EXPECT_TRUE(opt0);
00533     absl::optional<Listenable> opt1(absl::in_place, 1);
00534     EXPECT_TRUE(opt1);
00535     absl::optional<Listenable> opt2(absl::in_place, 1, 2);
00536     EXPECT_TRUE(opt2);
00537   }
00538   EXPECT_EQ(1, listener.construct0);
00539   EXPECT_EQ(1, listener.construct1);
00540   EXPECT_EQ(1, listener.construct2);
00541   EXPECT_EQ(3, listener.destruct);
00542 }
00543 
00544 TEST(optionalTest, CopyMoveStructor) {
00545   StructorListener listener;
00546   Listenable::listener = &listener;
00547   absl::optional<Listenable> original(absl::in_place);
00548   EXPECT_EQ(1, listener.construct0);
00549   EXPECT_EQ(0, listener.copy);
00550   EXPECT_EQ(0, listener.move);
00551   absl::optional<Listenable> copy(original);
00552   EXPECT_EQ(1, listener.construct0);
00553   EXPECT_EQ(1, listener.copy);
00554   EXPECT_EQ(0, listener.move);
00555   absl::optional<Listenable> move(std::move(original));
00556   EXPECT_EQ(1, listener.construct0);
00557   EXPECT_EQ(1, listener.copy);
00558   EXPECT_EQ(1, listener.move);
00559 }
00560 
00561 TEST(optionalTest, ListInit) {
00562   StructorListener listener;
00563   Listenable::listener = &listener;
00564   absl::optional<Listenable> listinit1(absl::in_place, {1});
00565   absl::optional<Listenable> listinit2(absl::in_place, {1, 2});
00566   EXPECT_EQ(2, listener.listinit);
00567 }
00568 
00569 TEST(optionalTest, AssignFromNullopt) {
00570   absl::optional<int> opt(1);
00571   opt = absl::nullopt;
00572   EXPECT_FALSE(opt);
00573 
00574   StructorListener listener;
00575   Listenable::listener = &listener;
00576   absl::optional<Listenable> opt1(absl::in_place);
00577   opt1 = absl::nullopt;
00578   EXPECT_FALSE(opt1);
00579   EXPECT_EQ(1, listener.construct0);
00580   EXPECT_EQ(1, listener.destruct);
00581 
00582   EXPECT_TRUE((
00583       std::is_nothrow_assignable<absl::optional<int>, absl::nullopt_t>::value));
00584   EXPECT_TRUE((std::is_nothrow_assignable<absl::optional<Listenable>,
00585                                           absl::nullopt_t>::value));
00586 }
00587 
00588 TEST(optionalTest, CopyAssignment) {
00589   const absl::optional<int> empty, opt1 = 1, opt2 = 2;
00590   absl::optional<int> empty_to_opt1, opt1_to_opt2, opt2_to_empty;
00591 
00592   EXPECT_FALSE(empty_to_opt1);
00593   empty_to_opt1 = empty;
00594   EXPECT_FALSE(empty_to_opt1);
00595   empty_to_opt1 = opt1;
00596   EXPECT_TRUE(empty_to_opt1);
00597   EXPECT_EQ(1, empty_to_opt1.value());
00598 
00599   EXPECT_FALSE(opt1_to_opt2);
00600   opt1_to_opt2 = opt1;
00601   EXPECT_TRUE(opt1_to_opt2);
00602   EXPECT_EQ(1, opt1_to_opt2.value());
00603   opt1_to_opt2 = opt2;
00604   EXPECT_TRUE(opt1_to_opt2);
00605   EXPECT_EQ(2, opt1_to_opt2.value());
00606 
00607   EXPECT_FALSE(opt2_to_empty);
00608   opt2_to_empty = opt2;
00609   EXPECT_TRUE(opt2_to_empty);
00610   EXPECT_EQ(2, opt2_to_empty.value());
00611   opt2_to_empty = empty;
00612   EXPECT_FALSE(opt2_to_empty);
00613 
00614   EXPECT_FALSE(absl::is_copy_assignable<absl::optional<const int>>::value);
00615   EXPECT_TRUE(absl::is_copy_assignable<absl::optional<Copyable>>::value);
00616   EXPECT_FALSE(absl::is_copy_assignable<absl::optional<MoveableThrow>>::value);
00617   EXPECT_FALSE(
00618       absl::is_copy_assignable<absl::optional<MoveableNoThrow>>::value);
00619   EXPECT_FALSE(absl::is_copy_assignable<absl::optional<NonMovable>>::value);
00620 
00621   EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value);
00622   EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value);
00623 
00624   struct Trivial {
00625     int i;
00626   };
00627   struct NonTrivial {
00628     NonTrivial& operator=(const NonTrivial&) { return *this; }
00629     int i;
00630   };
00631 
00632   EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
00633   EXPECT_FALSE(absl::is_copy_assignable<const Trivial>::value);
00634   EXPECT_FALSE(absl::is_copy_assignable<volatile Trivial>::value);
00635   EXPECT_TRUE(absl::is_copy_assignable<NonTrivial>::value);
00636   EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value);
00637 
00638   // std::optional doesn't support volatile nontrivial types.
00639 #ifndef ABSL_HAVE_STD_OPTIONAL
00640   {
00641     StructorListener listener;
00642     Listenable::listener = &listener;
00643 
00644     absl::optional<volatile Listenable> empty, set(absl::in_place);
00645     EXPECT_EQ(1, listener.construct0);
00646     absl::optional<volatile Listenable> empty_to_empty, empty_to_set,
00647         set_to_empty(absl::in_place), set_to_set(absl::in_place);
00648     EXPECT_EQ(3, listener.construct0);
00649     empty_to_empty = empty;  // no effect
00650     empty_to_set = set;      // copy construct
00651     set_to_empty = empty;    // destruct
00652     set_to_set = set;        // copy assign
00653     EXPECT_EQ(1, listener.volatile_copy);
00654     EXPECT_EQ(0, listener.volatile_move);
00655     EXPECT_EQ(1, listener.destruct);
00656     EXPECT_EQ(1, listener.volatile_copy_assign);
00657   }
00658 #endif  // ABSL_HAVE_STD_OPTIONAL
00659 }
00660 
00661 TEST(optionalTest, MoveAssignment) {
00662   {
00663     StructorListener listener;
00664     Listenable::listener = &listener;
00665 
00666     absl::optional<Listenable> empty1, empty2, set1(absl::in_place),
00667         set2(absl::in_place);
00668     EXPECT_EQ(2, listener.construct0);
00669     absl::optional<Listenable> empty_to_empty, empty_to_set,
00670         set_to_empty(absl::in_place), set_to_set(absl::in_place);
00671     EXPECT_EQ(4, listener.construct0);
00672     empty_to_empty = std::move(empty1);
00673     empty_to_set = std::move(set1);
00674     set_to_empty = std::move(empty2);
00675     set_to_set = std::move(set2);
00676     EXPECT_EQ(0, listener.copy);
00677     EXPECT_EQ(1, listener.move);
00678     EXPECT_EQ(1, listener.destruct);
00679     EXPECT_EQ(1, listener.move_assign);
00680   }
00681   // std::optional doesn't support volatile nontrivial types.
00682 #ifndef ABSL_HAVE_STD_OPTIONAL
00683   {
00684     StructorListener listener;
00685     Listenable::listener = &listener;
00686 
00687     absl::optional<volatile Listenable> empty1, empty2, set1(absl::in_place),
00688         set2(absl::in_place);
00689     EXPECT_EQ(2, listener.construct0);
00690     absl::optional<volatile Listenable> empty_to_empty, empty_to_set,
00691         set_to_empty(absl::in_place), set_to_set(absl::in_place);
00692     EXPECT_EQ(4, listener.construct0);
00693     empty_to_empty = std::move(empty1);  // no effect
00694     empty_to_set = std::move(set1);      // move construct
00695     set_to_empty = std::move(empty2);    // destruct
00696     set_to_set = std::move(set2);        // move assign
00697     EXPECT_EQ(0, listener.volatile_copy);
00698     EXPECT_EQ(1, listener.volatile_move);
00699     EXPECT_EQ(1, listener.destruct);
00700     EXPECT_EQ(1, listener.volatile_move_assign);
00701   }
00702 #endif  // ABSL_HAVE_STD_OPTIONAL
00703   EXPECT_FALSE(absl::is_move_assignable<absl::optional<const int>>::value);
00704   EXPECT_TRUE(absl::is_move_assignable<absl::optional<Copyable>>::value);
00705   EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableThrow>>::value);
00706   EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableNoThrow>>::value);
00707   EXPECT_FALSE(absl::is_move_assignable<absl::optional<NonMovable>>::value);
00708 
00709   EXPECT_FALSE(
00710       std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value);
00711   EXPECT_TRUE(
00712       std::is_nothrow_move_assignable<absl::optional<MoveableNoThrow>>::value);
00713 }
00714 
00715 struct NoConvertToOptional {
00716   // disable implicit conversion from const NoConvertToOptional&
00717   // to absl::optional<NoConvertToOptional>.
00718   NoConvertToOptional(const NoConvertToOptional&) = delete;
00719 };
00720 
00721 struct CopyConvert {
00722   CopyConvert(const NoConvertToOptional&);
00723   CopyConvert& operator=(const CopyConvert&) = delete;
00724   CopyConvert& operator=(const NoConvertToOptional&);
00725 };
00726 
00727 struct CopyConvertFromOptional {
00728   CopyConvertFromOptional(const NoConvertToOptional&);
00729   CopyConvertFromOptional(const absl::optional<NoConvertToOptional>&);
00730   CopyConvertFromOptional& operator=(const CopyConvertFromOptional&) = delete;
00731   CopyConvertFromOptional& operator=(const NoConvertToOptional&);
00732   CopyConvertFromOptional& operator=(
00733       const absl::optional<NoConvertToOptional>&);
00734 };
00735 
00736 struct MoveConvert {
00737   MoveConvert(NoConvertToOptional&&);
00738   MoveConvert& operator=(const MoveConvert&) = delete;
00739   MoveConvert& operator=(NoConvertToOptional&&);
00740 };
00741 
00742 struct MoveConvertFromOptional {
00743   MoveConvertFromOptional(NoConvertToOptional&&);
00744   MoveConvertFromOptional(absl::optional<NoConvertToOptional>&&);
00745   MoveConvertFromOptional& operator=(const MoveConvertFromOptional&) = delete;
00746   MoveConvertFromOptional& operator=(NoConvertToOptional&&);
00747   MoveConvertFromOptional& operator=(absl::optional<NoConvertToOptional>&&);
00748 };
00749 
00750 // template <typename U = T> absl::optional<T>& operator=(U&& v);
00751 TEST(optionalTest, ValueAssignment) {
00752   absl::optional<int> opt;
00753   EXPECT_FALSE(opt);
00754   opt = 42;
00755   EXPECT_TRUE(opt);
00756   EXPECT_EQ(42, opt.value());
00757   opt = absl::nullopt;
00758   EXPECT_FALSE(opt);
00759   opt = 42;
00760   EXPECT_TRUE(opt);
00761   EXPECT_EQ(42, opt.value());
00762   opt = 43;
00763   EXPECT_TRUE(opt);
00764   EXPECT_EQ(43, opt.value());
00765   opt = {};  // this should clear optional
00766   EXPECT_FALSE(opt);
00767 
00768   opt = {44};
00769   EXPECT_TRUE(opt);
00770   EXPECT_EQ(44, opt.value());
00771 
00772   // U = const NoConvertToOptional&
00773   EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvert>&,
00774                                   const NoConvertToOptional&>::value));
00775   // U = const absl::optional<NoConvertToOptional>&
00776   EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvertFromOptional>&,
00777                                   const NoConvertToOptional&>::value));
00778   // U = const NoConvertToOptional& triggers SFINAE because
00779   // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
00780   EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvert>&,
00781                                    const NoConvertToOptional&>::value));
00782   // U = NoConvertToOptional
00783   EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvert>&,
00784                                   NoConvertToOptional&&>::value));
00785   // U = const NoConvertToOptional& triggers SFINAE because
00786   // std::is_constructible_v<MoveConvertFromOptional, const
00787   // NoConvertToOptional&> is false
00788   EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,
00789                                    const NoConvertToOptional&>::value));
00790   // U = NoConvertToOptional
00791   EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,
00792                                   NoConvertToOptional&&>::value));
00793   // U = const absl::optional<NoConvertToOptional>&
00794   EXPECT_TRUE(
00795       (std::is_assignable<absl::optional<CopyConvertFromOptional>&,
00796                           const absl::optional<NoConvertToOptional>&>::value));
00797   // U = absl::optional<NoConvertToOptional>
00798   EXPECT_TRUE(
00799       (std::is_assignable<absl::optional<MoveConvertFromOptional>&,
00800                           absl::optional<NoConvertToOptional>&&>::value));
00801 }
00802 
00803 // template <typename U> absl::optional<T>& operator=(const absl::optional<U>&
00804 // rhs); template <typename U> absl::optional<T>& operator=(absl::optional<U>&&
00805 // rhs);
00806 TEST(optionalTest, ConvertingAssignment) {
00807   absl::optional<int> opt_i;
00808   absl::optional<char> opt_c('c');
00809   opt_i = opt_c;
00810   EXPECT_TRUE(opt_i);
00811   EXPECT_EQ(*opt_c, *opt_i);
00812   opt_i = absl::optional<char>();
00813   EXPECT_FALSE(opt_i);
00814   opt_i = absl::optional<char>('d');
00815   EXPECT_TRUE(opt_i);
00816   EXPECT_EQ('d', *opt_i);
00817 
00818   absl::optional<std::string> opt_str;
00819   absl::optional<const char*> opt_cstr("abc");
00820   opt_str = opt_cstr;
00821   EXPECT_TRUE(opt_str);
00822   EXPECT_EQ(std::string("abc"), *opt_str);
00823   opt_str = absl::optional<const char*>();
00824   EXPECT_FALSE(opt_str);
00825   opt_str = absl::optional<const char*>("def");
00826   EXPECT_TRUE(opt_str);
00827   EXPECT_EQ(std::string("def"), *opt_str);
00828 
00829   // operator=(const absl::optional<U>&) with U = NoConvertToOptional
00830   EXPECT_TRUE(
00831       (std::is_assignable<absl::optional<CopyConvert>,
00832                           const absl::optional<NoConvertToOptional>&>::value));
00833   // operator=(const absl::optional<U>&) with U = NoConvertToOptional
00834   // triggers SFINAE because
00835   // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
00836   EXPECT_FALSE(
00837       (std::is_assignable<absl::optional<MoveConvert>&,
00838                           const absl::optional<NoConvertToOptional>&>::value));
00839   // operator=(absl::optional<U>&&) with U = NoConvertToOptional
00840   EXPECT_TRUE(
00841       (std::is_assignable<absl::optional<MoveConvert>&,
00842                           absl::optional<NoConvertToOptional>&&>::value));
00843   // operator=(const absl::optional<U>&) with U = NoConvertToOptional triggers
00844   // SFINAE because std::is_constructible_v<MoveConvertFromOptional, const
00845   // NoConvertToOptional&> is false. operator=(U&&) with U = const
00846   // absl::optional<NoConverToOptional>& triggers SFINAE because
00847   // std::is_constructible<MoveConvertFromOptional,
00848   // absl::optional<NoConvertToOptional>&&> is true.
00849   EXPECT_FALSE(
00850       (std::is_assignable<absl::optional<MoveConvertFromOptional>&,
00851                           const absl::optional<NoConvertToOptional>&>::value));
00852 }
00853 
00854 TEST(optionalTest, ResetAndHasValue) {
00855   StructorListener listener;
00856   Listenable::listener = &listener;
00857   absl::optional<Listenable> opt;
00858   EXPECT_FALSE(opt);
00859   EXPECT_FALSE(opt.has_value());
00860   opt.emplace();
00861   EXPECT_TRUE(opt);
00862   EXPECT_TRUE(opt.has_value());
00863   opt.reset();
00864   EXPECT_FALSE(opt);
00865   EXPECT_FALSE(opt.has_value());
00866   EXPECT_EQ(1, listener.destruct);
00867   opt.reset();
00868   EXPECT_FALSE(opt);
00869   EXPECT_FALSE(opt.has_value());
00870 
00871   constexpr absl::optional<int> empty;
00872   static_assert(!empty.has_value(), "");
00873   constexpr absl::optional<int> nonempty(1);
00874   static_assert(nonempty.has_value(), "");
00875 }
00876 
00877 TEST(optionalTest, Emplace) {
00878   StructorListener listener;
00879   Listenable::listener = &listener;
00880   absl::optional<Listenable> opt;
00881   EXPECT_FALSE(opt);
00882   opt.emplace(1);
00883   EXPECT_TRUE(opt);
00884   opt.emplace(1, 2);
00885   EXPECT_EQ(1, listener.construct1);
00886   EXPECT_EQ(1, listener.construct2);
00887   EXPECT_EQ(1, listener.destruct);
00888 
00889   absl::optional<std::string> o;
00890   EXPECT_TRUE((std::is_same<std::string&, decltype(o.emplace("abc"))>::value));
00891   std::string& ref = o.emplace("abc");
00892   EXPECT_EQ(&ref, &o.value());
00893 }
00894 
00895 TEST(optionalTest, ListEmplace) {
00896   StructorListener listener;
00897   Listenable::listener = &listener;
00898   absl::optional<Listenable> opt;
00899   EXPECT_FALSE(opt);
00900   opt.emplace({1});
00901   EXPECT_TRUE(opt);
00902   opt.emplace({1, 2});
00903   EXPECT_EQ(2, listener.listinit);
00904   EXPECT_EQ(1, listener.destruct);
00905 
00906   absl::optional<Listenable> o;
00907   EXPECT_TRUE((std::is_same<Listenable&, decltype(o.emplace({1}))>::value));
00908   Listenable& ref = o.emplace({1});
00909   EXPECT_EQ(&ref, &o.value());
00910 }
00911 
00912 TEST(optionalTest, Swap) {
00913   absl::optional<int> opt_empty, opt1 = 1, opt2 = 2;
00914   EXPECT_FALSE(opt_empty);
00915   EXPECT_TRUE(opt1);
00916   EXPECT_EQ(1, opt1.value());
00917   EXPECT_TRUE(opt2);
00918   EXPECT_EQ(2, opt2.value());
00919   swap(opt_empty, opt1);
00920   EXPECT_FALSE(opt1);
00921   EXPECT_TRUE(opt_empty);
00922   EXPECT_EQ(1, opt_empty.value());
00923   EXPECT_TRUE(opt2);
00924   EXPECT_EQ(2, opt2.value());
00925   swap(opt_empty, opt1);
00926   EXPECT_FALSE(opt_empty);
00927   EXPECT_TRUE(opt1);
00928   EXPECT_EQ(1, opt1.value());
00929   EXPECT_TRUE(opt2);
00930   EXPECT_EQ(2, opt2.value());
00931   swap(opt1, opt2);
00932   EXPECT_FALSE(opt_empty);
00933   EXPECT_TRUE(opt1);
00934   EXPECT_EQ(2, opt1.value());
00935   EXPECT_TRUE(opt2);
00936   EXPECT_EQ(1, opt2.value());
00937 
00938   EXPECT_TRUE(noexcept(opt1.swap(opt2)));
00939   EXPECT_TRUE(noexcept(swap(opt1, opt2)));
00940 }
00941 
00942 template <int v>
00943 struct DeletedOpAddr {
00944   constexpr static const int value = v;
00945   constexpr DeletedOpAddr() = default;
00946   constexpr const DeletedOpAddr<v>* operator&() const = delete;  // NOLINT
00947   DeletedOpAddr<v>* operator&() = delete;                        // NOLINT
00948 };
00949 
00950 // The static_assert featuring a constexpr call to operator->() is commented out
00951 // to document the fact that the current implementation of absl::optional<T>
00952 // expects such usecases to be malformed and not compile.
00953 TEST(optionalTest, OperatorAddr) {
00954   constexpr const int v = -1;
00955   {  // constexpr
00956     constexpr const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});
00957     static_assert(opt.has_value(), "");
00958     // static_assert(opt->value == v, "");
00959     static_assert((*opt).value == v, "");
00960   }
00961   {  // non-constexpr
00962     const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});
00963     EXPECT_TRUE(opt.has_value());
00964     EXPECT_TRUE(opt->value == v);
00965     EXPECT_TRUE((*opt).value == v);
00966   }
00967 }
00968 
00969 TEST(optionalTest, PointerStuff) {
00970   absl::optional<std::string> opt(absl::in_place, "foo");
00971   EXPECT_EQ("foo", *opt);
00972   const auto& opt_const = opt;
00973   EXPECT_EQ("foo", *opt_const);
00974   EXPECT_EQ(opt->size(), 3);
00975   EXPECT_EQ(opt_const->size(), 3);
00976 
00977   constexpr absl::optional<ConstexprType> opt1(1);
00978   static_assert((*opt1).x == ConstexprType::kCtorInt, "");
00979 }
00980 
00981 // gcc has a bug pre 4.9.1 where it doesn't do correct overload resolution
00982 // when overloads are const-qualified and *this is an raluve.
00983 // Skip that test to make the build green again when using the old compiler.
00984 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59296 is fixed in 4.9.1.
00985 #if defined(__GNUC__) && !defined(__clang__)
00986 #define GCC_VERSION (__GNUC__ * 10000 \
00987                      + __GNUC_MINOR__ * 100 \
00988                      + __GNUC_PATCHLEVEL__)
00989 #if GCC_VERSION < 40901
00990 #define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
00991 #endif
00992 #endif
00993 
00994 // MSVC has a bug with "cv-qualifiers in class construction", fixed in 2017. See
00995 // https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#bug-fixes
00996 // The compiler some incorrectly ingores the cv-qualifier when generating a
00997 // class object via a constructor call. For example:
00998 //
00999 // class optional {
01000 //   constexpr T&& value() &&;
01001 //   constexpr const T&& value() const &&;
01002 // }
01003 //
01004 // using COI = const absl::optional<int>;
01005 // static_assert(2 == COI(2).value(), "");  // const &&
01006 //
01007 // This should invoke the "const &&" overload but since it ignores the const
01008 // qualifier it finds the "&&" overload the best candidate.
01009 #if defined(_MSC_VER) && _MSC_VER < 1910
01010 #define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG
01011 #endif
01012 
01013 TEST(optionalTest, Value) {
01014   using O = absl::optional<std::string>;
01015   using CO = const absl::optional<std::string>;
01016   using OC = absl::optional<const std::string>;
01017   O lvalue(absl::in_place, "lvalue");
01018   CO clvalue(absl::in_place, "clvalue");
01019   OC lvalue_c(absl::in_place, "lvalue_c");
01020   EXPECT_EQ("lvalue", lvalue.value());
01021   EXPECT_EQ("clvalue", clvalue.value());
01022   EXPECT_EQ("lvalue_c", lvalue_c.value());
01023   EXPECT_EQ("xvalue", O(absl::in_place, "xvalue").value());
01024   EXPECT_EQ("xvalue_c", OC(absl::in_place, "xvalue_c").value());
01025 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
01026   EXPECT_EQ("cxvalue", CO(absl::in_place, "cxvalue").value());
01027 #endif
01028   EXPECT_EQ("&", TypeQuals(lvalue.value()));
01029   EXPECT_EQ("c&", TypeQuals(clvalue.value()));
01030   EXPECT_EQ("c&", TypeQuals(lvalue_c.value()));
01031   EXPECT_EQ("&&", TypeQuals(O(absl::in_place, "xvalue").value()));
01032 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
01033     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
01034   EXPECT_EQ("c&&", TypeQuals(CO(absl::in_place, "cxvalue").value()));
01035 #endif
01036   EXPECT_EQ("c&&", TypeQuals(OC(absl::in_place, "xvalue_c").value()));
01037 
01038   // test on volatile type
01039   using OV = absl::optional<volatile int>;
01040   OV lvalue_v(absl::in_place, 42);
01041   EXPECT_EQ(42, lvalue_v.value());
01042   EXPECT_EQ(42, OV(42).value());
01043   EXPECT_TRUE((std::is_same<volatile int&, decltype(lvalue_v.value())>::value));
01044   EXPECT_TRUE((std::is_same<volatile int&&, decltype(OV(42).value())>::value));
01045 
01046   // test exception throw on value()
01047   absl::optional<int> empty;
01048 #ifdef ABSL_HAVE_EXCEPTIONS
01049   EXPECT_THROW((void)empty.value(), absl::bad_optional_access);
01050 #else
01051   EXPECT_DEATH((void)empty.value(), "Bad optional access");
01052 #endif
01053 
01054   // test constexpr value()
01055   constexpr absl::optional<int> o1(1);
01056   static_assert(1 == o1.value(), "");  // const &
01057 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
01058     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
01059   using COI = const absl::optional<int>;
01060   static_assert(2 == COI(2).value(), "");  // const &&
01061 #endif
01062 }
01063 
01064 TEST(optionalTest, DerefOperator) {
01065   using O = absl::optional<std::string>;
01066   using CO = const absl::optional<std::string>;
01067   using OC = absl::optional<const std::string>;
01068   O lvalue(absl::in_place, "lvalue");
01069   CO clvalue(absl::in_place, "clvalue");
01070   OC lvalue_c(absl::in_place, "lvalue_c");
01071   EXPECT_EQ("lvalue", *lvalue);
01072   EXPECT_EQ("clvalue", *clvalue);
01073   EXPECT_EQ("lvalue_c", *lvalue_c);
01074   EXPECT_EQ("xvalue", *O(absl::in_place, "xvalue"));
01075   EXPECT_EQ("xvalue_c", *OC(absl::in_place, "xvalue_c"));
01076 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
01077   EXPECT_EQ("cxvalue", *CO(absl::in_place, "cxvalue"));
01078 #endif
01079   EXPECT_EQ("&", TypeQuals(*lvalue));
01080   EXPECT_EQ("c&", TypeQuals(*clvalue));
01081   EXPECT_EQ("&&", TypeQuals(*O(absl::in_place, "xvalue")));
01082 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
01083     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
01084   EXPECT_EQ("c&&", TypeQuals(*CO(absl::in_place, "cxvalue")));
01085 #endif
01086   EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c")));
01087 
01088   // test on volatile type
01089   using OV = absl::optional<volatile int>;
01090   OV lvalue_v(absl::in_place, 42);
01091   EXPECT_EQ(42, *lvalue_v);
01092   EXPECT_EQ(42, *OV(42));
01093   EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value));
01094   EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value));
01095 
01096   constexpr absl::optional<int> opt1(1);
01097   static_assert(*opt1 == 1, "");
01098 #if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \
01099     !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
01100   using COI = const absl::optional<int>;
01101   static_assert(*COI(2) == 2, "");
01102 #endif
01103 }
01104 
01105 TEST(optionalTest, ValueOr) {
01106   absl::optional<double> opt_empty, opt_set = 1.2;
01107   EXPECT_EQ(42.0, opt_empty.value_or(42));
01108   EXPECT_EQ(1.2, opt_set.value_or(42));
01109   EXPECT_EQ(42.0, absl::optional<double>().value_or(42));
01110   EXPECT_EQ(1.2, absl::optional<double>(1.2).value_or(42));
01111 
01112   constexpr absl::optional<double> copt_empty, copt_set = {1.2};
01113   static_assert(42.0 == copt_empty.value_or(42), "");
01114   static_assert(1.2 == copt_set.value_or(42), "");
01115 #ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG
01116   using COD = const absl::optional<double>;
01117   static_assert(42.0 == COD().value_or(42), "");
01118   static_assert(1.2 == COD(1.2).value_or(42), "");
01119 #endif
01120 }
01121 
01122 // make_optional cannot be constexpr until C++17
01123 TEST(optionalTest, make_optional) {
01124   auto opt_int = absl::make_optional(42);
01125   EXPECT_TRUE((std::is_same<decltype(opt_int), absl::optional<int>>::value));
01126   EXPECT_EQ(42, opt_int);
01127 
01128   StructorListener listener;
01129   Listenable::listener = &listener;
01130 
01131   absl::optional<Listenable> opt0 = absl::make_optional<Listenable>();
01132   EXPECT_EQ(1, listener.construct0);
01133   absl::optional<Listenable> opt1 = absl::make_optional<Listenable>(1);
01134   EXPECT_EQ(1, listener.construct1);
01135   absl::optional<Listenable> opt2 = absl::make_optional<Listenable>(1, 2);
01136   EXPECT_EQ(1, listener.construct2);
01137   absl::optional<Listenable> opt3 = absl::make_optional<Listenable>({1});
01138   absl::optional<Listenable> opt4 = absl::make_optional<Listenable>({1, 2});
01139   EXPECT_EQ(2, listener.listinit);
01140 
01141   // Constexpr tests on trivially copyable types
01142   // optional<T> has trivial copy/move ctors when T is trivially copyable.
01143   // For nontrivial types with constexpr constructors, we need copy elision in
01144   // C++17 for make_optional to be constexpr.
01145   {
01146     constexpr absl::optional<int> c_opt = absl::make_optional(42);
01147     static_assert(c_opt.value() == 42, "");
01148   }
01149   {
01150     struct TrivialCopyable {
01151       constexpr TrivialCopyable() : x(0) {}
01152       constexpr explicit TrivialCopyable(int i) : x(i) {}
01153       int x;
01154     };
01155 
01156     constexpr TrivialCopyable v;
01157     constexpr absl::optional<TrivialCopyable> c_opt0 = absl::make_optional(v);
01158     static_assert((*c_opt0).x == 0, "");
01159     constexpr absl::optional<TrivialCopyable> c_opt1 =
01160         absl::make_optional<TrivialCopyable>();
01161     static_assert((*c_opt1).x == 0, "");
01162     constexpr absl::optional<TrivialCopyable> c_opt2 =
01163         absl::make_optional<TrivialCopyable>(42);
01164     static_assert((*c_opt2).x == 42, "");
01165   }
01166 }
01167 
01168 template <typename T, typename U>
01169 void optionalTest_Comparisons_EXPECT_LESS(T x, U y) {
01170   EXPECT_FALSE(x == y);
01171   EXPECT_TRUE(x != y);
01172   EXPECT_TRUE(x < y);
01173   EXPECT_FALSE(x > y);
01174   EXPECT_TRUE(x <= y);
01175   EXPECT_FALSE(x >= y);
01176 }
01177 
01178 template <typename T, typename U>
01179 void optionalTest_Comparisons_EXPECT_SAME(T x, U y) {
01180   EXPECT_TRUE(x == y);
01181   EXPECT_FALSE(x != y);
01182   EXPECT_FALSE(x < y);
01183   EXPECT_FALSE(x > y);
01184   EXPECT_TRUE(x <= y);
01185   EXPECT_TRUE(x >= y);
01186 }
01187 
01188 template <typename T, typename U>
01189 void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) {
01190   EXPECT_FALSE(x == y);
01191   EXPECT_TRUE(x != y);
01192   EXPECT_FALSE(x < y);
01193   EXPECT_TRUE(x > y);
01194   EXPECT_FALSE(x <= y);
01195   EXPECT_TRUE(x >= y);
01196 }
01197 
01198 
01199 template <typename T, typename U, typename V>
01200 void TestComparisons() {
01201   absl::optional<T> ae, a2{2}, a4{4};
01202   absl::optional<U> be, b2{2}, b4{4};
01203   V v3 = 3;
01204 
01205   // LHS: absl::nullopt, ae, a2, v3, a4
01206   // RHS: absl::nullopt, be, b2, v3, b4
01207 
01208   // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,absl::nullopt);
01209   optionalTest_Comparisons_EXPECT_SAME(absl::nullopt, be);
01210   optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b2);
01211   // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,v3);
01212   optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b4);
01213 
01214   optionalTest_Comparisons_EXPECT_SAME(ae, absl::nullopt);
01215   optionalTest_Comparisons_EXPECT_SAME(ae, be);
01216   optionalTest_Comparisons_EXPECT_LESS(ae, b2);
01217   optionalTest_Comparisons_EXPECT_LESS(ae, v3);
01218   optionalTest_Comparisons_EXPECT_LESS(ae, b4);
01219 
01220   optionalTest_Comparisons_EXPECT_GREATER(a2, absl::nullopt);
01221   optionalTest_Comparisons_EXPECT_GREATER(a2, be);
01222   optionalTest_Comparisons_EXPECT_SAME(a2, b2);
01223   optionalTest_Comparisons_EXPECT_LESS(a2, v3);
01224   optionalTest_Comparisons_EXPECT_LESS(a2, b4);
01225 
01226   // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(v3,absl::nullopt);
01227   optionalTest_Comparisons_EXPECT_GREATER(v3, be);
01228   optionalTest_Comparisons_EXPECT_GREATER(v3, b2);
01229   optionalTest_Comparisons_EXPECT_SAME(v3, v3);
01230   optionalTest_Comparisons_EXPECT_LESS(v3, b4);
01231 
01232   optionalTest_Comparisons_EXPECT_GREATER(a4, absl::nullopt);
01233   optionalTest_Comparisons_EXPECT_GREATER(a4, be);
01234   optionalTest_Comparisons_EXPECT_GREATER(a4, b2);
01235   optionalTest_Comparisons_EXPECT_GREATER(a4, v3);
01236   optionalTest_Comparisons_EXPECT_SAME(a4, b4);
01237 }
01238 
01239 struct Int1 {
01240   Int1() = default;
01241   Int1(int i) : i(i) {}  // NOLINT(runtime/explicit)
01242   int i;
01243 };
01244 
01245 struct Int2 {
01246   Int2() = default;
01247   Int2(int i) : i(i) {}  // NOLINT(runtime/explicit)
01248   int i;
01249 };
01250 
01251 // comparison between Int1 and Int2
01252 constexpr bool operator==(const Int1& lhs, const Int2& rhs) {
01253   return lhs.i == rhs.i;
01254 }
01255 constexpr bool operator!=(const Int1& lhs, const Int2& rhs) {
01256   return !(lhs == rhs);
01257 }
01258 constexpr bool operator<(const Int1& lhs, const Int2& rhs) {
01259   return lhs.i < rhs.i;
01260 }
01261 constexpr bool operator<=(const Int1& lhs, const Int2& rhs) {
01262   return lhs < rhs || lhs == rhs;
01263 }
01264 constexpr bool operator>(const Int1& lhs, const Int2& rhs) {
01265   return !(lhs <= rhs);
01266 }
01267 constexpr bool operator>=(const Int1& lhs, const Int2& rhs) {
01268   return !(lhs < rhs);
01269 }
01270 
01271 TEST(optionalTest, Comparisons) {
01272   TestComparisons<int, int, int>();
01273   TestComparisons<const int, int, int>();
01274   TestComparisons<Int1, int, int>();
01275   TestComparisons<int, Int2, int>();
01276   TestComparisons<Int1, Int2, int>();
01277 
01278   // compare absl::optional<std::string> with const char*
01279   absl::optional<std::string> opt_str = "abc";
01280   const char* cstr = "abc";
01281   EXPECT_TRUE(opt_str == cstr);
01282   // compare absl::optional<std::string> with absl::optional<const char*>
01283   absl::optional<const char*> opt_cstr = cstr;
01284   EXPECT_TRUE(opt_str == opt_cstr);
01285   // compare absl::optional<std::string> with absl::optional<absl::string_view>
01286   absl::optional<absl::string_view> e1;
01287   absl::optional<std::string> e2;
01288   EXPECT_TRUE(e1 == e2);
01289 }
01290 
01291 
01292 TEST(optionalTest, SwapRegression) {
01293   StructorListener listener;
01294   Listenable::listener = &listener;
01295 
01296   {
01297     absl::optional<Listenable> a;
01298     absl::optional<Listenable> b(absl::in_place);
01299     a.swap(b);
01300   }
01301 
01302   EXPECT_EQ(1, listener.construct0);
01303   EXPECT_EQ(1, listener.move);
01304   EXPECT_EQ(2, listener.destruct);
01305 
01306   {
01307     absl::optional<Listenable> a(absl::in_place);
01308     absl::optional<Listenable> b;
01309     a.swap(b);
01310   }
01311 
01312   EXPECT_EQ(2, listener.construct0);
01313   EXPECT_EQ(2, listener.move);
01314   EXPECT_EQ(4, listener.destruct);
01315 }
01316 
01317 TEST(optionalTest, BigStringLeakCheck) {
01318   constexpr size_t n = 1 << 16;
01319 
01320   using OS = absl::optional<std::string>;
01321 
01322   OS a;
01323   OS b = absl::nullopt;
01324   OS c = std::string(n, 'c');
01325   std::string sd(n, 'd');
01326   OS d = sd;
01327   OS e(absl::in_place, n, 'e');
01328   OS f;
01329   f.emplace(n, 'f');
01330 
01331   OS ca(a);
01332   OS cb(b);
01333   OS cc(c);
01334   OS cd(d);
01335   OS ce(e);
01336 
01337   OS oa;
01338   OS ob = absl::nullopt;
01339   OS oc = std::string(n, 'c');
01340   std::string sod(n, 'd');
01341   OS od = sod;
01342   OS oe(absl::in_place, n, 'e');
01343   OS of;
01344   of.emplace(n, 'f');
01345 
01346   OS ma(std::move(oa));
01347   OS mb(std::move(ob));
01348   OS mc(std::move(oc));
01349   OS md(std::move(od));
01350   OS me(std::move(oe));
01351   OS mf(std::move(of));
01352 
01353   OS aa1;
01354   OS ab1 = absl::nullopt;
01355   OS ac1 = std::string(n, 'c');
01356   std::string sad1(n, 'd');
01357   OS ad1 = sad1;
01358   OS ae1(absl::in_place, n, 'e');
01359   OS af1;
01360   af1.emplace(n, 'f');
01361 
01362   OS aa2;
01363   OS ab2 = absl::nullopt;
01364   OS ac2 = std::string(n, 'c');
01365   std::string sad2(n, 'd');
01366   OS ad2 = sad2;
01367   OS ae2(absl::in_place, n, 'e');
01368   OS af2;
01369   af2.emplace(n, 'f');
01370 
01371   aa1 = af2;
01372   ab1 = ae2;
01373   ac1 = ad2;
01374   ad1 = ac2;
01375   ae1 = ab2;
01376   af1 = aa2;
01377 
01378   OS aa3;
01379   OS ab3 = absl::nullopt;
01380   OS ac3 = std::string(n, 'c');
01381   std::string sad3(n, 'd');
01382   OS ad3 = sad3;
01383   OS ae3(absl::in_place, n, 'e');
01384   OS af3;
01385   af3.emplace(n, 'f');
01386 
01387   aa3 = absl::nullopt;
01388   ab3 = absl::nullopt;
01389   ac3 = absl::nullopt;
01390   ad3 = absl::nullopt;
01391   ae3 = absl::nullopt;
01392   af3 = absl::nullopt;
01393 
01394   OS aa4;
01395   OS ab4 = absl::nullopt;
01396   OS ac4 = std::string(n, 'c');
01397   std::string sad4(n, 'd');
01398   OS ad4 = sad4;
01399   OS ae4(absl::in_place, n, 'e');
01400   OS af4;
01401   af4.emplace(n, 'f');
01402 
01403   aa4 = OS(absl::in_place, n, 'a');
01404   ab4 = OS(absl::in_place, n, 'b');
01405   ac4 = OS(absl::in_place, n, 'c');
01406   ad4 = OS(absl::in_place, n, 'd');
01407   ae4 = OS(absl::in_place, n, 'e');
01408   af4 = OS(absl::in_place, n, 'f');
01409 
01410   OS aa5;
01411   OS ab5 = absl::nullopt;
01412   OS ac5 = std::string(n, 'c');
01413   std::string sad5(n, 'd');
01414   OS ad5 = sad5;
01415   OS ae5(absl::in_place, n, 'e');
01416   OS af5;
01417   af5.emplace(n, 'f');
01418 
01419   std::string saa5(n, 'a');
01420   std::string sab5(n, 'a');
01421   std::string sac5(n, 'a');
01422   std::string sad52(n, 'a');
01423   std::string sae5(n, 'a');
01424   std::string saf5(n, 'a');
01425 
01426   aa5 = saa5;
01427   ab5 = sab5;
01428   ac5 = sac5;
01429   ad5 = sad52;
01430   ae5 = sae5;
01431   af5 = saf5;
01432 
01433   OS aa6;
01434   OS ab6 = absl::nullopt;
01435   OS ac6 = std::string(n, 'c');
01436   std::string sad6(n, 'd');
01437   OS ad6 = sad6;
01438   OS ae6(absl::in_place, n, 'e');
01439   OS af6;
01440   af6.emplace(n, 'f');
01441 
01442   aa6 = std::string(n, 'a');
01443   ab6 = std::string(n, 'b');
01444   ac6 = std::string(n, 'c');
01445   ad6 = std::string(n, 'd');
01446   ae6 = std::string(n, 'e');
01447   af6 = std::string(n, 'f');
01448 
01449   OS aa7;
01450   OS ab7 = absl::nullopt;
01451   OS ac7 = std::string(n, 'c');
01452   std::string sad7(n, 'd');
01453   OS ad7 = sad7;
01454   OS ae7(absl::in_place, n, 'e');
01455   OS af7;
01456   af7.emplace(n, 'f');
01457 
01458   aa7.emplace(n, 'A');
01459   ab7.emplace(n, 'B');
01460   ac7.emplace(n, 'C');
01461   ad7.emplace(n, 'D');
01462   ae7.emplace(n, 'E');
01463   af7.emplace(n, 'F');
01464 }
01465 
01466 TEST(optionalTest, MoveAssignRegression) {
01467   StructorListener listener;
01468   Listenable::listener = &listener;
01469 
01470   {
01471     absl::optional<Listenable> a;
01472     Listenable b;
01473     a = std::move(b);
01474   }
01475 
01476   EXPECT_EQ(1, listener.construct0);
01477   EXPECT_EQ(1, listener.move);
01478   EXPECT_EQ(2, listener.destruct);
01479 }
01480 
01481 TEST(optionalTest, ValueType) {
01482   EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value));
01483   EXPECT_TRUE((std::is_same<absl::optional<std::string>::value_type,
01484                             std::string>::value));
01485   EXPECT_FALSE(
01486       (std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value));
01487 }
01488 
01489 template <typename T>
01490 struct is_hash_enabled_for {
01491   template <typename U, typename = decltype(std::hash<U>()(std::declval<U>()))>
01492   static std::true_type test(int);
01493 
01494   template <typename U>
01495   static std::false_type test(...);
01496 
01497   static constexpr bool value = decltype(test<T>(0))::value;
01498 };
01499 
01500 TEST(optionalTest, Hash) {
01501   std::hash<absl::optional<int>> hash;
01502   std::set<size_t> hashcodes;
01503   hashcodes.insert(hash(absl::nullopt));
01504   for (int i = 0; i < 100; ++i) {
01505     hashcodes.insert(hash(i));
01506   }
01507   EXPECT_GT(hashcodes.size(), 90);
01508 
01509   static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");
01510   static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");
01511   static_assert(
01512       absl::type_traits_internal::IsHashable<absl::optional<int>>::value, "");
01513   static_assert(
01514       absl::type_traits_internal::IsHashable<absl::optional<Hashable>>::value,
01515       "");
01516   absl::type_traits_internal::AssertHashEnabled<absl::optional<int>>();
01517   absl::type_traits_internal::AssertHashEnabled<absl::optional<Hashable>>();
01518 
01519 #if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
01520   static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, "");
01521   static_assert(!absl::type_traits_internal::IsHashable<
01522                     absl::optional<NonHashable>>::value,
01523                 "");
01524 #endif
01525 
01526   // libstdc++ std::optional is missing remove_const_t, i.e. it's using
01527   // std::hash<T> rather than std::hash<std::remove_const_t<T>>.
01528   // Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262
01529 #ifndef __GLIBCXX__
01530   static_assert(is_hash_enabled_for<absl::optional<const int>>::value, "");
01531   static_assert(is_hash_enabled_for<absl::optional<const Hashable>>::value, "");
01532   std::hash<absl::optional<const int>> c_hash;
01533   for (int i = 0; i < 100; ++i) {
01534     EXPECT_EQ(hash(i), c_hash(i));
01535   }
01536 #endif
01537 }
01538 
01539 struct MoveMeNoThrow {
01540   MoveMeNoThrow() : x(0) {}
01541   [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
01542     ABSL_RAW_LOG(FATAL, "Should not be called.");
01543     abort();
01544   }
01545   MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
01546   int x;
01547 };
01548 
01549 struct MoveMeThrow {
01550   MoveMeThrow() : x(0) {}
01551   MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}
01552   MoveMeThrow(MoveMeThrow&& other) : x(other.x) {}
01553   int x;
01554 };
01555 
01556 TEST(optionalTest, NoExcept) {
01557   static_assert(
01558       std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value,
01559       "");
01560 #ifndef ABSL_HAVE_STD_OPTIONAL
01561   static_assert(absl::default_allocator_is_nothrow::value ==
01562                     std::is_nothrow_move_constructible<
01563                         absl::optional<MoveMeThrow>>::value,
01564                 "");
01565 #endif
01566   std::vector<absl::optional<MoveMeNoThrow>> v;
01567   for (int i = 0; i < 10; ++i) v.emplace_back();
01568 }
01569 
01570 struct AnyLike {
01571   AnyLike(AnyLike&&) = default;
01572   AnyLike(const AnyLike&) = default;
01573 
01574   template <typename ValueType,
01575             typename T = typename std::decay<ValueType>::type,
01576             typename std::enable_if<
01577                 !absl::disjunction<
01578                     std::is_same<AnyLike, T>,
01579                     absl::negation<std::is_copy_constructible<T>>>::value,
01580                 int>::type = 0>
01581   AnyLike(ValueType&&) {}  // NOLINT(runtime/explicit)
01582 
01583   AnyLike& operator=(AnyLike&&) = default;
01584   AnyLike& operator=(const AnyLike&) = default;
01585 
01586   template <typename ValueType,
01587             typename T = typename std::decay<ValueType>::type>
01588   typename std::enable_if<
01589       absl::conjunction<absl::negation<std::is_same<AnyLike, T>>,
01590                         std::is_copy_constructible<T>>::value,
01591       AnyLike&>::type
01592   operator=(ValueType&& /* rhs */) {
01593     return *this;
01594   }
01595 };
01596 
01597 TEST(optionalTest, ConstructionConstraints) {
01598   EXPECT_TRUE((std::is_constructible<AnyLike, absl::optional<AnyLike>>::value));
01599 
01600   EXPECT_TRUE(
01601       (std::is_constructible<AnyLike, const absl::optional<AnyLike>&>::value));
01602 
01603   EXPECT_TRUE((std::is_constructible<absl::optional<AnyLike>, AnyLike>::value));
01604   EXPECT_TRUE(
01605       (std::is_constructible<absl::optional<AnyLike>, const AnyLike&>::value));
01606 
01607   EXPECT_TRUE((std::is_convertible<absl::optional<AnyLike>, AnyLike>::value));
01608 
01609   EXPECT_TRUE(
01610       (std::is_convertible<const absl::optional<AnyLike>&, AnyLike>::value));
01611 
01612   EXPECT_TRUE((std::is_convertible<AnyLike, absl::optional<AnyLike>>::value));
01613   EXPECT_TRUE(
01614       (std::is_convertible<const AnyLike&, absl::optional<AnyLike>>::value));
01615 
01616   EXPECT_TRUE(std::is_move_constructible<absl::optional<AnyLike>>::value);
01617   EXPECT_TRUE(std::is_copy_constructible<absl::optional<AnyLike>>::value);
01618 }
01619 
01620 TEST(optionalTest, AssignmentConstraints) {
01621   EXPECT_TRUE((std::is_assignable<AnyLike&, absl::optional<AnyLike>>::value));
01622   EXPECT_TRUE(
01623       (std::is_assignable<AnyLike&, const absl::optional<AnyLike>&>::value));
01624   EXPECT_TRUE((std::is_assignable<absl::optional<AnyLike>&, AnyLike>::value));
01625   EXPECT_TRUE(
01626       (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value));
01627   EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value);
01628   EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
01629 }
01630 
01631 struct NestedClassBug {
01632   struct Inner {
01633     bool dummy = false;
01634   };
01635   absl::optional<Inner> value;
01636 };
01637 
01638 TEST(optionalTest, InPlaceTSFINAEBug) {
01639   NestedClassBug b;
01640   ((void)b);
01641   using Inner = NestedClassBug::Inner;
01642 
01643   EXPECT_TRUE((std::is_default_constructible<Inner>::value));
01644   EXPECT_TRUE((std::is_constructible<Inner>::value));
01645   EXPECT_TRUE(
01646       (std::is_constructible<absl::optional<Inner>, absl::in_place_t>::value));
01647 
01648   absl::optional<Inner> o(absl::in_place);
01649   EXPECT_TRUE(o.has_value());
01650   o.emplace();
01651   EXPECT_TRUE(o.has_value());
01652 }
01653 
01654 }  // namespace


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15