| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627 | // Copyright 2017 The Abseil Authors.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#include "absl/types/optional.h"#include <string>#include <type_traits>#include <utility>#include "gtest/gtest.h"#include "absl/base/config.h"#include "absl/base/internal/raw_logging.h"#include "absl/meta/type_traits.h"#include "absl/strings/string_view.h"struct Hashable {};namespace std {template <>struct hash<Hashable> {  size_t operator()(const Hashable&) { return 0; }};}  // namespace stdstruct NonHashable {};namespace {std::string TypeQuals(std::string&) { return "&"; }std::string TypeQuals(std::string&&) { return "&&"; }std::string TypeQuals(const std::string&) { return "c&"; }std::string TypeQuals(const std::string&&) { return "c&&"; }struct StructorListener {  int construct0 = 0;  int construct1 = 0;  int construct2 = 0;  int listinit = 0;  int copy = 0;  int move = 0;  int copy_assign = 0;  int move_assign = 0;  int destruct = 0;  int volatile_copy = 0;  int volatile_move = 0;  int volatile_copy_assign = 0;  int volatile_move_assign = 0;};// Suppress MSVC warnings.// 4521: multiple copy constructors specified// 4522: multiple assignment operators specified// We wrote multiple of them to test that the correct overloads are selected.#ifdef _MSC_VER#pragma warning( push )#pragma warning( disable : 4521)#pragma warning( disable : 4522)#endifstruct Listenable {  static StructorListener* listener;  Listenable() { ++listener->construct0; }  explicit Listenable(int /*unused*/) { ++listener->construct1; }  Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }  Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }  Listenable(const Listenable& /*unused*/) { ++listener->copy; }  Listenable(const volatile Listenable& /*unused*/) {    ++listener->volatile_copy;  }  Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; }  Listenable(Listenable&& /*unused*/) { ++listener->move; }  Listenable& operator=(const Listenable& /*unused*/) {    ++listener->copy_assign;    return *this;  }  Listenable& operator=(Listenable&& /*unused*/) {    ++listener->move_assign;    return *this;  }  // use void return type instead of volatile T& to work around GCC warning  // when the assignment's returned reference is ignored.  void operator=(const volatile Listenable& /*unused*/) volatile {    ++listener->volatile_copy_assign;  }  void operator=(volatile Listenable&& /*unused*/) volatile {    ++listener->volatile_move_assign;  }  ~Listenable() { ++listener->destruct; }};#ifdef _MSC_VER#pragma warning( pop )#endifStructorListener* Listenable::listener = nullptr;// ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST is defined to 1 when the standard// library implementation doesn't marked initializer_list's default constructor// constexpr. The C++11 standard doesn't specify constexpr on it, but C++14// added it. However, libstdc++ 4.7 marked it constexpr.#if defined(_LIBCPP_VERSION) && \    (_LIBCPP_STD_VER <= 11 || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR))#define ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST 1#endifstruct ConstexprType {  enum CtorTypes {    kCtorDefault,    kCtorInt,    kCtorInitializerList,    kCtorConstChar  };  constexpr ConstexprType() : x(kCtorDefault) {}  constexpr explicit ConstexprType(int i) : x(kCtorInt) {}#ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST  constexpr ConstexprType(std::initializer_list<int> il)      : x(kCtorInitializerList) {}#endif  constexpr ConstexprType(const char*)  // NOLINT(runtime/explicit)      : x(kCtorConstChar) {}  int x;};struct Copyable {  Copyable() {}  Copyable(const Copyable&) {}  Copyable& operator=(const Copyable&) { return *this; }};struct MoveableThrow {  MoveableThrow() {}  MoveableThrow(MoveableThrow&&) {}  MoveableThrow& operator=(MoveableThrow&&) { return *this; }};struct MoveableNoThrow {  MoveableNoThrow() {}  MoveableNoThrow(MoveableNoThrow&&) noexcept {}  MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }};struct NonMovable {  NonMovable() {}  NonMovable(const NonMovable&) = delete;  NonMovable& operator=(const NonMovable&) = delete;  NonMovable(NonMovable&&) = delete;  NonMovable& operator=(NonMovable&&) = delete;};TEST(optionalTest, DefaultConstructor) {  absl::optional<int> empty;  EXPECT_FALSE(empty);  constexpr absl::optional<int> cempty;  static_assert(!cempty.has_value(), "");  EXPECT_TRUE(      std::is_nothrow_default_constructible<absl::optional<int>>::value);}TEST(optionalTest, nulloptConstructor) {  absl::optional<int> empty(absl::nullopt);  EXPECT_FALSE(empty);#ifdef ABSL_HAVE_STD_OPTIONAL  constexpr absl::optional<int> cempty{absl::nullopt};#else  // Creating a temporary absl::nullopt_t object instead of using absl::nullopt  // because absl::nullopt cannot be constexpr and have external linkage at the  // same time.  constexpr absl::optional<int> cempty{absl::nullopt_t(absl::nullopt_t::init)};#endif  static_assert(!cempty.has_value(), "");  EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>,                                             absl::nullopt_t>::value));}TEST(optionalTest, CopyConstructor) {  {    absl::optional<int> empty, opt42 = 42;    absl::optional<int> empty_copy(empty);    EXPECT_FALSE(empty_copy);    absl::optional<int> opt42_copy(opt42);    EXPECT_TRUE(opt42_copy);    EXPECT_EQ(42, *opt42_copy);  }  {    absl::optional<const int> empty, opt42 = 42;    absl::optional<const int> empty_copy(empty);    EXPECT_FALSE(empty_copy);    absl::optional<const int> opt42_copy(opt42);    EXPECT_TRUE(opt42_copy);    EXPECT_EQ(42, *opt42_copy);  }  {    absl::optional<volatile int> empty, opt42 = 42;    absl::optional<volatile int> empty_copy(empty);    EXPECT_FALSE(empty_copy);    absl::optional<volatile int> opt42_copy(opt42);    EXPECT_TRUE(opt42_copy);    EXPECT_EQ(42, *opt42_copy);  }  // test copyablility  EXPECT_TRUE(std::is_copy_constructible<absl::optional<int>>::value);  EXPECT_TRUE(std::is_copy_constructible<absl::optional<Copyable>>::value);  EXPECT_FALSE(      std::is_copy_constructible<absl::optional<MoveableThrow>>::value);  EXPECT_FALSE(      std::is_copy_constructible<absl::optional<MoveableNoThrow>>::value);  EXPECT_FALSE(std::is_copy_constructible<absl::optional<NonMovable>>::value);  EXPECT_FALSE(      absl::is_trivially_copy_constructible<absl::optional<Copyable>>::value);#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(__GLIBCXX__)  // libstdc++ std::optional implementation (as of 7.2) has a bug: when T is  // trivially copyable, optional<T> is not trivially copyable (due to one of  // its base class is unconditionally nontrivial).#define ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG 1#endif#ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG  EXPECT_TRUE(      absl::is_trivially_copy_constructible<absl::optional<int>>::value);  EXPECT_TRUE(      absl::is_trivially_copy_constructible<absl::optional<const int>>::value);#ifndef _MSC_VER  // See defect report "Trivial copy/move constructor for class with volatile  // member" at  // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094  // A class with non-static data member of volatile-qualified type should still  // have a trivial copy constructor if the data member is trivial.  // Also a cv-qualified scalar type should be trivially copyable.  EXPECT_TRUE(absl::is_trivially_copy_constructible<              absl::optional<volatile int>>::value);#endif  // _MSC_VER#endif  // ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG  // constexpr copy constructor for trivially copyable types  {    constexpr absl::optional<int> o1;    constexpr absl::optional<int> o2 = o1;    static_assert(!o2, "");  }  {    constexpr absl::optional<int> o1 = 42;    constexpr absl::optional<int> o2 = o1;    static_assert(o2, "");    static_assert(*o2 == 42, "");  }  {    struct TrivialCopyable {      constexpr TrivialCopyable() : x(0) {}      constexpr explicit TrivialCopyable(int i) : x(i) {}      int x;    };    constexpr absl::optional<TrivialCopyable> o1(42);    constexpr absl::optional<TrivialCopyable> o2 = o1;    static_assert(o2, "");    static_assert((*o2).x == 42, "");#ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG    EXPECT_TRUE(absl::is_trivially_copy_constructible<                absl::optional<TrivialCopyable>>::value);    EXPECT_TRUE(absl::is_trivially_copy_constructible<                absl::optional<const TrivialCopyable>>::value);#endif    // When testing with VS 2017 15.3, there seems to be a bug in MSVC    // std::optional when T is volatile-qualified. So skipping this test.    // Bug report:    // https://connect.microsoft.com/VisualStudio/feedback/details/3142534#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911#define ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG 1#endif#ifndef ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG    EXPECT_FALSE(std::is_copy_constructible<                 absl::optional<volatile TrivialCopyable>>::value);#endif  }}TEST(optionalTest, MoveConstructor) {  absl::optional<int> empty, opt42 = 42;  absl::optional<int> empty_move(std::move(empty));  EXPECT_FALSE(empty_move);  absl::optional<int> opt42_move(std::move(opt42));  EXPECT_TRUE(opt42_move);  EXPECT_EQ(42, opt42_move);  // test movability  EXPECT_TRUE(std::is_move_constructible<absl::optional<int>>::value);  EXPECT_TRUE(std::is_move_constructible<absl::optional<Copyable>>::value);  EXPECT_TRUE(std::is_move_constructible<absl::optional<MoveableThrow>>::value);  EXPECT_TRUE(      std::is_move_constructible<absl::optional<MoveableNoThrow>>::value);  EXPECT_FALSE(std::is_move_constructible<absl::optional<NonMovable>>::value);  // test noexcept  EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value);#ifndef ABSL_HAVE_STD_OPTIONAL  EXPECT_EQ(      absl::default_allocator_is_nothrow::value,      std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value);#endif  EXPECT_TRUE(std::is_nothrow_move_constructible<              absl::optional<MoveableNoThrow>>::value);}TEST(optionalTest, Destructor) {  struct Trivial {};  struct NonTrivial {    NonTrivial(const NonTrivial&) {}    NonTrivial& operator=(const NonTrivial&) { return *this; }    ~NonTrivial() {}  };  EXPECT_TRUE(std::is_trivially_destructible<absl::optional<int>>::value);  EXPECT_TRUE(std::is_trivially_destructible<absl::optional<Trivial>>::value);  EXPECT_FALSE(      std::is_trivially_destructible<absl::optional<NonTrivial>>::value);}TEST(optionalTest, InPlaceConstructor) {  constexpr absl::optional<ConstexprType> opt0{absl::in_place_t()};  static_assert(opt0, "");  static_assert((*opt0).x == ConstexprType::kCtorDefault, "");  constexpr absl::optional<ConstexprType> opt1{absl::in_place_t(), 1};  static_assert(opt1, "");  static_assert((*opt1).x == ConstexprType::kCtorInt, "");#ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST  constexpr absl::optional<ConstexprType> opt2{absl::in_place_t(), {1, 2}};  static_assert(opt2, "");  static_assert((*opt2).x == ConstexprType::kCtorInitializerList, "");#endif  // TODO(absl-team): uncomment these when std::is_constructible<T, Args&&...>  // SFINAE is added to optional::optional(absl::in_place_t, Args&&...).  // struct I {  //   I(absl::in_place_t);  // };  // EXPECT_FALSE((std::is_constructible<absl::optional<I>,  // absl::in_place_t>::value));  // EXPECT_FALSE((std::is_constructible<absl::optional<I>, const  // absl::in_place_t&>::value));}// template<U=T> optional(U&&);TEST(optionalTest, ValueConstructor) {  constexpr absl::optional<int> opt0(0);  static_assert(opt0, "");  static_assert(*opt0 == 0, "");  EXPECT_TRUE((std::is_convertible<int, absl::optional<int>>::value));  // Copy initialization ( = "abc") won't work due to optional(optional&&)  // is not constexpr. Use list initialization instead. This invokes  // absl::optional<ConstexprType>::absl::optional<U>(U&&), with U = const char  // (&) [4], which direct-initializes the ConstexprType value held by the  // optional via ConstexprType::ConstexprType(const char*).  constexpr absl::optional<ConstexprType> opt1 = {"abc"};  static_assert(opt1, "");  static_assert(ConstexprType::kCtorConstChar == (*opt1).x, "");  EXPECT_TRUE(      (std::is_convertible<const char*, absl::optional<ConstexprType>>::value));  // direct initialization  constexpr absl::optional<ConstexprType> opt2{2};  static_assert(opt2, "");  static_assert(ConstexprType::kCtorInt == (*opt2).x, "");  EXPECT_FALSE(      (std::is_convertible<int, absl::optional<ConstexprType>>::value));  // this invokes absl::optional<int>::optional(int&&)  // NOTE: this has different behavior than assignment, e.g.  // "opt3 = {};" clears the optional rather than setting the value to 0  // According to C++17 standard N4659 [over.ics.list] 16.3.3.1.5, (9.2)- "if  // the initializer list has no elements, the implicit conversion is the  // identity conversion", so `optional(int&&)` should be a better match than  // `optional(optional&&)` which is a user-defined conversion.  // Note: GCC 7 has a bug with this overload selection when compiled with  // `-std=c++17`.#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7 && \    __cplusplus == 201703L#define ABSL_GCC7_OVER_ICS_LIST_BUG 1#endif#ifndef ABSL_GCC7_OVER_ICS_LIST_BUG  constexpr absl::optional<int> opt3({});  static_assert(opt3, "");  static_assert(*opt3 == 0, "");#endif  // this invokes the move constructor with a default constructed optional  // because non-template function is a better match than template function.  absl::optional<ConstexprType> opt4({});  EXPECT_FALSE(opt4);}struct Implicit {};struct Explicit {};struct Convert {  Convert(const Implicit&)  // NOLINT(runtime/explicit)      : implicit(true), move(false) {}  Convert(Implicit&&)  // NOLINT(runtime/explicit)      : implicit(true), move(true) {}  explicit Convert(const Explicit&) : implicit(false), move(false) {}  explicit Convert(Explicit&&) : implicit(false), move(true) {}  bool implicit;  bool move;};struct ConvertFromOptional {  ConvertFromOptional(const Implicit&)  // NOLINT(runtime/explicit)      : implicit(true), move(false), from_optional(false) {}  ConvertFromOptional(Implicit&&)  // NOLINT(runtime/explicit)      : implicit(true), move(true), from_optional(false) {}  ConvertFromOptional(      const absl::optional<Implicit>&)  // NOLINT(runtime/explicit)      : implicit(true), move(false), from_optional(true) {}  ConvertFromOptional(absl::optional<Implicit>&&)  // NOLINT(runtime/explicit)      : implicit(true), move(true), from_optional(true) {}  explicit ConvertFromOptional(const Explicit&)      : implicit(false), move(false), from_optional(false) {}  explicit ConvertFromOptional(Explicit&&)      : implicit(false), move(true), from_optional(false) {}  explicit ConvertFromOptional(const absl::optional<Explicit>&)      : implicit(false), move(false), from_optional(true) {}  explicit ConvertFromOptional(absl::optional<Explicit>&&)      : implicit(false), move(true), from_optional(true) {}  bool implicit;  bool move;  bool from_optional;};TEST(optionalTest, ConvertingConstructor) {  absl::optional<Implicit> i_empty;  absl::optional<Implicit> i(absl::in_place);  absl::optional<Explicit> e_empty;  absl::optional<Explicit> e(absl::in_place);  {    // implicitly constructing absl::optional<Convert> from    // absl::optional<Implicit>    absl::optional<Convert> empty = i_empty;    EXPECT_FALSE(empty);    absl::optional<Convert> opt_copy = i;    EXPECT_TRUE(opt_copy);    EXPECT_TRUE(opt_copy->implicit);    EXPECT_FALSE(opt_copy->move);    absl::optional<Convert> opt_move = absl::optional<Implicit>(absl::in_place);    EXPECT_TRUE(opt_move);    EXPECT_TRUE(opt_move->implicit);    EXPECT_TRUE(opt_move->move);  }  {    // explicitly constructing absl::optional<Convert> from    // absl::optional<Explicit>    absl::optional<Convert> empty(e_empty);    EXPECT_FALSE(empty);    absl::optional<Convert> opt_copy(e);    EXPECT_TRUE(opt_copy);    EXPECT_FALSE(opt_copy->implicit);    EXPECT_FALSE(opt_copy->move);    EXPECT_FALSE((std::is_convertible<const absl::optional<Explicit>&,                                      absl::optional<Convert>>::value));    absl::optional<Convert> opt_move{absl::optional<Explicit>(absl::in_place)};    EXPECT_TRUE(opt_move);    EXPECT_FALSE(opt_move->implicit);    EXPECT_TRUE(opt_move->move);    EXPECT_FALSE((std::is_convertible<absl::optional<Explicit>&&,                                      absl::optional<Convert>>::value));  }  {    // implicitly constructing absl::optional<ConvertFromOptional> from    // absl::optional<Implicit> via    // ConvertFromOptional(absl::optional<Implicit>&&) check that    // ConvertFromOptional(Implicit&&) is NOT called    static_assert(        std::is_convertible<absl::optional<Implicit>,                            absl::optional<ConvertFromOptional>>::value,        "");    absl::optional<ConvertFromOptional> opt0 = i_empty;    EXPECT_TRUE(opt0);    EXPECT_TRUE(opt0->implicit);    EXPECT_FALSE(opt0->move);    EXPECT_TRUE(opt0->from_optional);    absl::optional<ConvertFromOptional> opt1 = absl::optional<Implicit>();    EXPECT_TRUE(opt1);    EXPECT_TRUE(opt1->implicit);    EXPECT_TRUE(opt1->move);    EXPECT_TRUE(opt1->from_optional);  }  {    // implicitly constructing absl::optional<ConvertFromOptional> from    // absl::optional<Explicit> via    // ConvertFromOptional(absl::optional<Explicit>&&) check that    // ConvertFromOptional(Explicit&&) is NOT called    absl::optional<ConvertFromOptional> opt0(e_empty);    EXPECT_TRUE(opt0);    EXPECT_FALSE(opt0->implicit);    EXPECT_FALSE(opt0->move);    EXPECT_TRUE(opt0->from_optional);    EXPECT_FALSE(        (std::is_convertible<const absl::optional<Explicit>&,                             absl::optional<ConvertFromOptional>>::value));    absl::optional<ConvertFromOptional> opt1{absl::optional<Explicit>()};    EXPECT_TRUE(opt1);    EXPECT_FALSE(opt1->implicit);    EXPECT_TRUE(opt1->move);    EXPECT_TRUE(opt1->from_optional);    EXPECT_FALSE(        (std::is_convertible<absl::optional<Explicit>&&,                             absl::optional<ConvertFromOptional>>::value));  }}TEST(optionalTest, StructorBasic) {  StructorListener listener;  Listenable::listener = &listener;  {    absl::optional<Listenable> empty;    EXPECT_FALSE(empty);    absl::optional<Listenable> opt0(absl::in_place);    EXPECT_TRUE(opt0);    absl::optional<Listenable> opt1(absl::in_place, 1);    EXPECT_TRUE(opt1);    absl::optional<Listenable> opt2(absl::in_place, 1, 2);    EXPECT_TRUE(opt2);  }  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(1, listener.construct1);  EXPECT_EQ(1, listener.construct2);  EXPECT_EQ(3, listener.destruct);}TEST(optionalTest, CopyMoveStructor) {  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> original(absl::in_place);  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(0, listener.copy);  EXPECT_EQ(0, listener.move);  absl::optional<Listenable> copy(original);  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(1, listener.copy);  EXPECT_EQ(0, listener.move);  absl::optional<Listenable> move(std::move(original));  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(1, listener.copy);  EXPECT_EQ(1, listener.move);}TEST(optionalTest, ListInit) {  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> listinit1(absl::in_place, {1});  absl::optional<Listenable> listinit2(absl::in_place, {1, 2});  EXPECT_EQ(2, listener.listinit);}TEST(optionalTest, AssignFromNullopt) {  absl::optional<int> opt(1);  opt = absl::nullopt;  EXPECT_FALSE(opt);  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> opt1(absl::in_place);  opt1 = absl::nullopt;  EXPECT_FALSE(opt1);  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(1, listener.destruct);  EXPECT_TRUE((      std::is_nothrow_assignable<absl::optional<int>, absl::nullopt_t>::value));  EXPECT_TRUE((std::is_nothrow_assignable<absl::optional<Listenable>,                                          absl::nullopt_t>::value));}TEST(optionalTest, CopyAssignment) {  const absl::optional<int> empty, opt1 = 1, opt2 = 2;  absl::optional<int> empty_to_opt1, opt1_to_opt2, opt2_to_empty;  EXPECT_FALSE(empty_to_opt1);  empty_to_opt1 = empty;  EXPECT_FALSE(empty_to_opt1);  empty_to_opt1 = opt1;  EXPECT_TRUE(empty_to_opt1);  EXPECT_EQ(1, empty_to_opt1.value());  EXPECT_FALSE(opt1_to_opt2);  opt1_to_opt2 = opt1;  EXPECT_TRUE(opt1_to_opt2);  EXPECT_EQ(1, opt1_to_opt2.value());  opt1_to_opt2 = opt2;  EXPECT_TRUE(opt1_to_opt2);  EXPECT_EQ(2, opt1_to_opt2.value());  EXPECT_FALSE(opt2_to_empty);  opt2_to_empty = opt2;  EXPECT_TRUE(opt2_to_empty);  EXPECT_EQ(2, opt2_to_empty.value());  opt2_to_empty = empty;  EXPECT_FALSE(opt2_to_empty);  EXPECT_FALSE(absl::is_copy_assignable<absl::optional<const int>>::value);  EXPECT_TRUE(absl::is_copy_assignable<absl::optional<Copyable>>::value);  EXPECT_FALSE(absl::is_copy_assignable<absl::optional<MoveableThrow>>::value);  EXPECT_FALSE(      absl::is_copy_assignable<absl::optional<MoveableNoThrow>>::value);  EXPECT_FALSE(absl::is_copy_assignable<absl::optional<NonMovable>>::value);  EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value);  EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value);  struct Trivial {    int i;  };  struct NonTrivial {    NonTrivial& operator=(const NonTrivial&) { return *this; }    int i;  };  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);  EXPECT_FALSE(absl::is_copy_assignable<const Trivial>::value);  EXPECT_FALSE(absl::is_copy_assignable<volatile Trivial>::value);  EXPECT_TRUE(absl::is_copy_assignable<NonTrivial>::value);  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value);  // std::optional doesn't support volatile nontrivial types.#ifndef ABSL_HAVE_STD_OPTIONAL  {    StructorListener listener;    Listenable::listener = &listener;    absl::optional<volatile Listenable> empty, set(absl::in_place);    EXPECT_EQ(1, listener.construct0);    absl::optional<volatile Listenable> empty_to_empty, empty_to_set,        set_to_empty(absl::in_place), set_to_set(absl::in_place);    EXPECT_EQ(3, listener.construct0);    empty_to_empty = empty;  // no effect    empty_to_set = set;      // copy construct    set_to_empty = empty;    // destruct    set_to_set = set;        // copy assign    EXPECT_EQ(1, listener.volatile_copy);    EXPECT_EQ(0, listener.volatile_move);    EXPECT_EQ(1, listener.destruct);    EXPECT_EQ(1, listener.volatile_copy_assign);  }#endif  // ABSL_HAVE_STD_OPTIONAL}TEST(optionalTest, MoveAssignment) {  {    StructorListener listener;    Listenable::listener = &listener;    absl::optional<Listenable> empty1, empty2, set1(absl::in_place),        set2(absl::in_place);    EXPECT_EQ(2, listener.construct0);    absl::optional<Listenable> empty_to_empty, empty_to_set,        set_to_empty(absl::in_place), set_to_set(absl::in_place);    EXPECT_EQ(4, listener.construct0);    empty_to_empty = std::move(empty1);    empty_to_set = std::move(set1);    set_to_empty = std::move(empty2);    set_to_set = std::move(set2);    EXPECT_EQ(0, listener.copy);    EXPECT_EQ(1, listener.move);    EXPECT_EQ(1, listener.destruct);    EXPECT_EQ(1, listener.move_assign);  }  // std::optional doesn't support volatile nontrivial types.#ifndef ABSL_HAVE_STD_OPTIONAL  {    StructorListener listener;    Listenable::listener = &listener;    absl::optional<volatile Listenable> empty1, empty2, set1(absl::in_place),        set2(absl::in_place);    EXPECT_EQ(2, listener.construct0);    absl::optional<volatile Listenable> empty_to_empty, empty_to_set,        set_to_empty(absl::in_place), set_to_set(absl::in_place);    EXPECT_EQ(4, listener.construct0);    empty_to_empty = std::move(empty1);  // no effect    empty_to_set = std::move(set1);      // move construct    set_to_empty = std::move(empty2);    // destruct    set_to_set = std::move(set2);        // move assign    EXPECT_EQ(0, listener.volatile_copy);    EXPECT_EQ(1, listener.volatile_move);    EXPECT_EQ(1, listener.destruct);    EXPECT_EQ(1, listener.volatile_move_assign);  }#endif  // ABSL_HAVE_STD_OPTIONAL  EXPECT_FALSE(absl::is_move_assignable<absl::optional<const int>>::value);  EXPECT_TRUE(absl::is_move_assignable<absl::optional<Copyable>>::value);  EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableThrow>>::value);  EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableNoThrow>>::value);  EXPECT_FALSE(absl::is_move_assignable<absl::optional<NonMovable>>::value);  EXPECT_FALSE(      std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value);  EXPECT_TRUE(      std::is_nothrow_move_assignable<absl::optional<MoveableNoThrow>>::value);}struct NoConvertToOptional {  // disable implicit conversion from const NoConvertToOptional&  // to absl::optional<NoConvertToOptional>.  NoConvertToOptional(const NoConvertToOptional&) = delete;};struct CopyConvert {  CopyConvert(const NoConvertToOptional&);  CopyConvert& operator=(const CopyConvert&) = delete;  CopyConvert& operator=(const NoConvertToOptional&);};struct CopyConvertFromOptional {  CopyConvertFromOptional(const NoConvertToOptional&);  CopyConvertFromOptional(const absl::optional<NoConvertToOptional>&);  CopyConvertFromOptional& operator=(const CopyConvertFromOptional&) = delete;  CopyConvertFromOptional& operator=(const NoConvertToOptional&);  CopyConvertFromOptional& operator=(      const absl::optional<NoConvertToOptional>&);};struct MoveConvert {  MoveConvert(NoConvertToOptional&&);  MoveConvert& operator=(const MoveConvert&) = delete;  MoveConvert& operator=(NoConvertToOptional&&);};struct MoveConvertFromOptional {  MoveConvertFromOptional(NoConvertToOptional&&);  MoveConvertFromOptional(absl::optional<NoConvertToOptional>&&);  MoveConvertFromOptional& operator=(const MoveConvertFromOptional&) = delete;  MoveConvertFromOptional& operator=(NoConvertToOptional&&);  MoveConvertFromOptional& operator=(absl::optional<NoConvertToOptional>&&);};// template <typename U = T> absl::optional<T>& operator=(U&& v);TEST(optionalTest, ValueAssignment) {  absl::optional<int> opt;  EXPECT_FALSE(opt);  opt = 42;  EXPECT_TRUE(opt);  EXPECT_EQ(42, opt.value());  opt = absl::nullopt;  EXPECT_FALSE(opt);  opt = 42;  EXPECT_TRUE(opt);  EXPECT_EQ(42, opt.value());  opt = 43;  EXPECT_TRUE(opt);  EXPECT_EQ(43, opt.value());  opt = {};  // this should clear optional  EXPECT_FALSE(opt);  opt = {44};  EXPECT_TRUE(opt);  EXPECT_EQ(44, opt.value());  // U = const NoConvertToOptional&  EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvert>&,                                  const NoConvertToOptional&>::value));  // U = const absl::optional<NoConvertToOptional>&  EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvertFromOptional>&,                                  const NoConvertToOptional&>::value));  // U = const NoConvertToOptional& triggers SFINAE because  // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false  EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvert>&,                                   const NoConvertToOptional&>::value));  // U = NoConvertToOptional  EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvert>&,                                  NoConvertToOptional&&>::value));  // U = const NoConvertToOptional& triggers SFINAE because  // std::is_constructible_v<MoveConvertFromOptional, const  // NoConvertToOptional&> is false  EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,                                   const NoConvertToOptional&>::value));  // U = NoConvertToOptional  EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,                                  NoConvertToOptional&&>::value));  // U = const absl::optional<NoConvertToOptional>&  EXPECT_TRUE(      (std::is_assignable<absl::optional<CopyConvertFromOptional>&,                          const absl::optional<NoConvertToOptional>&>::value));  // U = absl::optional<NoConvertToOptional>  EXPECT_TRUE(      (std::is_assignable<absl::optional<MoveConvertFromOptional>&,                          absl::optional<NoConvertToOptional>&&>::value));}// template <typename U> absl::optional<T>& operator=(const absl::optional<U>&// rhs); template <typename U> absl::optional<T>& operator=(absl::optional<U>&&// rhs);TEST(optionalTest, ConvertingAssignment) {  absl::optional<int> opt_i;  absl::optional<char> opt_c('c');  opt_i = opt_c;  EXPECT_TRUE(opt_i);  EXPECT_EQ(*opt_c, *opt_i);  opt_i = absl::optional<char>();  EXPECT_FALSE(opt_i);  opt_i = absl::optional<char>('d');  EXPECT_TRUE(opt_i);  EXPECT_EQ('d', *opt_i);  absl::optional<std::string> opt_str;  absl::optional<const char*> opt_cstr("abc");  opt_str = opt_cstr;  EXPECT_TRUE(opt_str);  EXPECT_EQ(std::string("abc"), *opt_str);  opt_str = absl::optional<const char*>();  EXPECT_FALSE(opt_str);  opt_str = absl::optional<const char*>("def");  EXPECT_TRUE(opt_str);  EXPECT_EQ(std::string("def"), *opt_str);  // operator=(const absl::optional<U>&) with U = NoConvertToOptional  EXPECT_TRUE(      (std::is_assignable<absl::optional<CopyConvert>,                          const absl::optional<NoConvertToOptional>&>::value));  // operator=(const absl::optional<U>&) with U = NoConvertToOptional  // triggers SFINAE because  // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false  EXPECT_FALSE(      (std::is_assignable<absl::optional<MoveConvert>&,                          const absl::optional<NoConvertToOptional>&>::value));  // operator=(absl::optional<U>&&) with U = NoConvertToOptional  EXPECT_TRUE(      (std::is_assignable<absl::optional<MoveConvert>&,                          absl::optional<NoConvertToOptional>&&>::value));  // operator=(const absl::optional<U>&) with U = NoConvertToOptional triggers  // SFINAE because std::is_constructible_v<MoveConvertFromOptional, const  // NoConvertToOptional&> is false. operator=(U&&) with U = const  // absl::optional<NoConverToOptional>& triggers SFINAE because  // std::is_constructible<MoveConvertFromOptional,  // absl::optional<NoConvertToOptional>&&> is true.  EXPECT_FALSE(      (std::is_assignable<absl::optional<MoveConvertFromOptional>&,                          const absl::optional<NoConvertToOptional>&>::value));}TEST(optionalTest, ResetAndHasValue) {  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> opt;  EXPECT_FALSE(opt);  EXPECT_FALSE(opt.has_value());  opt.emplace();  EXPECT_TRUE(opt);  EXPECT_TRUE(opt.has_value());  opt.reset();  EXPECT_FALSE(opt);  EXPECT_FALSE(opt.has_value());  EXPECT_EQ(1, listener.destruct);  opt.reset();  EXPECT_FALSE(opt);  EXPECT_FALSE(opt.has_value());  constexpr absl::optional<int> empty;  static_assert(!empty.has_value(), "");  constexpr absl::optional<int> nonempty(1);  static_assert(nonempty.has_value(), "");}TEST(optionalTest, Emplace) {  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> opt;  EXPECT_FALSE(opt);  opt.emplace(1);  EXPECT_TRUE(opt);  opt.emplace(1, 2);  EXPECT_EQ(1, listener.construct1);  EXPECT_EQ(1, listener.construct2);  EXPECT_EQ(1, listener.destruct);  absl::optional<std::string> o;  EXPECT_TRUE((std::is_same<std::string&, decltype(o.emplace("abc"))>::value));  std::string& ref = o.emplace("abc");  EXPECT_EQ(&ref, &o.value());}TEST(optionalTest, ListEmplace) {  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> opt;  EXPECT_FALSE(opt);  opt.emplace({1});  EXPECT_TRUE(opt);  opt.emplace({1, 2});  EXPECT_EQ(2, listener.listinit);  EXPECT_EQ(1, listener.destruct);  absl::optional<Listenable> o;  EXPECT_TRUE((std::is_same<Listenable&, decltype(o.emplace({1}))>::value));  Listenable& ref = o.emplace({1});  EXPECT_EQ(&ref, &o.value());}TEST(optionalTest, Swap) {  absl::optional<int> opt_empty, opt1 = 1, opt2 = 2;  EXPECT_FALSE(opt_empty);  EXPECT_TRUE(opt1);  EXPECT_EQ(1, opt1.value());  EXPECT_TRUE(opt2);  EXPECT_EQ(2, opt2.value());  swap(opt_empty, opt1);  EXPECT_FALSE(opt1);  EXPECT_TRUE(opt_empty);  EXPECT_EQ(1, opt_empty.value());  EXPECT_TRUE(opt2);  EXPECT_EQ(2, opt2.value());  swap(opt_empty, opt1);  EXPECT_FALSE(opt_empty);  EXPECT_TRUE(opt1);  EXPECT_EQ(1, opt1.value());  EXPECT_TRUE(opt2);  EXPECT_EQ(2, opt2.value());  swap(opt1, opt2);  EXPECT_FALSE(opt_empty);  EXPECT_TRUE(opt1);  EXPECT_EQ(2, opt1.value());  EXPECT_TRUE(opt2);  EXPECT_EQ(1, opt2.value());  EXPECT_TRUE(noexcept(opt1.swap(opt2)));  EXPECT_TRUE(noexcept(swap(opt1, opt2)));}template <int v>struct DeletedOpAddr {  constexpr static const int value = v;  constexpr DeletedOpAddr() = default;  constexpr const DeletedOpAddr<v>* operator&() const = delete;  // NOLINT  DeletedOpAddr<v>* operator&() = delete;                        // NOLINT};// The static_assert featuring a constexpr call to operator->() is commented out// to document the fact that the current implementation of absl::optional<T>// expects such usecases to be malformed and not compile.TEST(optionalTest, OperatorAddr) {  constexpr const int v = -1;  {  // constexpr    constexpr const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});    static_assert(opt.has_value(), "");    // static_assert(opt->value == v, "");    static_assert((*opt).value == v, "");  }  {  // non-constexpr    const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});    EXPECT_TRUE(opt.has_value());    EXPECT_TRUE(opt->value == v);    EXPECT_TRUE((*opt).value == v);  }}TEST(optionalTest, PointerStuff) {  absl::optional<std::string> opt(absl::in_place, "foo");  EXPECT_EQ("foo", *opt);  const auto& opt_const = opt;  EXPECT_EQ("foo", *opt_const);  EXPECT_EQ(opt->size(), 3);  EXPECT_EQ(opt_const->size(), 3);  constexpr absl::optional<ConstexprType> opt1(1);  static_assert((*opt1).x == ConstexprType::kCtorInt, "");}// gcc has a bug pre 4.9.1 where it doesn't do correct overload resolution// when overloads are const-qualified and *this is an raluve.// Skip that test to make the build green again when using the old compiler.// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59296 is fixed in 4.9.1.#if defined(__GNUC__) && !defined(__clang__)#define GCC_VERSION (__GNUC__ * 10000 \                     + __GNUC_MINOR__ * 100 \                     + __GNUC_PATCHLEVEL__)#if GCC_VERSION < 40901#define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG#endif#endif// MSVC has a bug with "cv-qualifiers in class construction", fixed in 2017. See// https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#bug-fixes// The compiler some incorrectly ingores the cv-qualifier when generating a// class object via a constructor call. For example://// class optional {//   constexpr T&& value() &&;//   constexpr const T&& value() const &&;// }//// using COI = const absl::optional<int>;// static_assert(2 == COI(2).value(), "");  // const &&//// This should invoke the "const &&" overload but since it ignores the const// qualifier it finds the "&&" overload the best candidate.#if defined(_MSC_VER) && _MSC_VER < 1910#define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG#endifTEST(optionalTest, Value) {  using O = absl::optional<std::string>;  using CO = const absl::optional<std::string>;  using OC = absl::optional<const std::string>;  O lvalue(absl::in_place, "lvalue");  CO clvalue(absl::in_place, "clvalue");  OC lvalue_c(absl::in_place, "lvalue_c");  EXPECT_EQ("lvalue", lvalue.value());  EXPECT_EQ("clvalue", clvalue.value());  EXPECT_EQ("lvalue_c", lvalue_c.value());  EXPECT_EQ("xvalue", O(absl::in_place, "xvalue").value());  EXPECT_EQ("xvalue_c", OC(absl::in_place, "xvalue_c").value());#ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG  EXPECT_EQ("cxvalue", CO(absl::in_place, "cxvalue").value());#endif  EXPECT_EQ("&", TypeQuals(lvalue.value()));  EXPECT_EQ("c&", TypeQuals(clvalue.value()));  EXPECT_EQ("c&", TypeQuals(lvalue_c.value()));  EXPECT_EQ("&&", TypeQuals(O(absl::in_place, "xvalue").value()));#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \    !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)  EXPECT_EQ("c&&", TypeQuals(CO(absl::in_place, "cxvalue").value()));#endif  EXPECT_EQ("c&&", TypeQuals(OC(absl::in_place, "xvalue_c").value()));  // test on volatile type  using OV = absl::optional<volatile int>;  OV lvalue_v(absl::in_place, 42);  EXPECT_EQ(42, lvalue_v.value());  EXPECT_EQ(42, OV(42).value());  EXPECT_TRUE((std::is_same<volatile int&, decltype(lvalue_v.value())>::value));  EXPECT_TRUE((std::is_same<volatile int&&, decltype(OV(42).value())>::value));  // test exception throw on value()  absl::optional<int> empty;#ifdef ABSL_HAVE_EXCEPTIONS  EXPECT_THROW((void)empty.value(), absl::bad_optional_access);#else  EXPECT_DEATH((void)empty.value(), "Bad optional access");#endif  // test constexpr value()  constexpr absl::optional<int> o1(1);  static_assert(1 == o1.value(), "");  // const &#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \    !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)  using COI = const absl::optional<int>;  static_assert(2 == COI(2).value(), "");  // const &&#endif}TEST(optionalTest, DerefOperator) {  using O = absl::optional<std::string>;  using CO = const absl::optional<std::string>;  using OC = absl::optional<const std::string>;  O lvalue(absl::in_place, "lvalue");  CO clvalue(absl::in_place, "clvalue");  OC lvalue_c(absl::in_place, "lvalue_c");  EXPECT_EQ("lvalue", *lvalue);  EXPECT_EQ("clvalue", *clvalue);  EXPECT_EQ("lvalue_c", *lvalue_c);  EXPECT_EQ("xvalue", *O(absl::in_place, "xvalue"));  EXPECT_EQ("xvalue_c", *OC(absl::in_place, "xvalue_c"));#ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG  EXPECT_EQ("cxvalue", *CO(absl::in_place, "cxvalue"));#endif  EXPECT_EQ("&", TypeQuals(*lvalue));  EXPECT_EQ("c&", TypeQuals(*clvalue));  EXPECT_EQ("&&", TypeQuals(*O(absl::in_place, "xvalue")));#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \    !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)  EXPECT_EQ("c&&", TypeQuals(*CO(absl::in_place, "cxvalue")));#endif  EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c")));  // test on volatile type  using OV = absl::optional<volatile int>;  OV lvalue_v(absl::in_place, 42);  EXPECT_EQ(42, *lvalue_v);  EXPECT_EQ(42, *OV(42));  EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value));  EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value));  constexpr absl::optional<int> opt1(1);  static_assert(*opt1 == 1, "");#if !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG) && \    !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)  using COI = const absl::optional<int>;  static_assert(*COI(2) == 2, "");#endif}TEST(optionalTest, ValueOr) {  absl::optional<double> opt_empty, opt_set = 1.2;  EXPECT_EQ(42.0, opt_empty.value_or(42));  EXPECT_EQ(1.2, opt_set.value_or(42));  EXPECT_EQ(42.0, absl::optional<double>().value_or(42));  EXPECT_EQ(1.2, absl::optional<double>(1.2).value_or(42));  constexpr absl::optional<double> copt_empty, copt_set = {1.2};  static_assert(42.0 == copt_empty.value_or(42), "");  static_assert(1.2 == copt_set.value_or(42), "");#ifndef ABSL_SKIP_OVERLOAD_TEST_DUE_TO_MSVC_BUG  using COD = const absl::optional<double>;  static_assert(42.0 == COD().value_or(42), "");  static_assert(1.2 == COD(1.2).value_or(42), "");#endif}// make_optional cannot be constexpr until C++17TEST(optionalTest, make_optional) {  auto opt_int = absl::make_optional(42);  EXPECT_TRUE((std::is_same<decltype(opt_int), absl::optional<int>>::value));  EXPECT_EQ(42, opt_int);  StructorListener listener;  Listenable::listener = &listener;  absl::optional<Listenable> opt0 = absl::make_optional<Listenable>();  EXPECT_EQ(1, listener.construct0);  absl::optional<Listenable> opt1 = absl::make_optional<Listenable>(1);  EXPECT_EQ(1, listener.construct1);  absl::optional<Listenable> opt2 = absl::make_optional<Listenable>(1, 2);  EXPECT_EQ(1, listener.construct2);  absl::optional<Listenable> opt3 = absl::make_optional<Listenable>({1});  absl::optional<Listenable> opt4 = absl::make_optional<Listenable>({1, 2});  EXPECT_EQ(2, listener.listinit);  // Constexpr tests on trivially copyable types  // optional<T> has trivial copy/move ctors when T is trivially copyable.  // For nontrivial types with constexpr constructors, we need copy elision in  // C++17 for make_optional to be constexpr.  {    constexpr absl::optional<int> c_opt = absl::make_optional(42);    static_assert(c_opt.value() == 42, "");  }  {    struct TrivialCopyable {      constexpr TrivialCopyable() : x(0) {}      constexpr explicit TrivialCopyable(int i) : x(i) {}      int x;    };    constexpr TrivialCopyable v;    constexpr absl::optional<TrivialCopyable> c_opt0 = absl::make_optional(v);    static_assert((*c_opt0).x == 0, "");    constexpr absl::optional<TrivialCopyable> c_opt1 =        absl::make_optional<TrivialCopyable>();    static_assert((*c_opt1).x == 0, "");    constexpr absl::optional<TrivialCopyable> c_opt2 =        absl::make_optional<TrivialCopyable>(42);    static_assert((*c_opt2).x == 42, "");  }}template <typename T, typename U>void optionalTest_Comparisons_EXPECT_LESS(T x, U y) {  EXPECT_FALSE(x == y);  EXPECT_TRUE(x != y);  EXPECT_TRUE(x < y);  EXPECT_FALSE(x > y);  EXPECT_TRUE(x <= y);  EXPECT_FALSE(x >= y);}template <typename T, typename U>void optionalTest_Comparisons_EXPECT_SAME(T x, U y) {  EXPECT_TRUE(x == y);  EXPECT_FALSE(x != y);  EXPECT_FALSE(x < y);  EXPECT_FALSE(x > y);  EXPECT_TRUE(x <= y);  EXPECT_TRUE(x >= y);}template <typename T, typename U>void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) {  EXPECT_FALSE(x == y);  EXPECT_TRUE(x != y);  EXPECT_FALSE(x < y);  EXPECT_TRUE(x > y);  EXPECT_FALSE(x <= y);  EXPECT_TRUE(x >= y);}template <typename T, typename U, typename V>void TestComparisons() {  absl::optional<T> ae, a2{2}, a4{4};  absl::optional<U> be, b2{2}, b4{4};  V v3 = 3;  // LHS: absl::nullopt, ae, a2, v3, a4  // RHS: absl::nullopt, be, b2, v3, b4  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,absl::nullopt);  optionalTest_Comparisons_EXPECT_SAME(absl::nullopt, be);  optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b2);  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,v3);  optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b4);  optionalTest_Comparisons_EXPECT_SAME(ae, absl::nullopt);  optionalTest_Comparisons_EXPECT_SAME(ae, be);  optionalTest_Comparisons_EXPECT_LESS(ae, b2);  optionalTest_Comparisons_EXPECT_LESS(ae, v3);  optionalTest_Comparisons_EXPECT_LESS(ae, b4);  optionalTest_Comparisons_EXPECT_GREATER(a2, absl::nullopt);  optionalTest_Comparisons_EXPECT_GREATER(a2, be);  optionalTest_Comparisons_EXPECT_SAME(a2, b2);  optionalTest_Comparisons_EXPECT_LESS(a2, v3);  optionalTest_Comparisons_EXPECT_LESS(a2, b4);  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(v3,absl::nullopt);  optionalTest_Comparisons_EXPECT_GREATER(v3, be);  optionalTest_Comparisons_EXPECT_GREATER(v3, b2);  optionalTest_Comparisons_EXPECT_SAME(v3, v3);  optionalTest_Comparisons_EXPECT_LESS(v3, b4);  optionalTest_Comparisons_EXPECT_GREATER(a4, absl::nullopt);  optionalTest_Comparisons_EXPECT_GREATER(a4, be);  optionalTest_Comparisons_EXPECT_GREATER(a4, b2);  optionalTest_Comparisons_EXPECT_GREATER(a4, v3);  optionalTest_Comparisons_EXPECT_SAME(a4, b4);}struct Int1 {  Int1() = default;  Int1(int i) : i(i) {}  // NOLINT(runtime/explicit)  int i;};struct Int2 {  Int2() = default;  Int2(int i) : i(i) {}  // NOLINT(runtime/explicit)  int i;};// comparison between Int1 and Int2constexpr bool operator==(const Int1& lhs, const Int2& rhs) {  return lhs.i == rhs.i;}constexpr bool operator!=(const Int1& lhs, const Int2& rhs) {  return !(lhs == rhs);}constexpr bool operator<(const Int1& lhs, const Int2& rhs) {  return lhs.i < rhs.i;}constexpr bool operator<=(const Int1& lhs, const Int2& rhs) {  return lhs < rhs || lhs == rhs;}constexpr bool operator>(const Int1& lhs, const Int2& rhs) {  return !(lhs <= rhs);}constexpr bool operator>=(const Int1& lhs, const Int2& rhs) {  return !(lhs < rhs);}TEST(optionalTest, Comparisons) {  TestComparisons<int, int, int>();  TestComparisons<const int, int, int>();  TestComparisons<Int1, int, int>();  TestComparisons<int, Int2, int>();  TestComparisons<Int1, Int2, int>();  // compare absl::optional<std::string> with const char*  absl::optional<std::string> opt_str = "abc";  const char* cstr = "abc";  EXPECT_TRUE(opt_str == cstr);  // compare absl::optional<std::string> with absl::optional<const char*>  absl::optional<const char*> opt_cstr = cstr;  EXPECT_TRUE(opt_str == opt_cstr);  // compare absl::optional<std::string> with absl::optional<absl::string_view>  absl::optional<absl::string_view> e1;  absl::optional<std::string> e2;  EXPECT_TRUE(e1 == e2);}TEST(optionalTest, SwapRegression) {  StructorListener listener;  Listenable::listener = &listener;  {    absl::optional<Listenable> a;    absl::optional<Listenable> b(absl::in_place);    a.swap(b);  }  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(1, listener.move);  EXPECT_EQ(2, listener.destruct);  {    absl::optional<Listenable> a(absl::in_place);    absl::optional<Listenable> b;    a.swap(b);  }  EXPECT_EQ(2, listener.construct0);  EXPECT_EQ(2, listener.move);  EXPECT_EQ(4, listener.destruct);}TEST(optionalTest, BigStringLeakCheck) {  constexpr size_t n = 1 << 16;  using OS = absl::optional<std::string>;  OS a;  OS b = absl::nullopt;  OS c = std::string(n, 'c');  std::string sd(n, 'd');  OS d = sd;  OS e(absl::in_place, n, 'e');  OS f;  f.emplace(n, 'f');  OS ca(a);  OS cb(b);  OS cc(c);  OS cd(d);  OS ce(e);  OS oa;  OS ob = absl::nullopt;  OS oc = std::string(n, 'c');  std::string sod(n, 'd');  OS od = sod;  OS oe(absl::in_place, n, 'e');  OS of;  of.emplace(n, 'f');  OS ma(std::move(oa));  OS mb(std::move(ob));  OS mc(std::move(oc));  OS md(std::move(od));  OS me(std::move(oe));  OS mf(std::move(of));  OS aa1;  OS ab1 = absl::nullopt;  OS ac1 = std::string(n, 'c');  std::string sad1(n, 'd');  OS ad1 = sad1;  OS ae1(absl::in_place, n, 'e');  OS af1;  af1.emplace(n, 'f');  OS aa2;  OS ab2 = absl::nullopt;  OS ac2 = std::string(n, 'c');  std::string sad2(n, 'd');  OS ad2 = sad2;  OS ae2(absl::in_place, n, 'e');  OS af2;  af2.emplace(n, 'f');  aa1 = af2;  ab1 = ae2;  ac1 = ad2;  ad1 = ac2;  ae1 = ab2;  af1 = aa2;  OS aa3;  OS ab3 = absl::nullopt;  OS ac3 = std::string(n, 'c');  std::string sad3(n, 'd');  OS ad3 = sad3;  OS ae3(absl::in_place, n, 'e');  OS af3;  af3.emplace(n, 'f');  aa3 = absl::nullopt;  ab3 = absl::nullopt;  ac3 = absl::nullopt;  ad3 = absl::nullopt;  ae3 = absl::nullopt;  af3 = absl::nullopt;  OS aa4;  OS ab4 = absl::nullopt;  OS ac4 = std::string(n, 'c');  std::string sad4(n, 'd');  OS ad4 = sad4;  OS ae4(absl::in_place, n, 'e');  OS af4;  af4.emplace(n, 'f');  aa4 = OS(absl::in_place, n, 'a');  ab4 = OS(absl::in_place, n, 'b');  ac4 = OS(absl::in_place, n, 'c');  ad4 = OS(absl::in_place, n, 'd');  ae4 = OS(absl::in_place, n, 'e');  af4 = OS(absl::in_place, n, 'f');  OS aa5;  OS ab5 = absl::nullopt;  OS ac5 = std::string(n, 'c');  std::string sad5(n, 'd');  OS ad5 = sad5;  OS ae5(absl::in_place, n, 'e');  OS af5;  af5.emplace(n, 'f');  std::string saa5(n, 'a');  std::string sab5(n, 'a');  std::string sac5(n, 'a');  std::string sad52(n, 'a');  std::string sae5(n, 'a');  std::string saf5(n, 'a');  aa5 = saa5;  ab5 = sab5;  ac5 = sac5;  ad5 = sad52;  ae5 = sae5;  af5 = saf5;  OS aa6;  OS ab6 = absl::nullopt;  OS ac6 = std::string(n, 'c');  std::string sad6(n, 'd');  OS ad6 = sad6;  OS ae6(absl::in_place, n, 'e');  OS af6;  af6.emplace(n, 'f');  aa6 = std::string(n, 'a');  ab6 = std::string(n, 'b');  ac6 = std::string(n, 'c');  ad6 = std::string(n, 'd');  ae6 = std::string(n, 'e');  af6 = std::string(n, 'f');  OS aa7;  OS ab7 = absl::nullopt;  OS ac7 = std::string(n, 'c');  std::string sad7(n, 'd');  OS ad7 = sad7;  OS ae7(absl::in_place, n, 'e');  OS af7;  af7.emplace(n, 'f');  aa7.emplace(n, 'A');  ab7.emplace(n, 'B');  ac7.emplace(n, 'C');  ad7.emplace(n, 'D');  ae7.emplace(n, 'E');  af7.emplace(n, 'F');}TEST(optionalTest, MoveAssignRegression) {  StructorListener listener;  Listenable::listener = &listener;  {    absl::optional<Listenable> a;    Listenable b;    a = std::move(b);  }  EXPECT_EQ(1, listener.construct0);  EXPECT_EQ(1, listener.move);  EXPECT_EQ(2, listener.destruct);}TEST(optionalTest, ValueType) {  EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value));  EXPECT_TRUE(      (std::is_same<absl::optional<std::string>::value_type, std::string>::value));  EXPECT_FALSE(      (std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value));}template <typename T>struct is_hash_enabled_for {  template <typename U, typename = decltype(std::hash<U>()(std::declval<U>()))>  static std::true_type test(int);  template <typename U>  static std::false_type test(...);  static constexpr bool value = decltype(test<T>(0))::value;};TEST(optionalTest, Hash) {  std::hash<absl::optional<int>> hash;  std::set<size_t> hashcodes;  hashcodes.insert(hash(absl::nullopt));  for (int i = 0; i < 100; ++i) {    hashcodes.insert(hash(i));  }  EXPECT_GT(hashcodes.size(), 90);  static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");  static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");  static_assert(      absl::type_traits_internal::IsHashable<absl::optional<int>>::value, "");  static_assert(      absl::type_traits_internal::IsHashable<absl::optional<Hashable>>::value,      "");  absl::type_traits_internal::AssertHashEnabled<absl::optional<int>>();  absl::type_traits_internal::AssertHashEnabled<absl::optional<Hashable>>();#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_  static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, "");  static_assert(!absl::type_traits_internal::IsHashable<                    absl::optional<NonHashable>>::value,                "");#endif  // libstdc++ std::optional is missing remove_const_t, i.e. it's using  // std::hash<T> rather than std::hash<std::remove_const_t<T>>.  // Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262#ifndef __GLIBCXX__  static_assert(is_hash_enabled_for<absl::optional<const int>>::value, "");  static_assert(is_hash_enabled_for<absl::optional<const Hashable>>::value, "");  std::hash<absl::optional<const int>> c_hash;  for (int i = 0; i < 100; ++i) {    EXPECT_EQ(hash(i), c_hash(i));  }#endif}struct MoveMeNoThrow {  MoveMeNoThrow() : x(0) {}  [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {    ABSL_RAW_LOG(FATAL, "Should not be called.");    abort();  }  MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}  int x;};struct MoveMeThrow {  MoveMeThrow() : x(0) {}  MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}  MoveMeThrow(MoveMeThrow&& other) : x(other.x) {}  int x;};TEST(optionalTest, NoExcept) {  static_assert(      std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value,      "");#ifndef ABSL_HAVE_STD_OPTIONAL  static_assert(absl::default_allocator_is_nothrow::value ==                    std::is_nothrow_move_constructible<                        absl::optional<MoveMeThrow>>::value,                "");#endif  std::vector<absl::optional<MoveMeNoThrow>> v;  for (int i = 0; i < 10; ++i) v.emplace_back();}struct AnyLike {  AnyLike(AnyLike&&) = default;  AnyLike(const AnyLike&) = default;  template <typename ValueType,            typename T = typename std::decay<ValueType>::type,            typename std::enable_if<                !absl::disjunction<                    std::is_same<AnyLike, T>,                    absl::negation<std::is_copy_constructible<T>>>::value,                int>::type = 0>  AnyLike(ValueType&&) {}  // NOLINT(runtime/explicit)  AnyLike& operator=(AnyLike&&) = default;  AnyLike& operator=(const AnyLike&) = default;  template <typename ValueType,            typename T = typename std::decay<ValueType>::type>  typename std::enable_if<      absl::conjunction<absl::negation<std::is_same<AnyLike, T>>,                        std::is_copy_constructible<T>>::value,      AnyLike&>::type  operator=(ValueType&& /* rhs */) {    return *this;  }};TEST(optionalTest, ConstructionConstraints) {  EXPECT_TRUE((std::is_constructible<AnyLike, absl::optional<AnyLike>>::value));  EXPECT_TRUE(      (std::is_constructible<AnyLike, const absl::optional<AnyLike>&>::value));  EXPECT_TRUE((std::is_constructible<absl::optional<AnyLike>, AnyLike>::value));  EXPECT_TRUE(      (std::is_constructible<absl::optional<AnyLike>, const AnyLike&>::value));  EXPECT_TRUE((std::is_convertible<absl::optional<AnyLike>, AnyLike>::value));  EXPECT_TRUE(      (std::is_convertible<const absl::optional<AnyLike>&, AnyLike>::value));  EXPECT_TRUE((std::is_convertible<AnyLike, absl::optional<AnyLike>>::value));  EXPECT_TRUE(      (std::is_convertible<const AnyLike&, absl::optional<AnyLike>>::value));  EXPECT_TRUE(std::is_move_constructible<absl::optional<AnyLike>>::value);  EXPECT_TRUE(std::is_copy_constructible<absl::optional<AnyLike>>::value);}TEST(optionalTest, AssignmentConstraints) {  EXPECT_TRUE((std::is_assignable<AnyLike&, absl::optional<AnyLike>>::value));  EXPECT_TRUE(      (std::is_assignable<AnyLike&, const absl::optional<AnyLike>&>::value));  EXPECT_TRUE((std::is_assignable<absl::optional<AnyLike>&, AnyLike>::value));  EXPECT_TRUE(      (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value));  EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value);  EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);}}  // namespace
 |