10d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
20d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
30d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarLicensed under the Apache License, Version 2.0 (the "License");
40d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebaryou may not use this file except in compliance with the License.
50d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarYou may obtain a copy of the License at
60d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
70d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    http://www.apache.org/licenses/LICENSE-2.0
80d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
90d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarUnless required by applicable law or agreed to in writing, software
100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebardistributed under the License is distributed on an "AS IS" BASIS,
110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarSee the License for the specific language governing permissions and
130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarlimitations under the License.
140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar==============================================================================*/
150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#include "tensorflow/core/lib/gtl/optional.h"
170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#include <string>
190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#include <utility>
200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#include "tensorflow/core/platform/test.h"
220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#include "tensorflow/core/platform/types.h"
230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarnamespace tensorflow {
250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarnamespace {
260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarusing tensorflow::gtl::in_place;
280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarusing tensorflow::gtl::in_place_t;
290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarusing tensorflow::gtl::make_optional;
307149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerusing tensorflow::gtl::nullopt;
317149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerusing tensorflow::gtl::nullopt_t;
327149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerusing tensorflow::gtl::optional;
330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
347149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowertemplate <typename T>
357149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerstring TypeQuals(T&) {
367149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower  return "&";
377149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower}
387149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowertemplate <typename T>
397149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerstring TypeQuals(T&&) {
407149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower  return "&&";
417149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower}
427149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowertemplate <typename T>
437149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerstring TypeQuals(const T&) {
447149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower  return "c&";
457149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower}
467149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowertemplate <typename T>
477149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlowerstring TypeQuals(const T&&) {
487149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower  return "c&&";
497149a2e2e2f549035f23e21224ee41afe8df3876A. Unique TensorFlower}
500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct StructorListener {
520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int construct0 = 0;
530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int construct1 = 0;
540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int construct2 = 0;
550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int listinit = 0;
560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int copy = 0;
570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int move = 0;
580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int copy_assign = 0;
590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int move_assign = 0;
600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int destruct = 0;
610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct Listenable {
640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static StructorListener* listener;
650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable() { ++listener->construct0; }
670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable(int /*unused*/) { ++listener->construct1; }  // NOLINT
680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }
690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }
700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable(const Listenable& /*unused*/) { ++listener->copy; }
710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable(Listenable&& /*unused*/) { ++listener->move; }  // NOLINT
720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable& operator=(const Listenable& /*unused*/) {
730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    ++listener->copy_assign;
740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    return *this;
750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable& operator=(Listenable&& /*unused*/) {  // NOLINT
770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    ++listener->move_assign;
780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    return *this;
790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ~Listenable() { ++listener->destruct; }
810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarStructorListener* Listenable::listener = nullptr;
840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// clang on macos -- even the latest major version at time of writing (8.x) --
860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// does not like much of our constexpr business.  clang < 3.0 also has trouble.
870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#if defined(__clang__) && defined(__APPLE__)
880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#define SKIP_CONSTEXPR_TEST_DUE_TO_CLANG_BUG
890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct ConstexprType {
920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr ConstexprType() : x(0) {}
930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr explicit ConstexprType(int i) : x(i) {}
940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#ifndef SKIP_CONSTEXPR_TEST_DUE_TO_CLANG_BUG
950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr ConstexprType(std::initializer_list<int> il) : x(il.size()) {}
960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr ConstexprType(const char* s) : x(-1) {}  // NOLINT
980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int x;
990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
1000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct Copyable {
1020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Copyable() {}
1030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Copyable(const Copyable&) {}
1040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Copyable& operator=(const Copyable&) { return *this; }
1050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
1060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct MoveableThrow {
1080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveableThrow() {}
1090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveableThrow(MoveableThrow&&) {}
1100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveableThrow& operator=(MoveableThrow&&) { return *this; }
1110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
1120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct MoveableNoThrow {
1140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveableNoThrow() {}
1150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveableNoThrow(MoveableNoThrow&&) noexcept {}
1160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }
1170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
1180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct NonMovable {
1200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  NonMovable() {}
1210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  NonMovable(const NonMovable&) = delete;
1220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  NonMovable& operator=(const NonMovable&) = delete;
1230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  NonMovable(NonMovable&&) = delete;
1240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  NonMovable& operator=(NonMovable&&) = delete;
1250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
1260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, DefaultConstructor) {
1280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty;
1290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!empty);
1300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> cempty;
1310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(!cempty.has_value(), "");
1320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_nothrow_default_constructible<optional<int>>::value);
1330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
1340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, NullOptConstructor) {
1360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty(nullopt);
1370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!empty);
1380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // Creating a temporary nullopt_t object instead of using nullopt because
1390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // nullopt cannot be constexpr and have external linkage at the same time.
1400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> cempty{nullopt_t(nullopt_t::init)};
1410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(!cempty.has_value(), "");
1420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_nothrow_constructible<optional<int>, nullopt_t>::value));
1430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
1440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, CopyConstructor) {
1460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty, opt42 = 42;
1470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty_copy(empty);
1480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!empty_copy);
1490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> opt42_copy(opt42);
1500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt42_copy);
1510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42, opt42_copy);
1520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // test copyablility
1530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_copy_constructible<optional<int>>::value);
1540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_copy_constructible<optional<Copyable>>::value);
1550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_copy_constructible<optional<MoveableThrow>>::value);
1560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_copy_constructible<optional<MoveableNoThrow>>::value);
1570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_copy_constructible<optional<NonMovable>>::value);
1580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
1590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, MoveConstructor) {
1610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty, opt42 = 42;
1620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty_move(std::move(empty));
1630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!empty_move);
1640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> opt42_move(std::move(opt42));
1650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt42_move);
1660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42, opt42_move);
1670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // test movability
1680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_constructible<optional<int>>::value);
1690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_constructible<optional<Copyable>>::value);
1700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_constructible<optional<MoveableThrow>>::value);
1710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_constructible<optional<MoveableNoThrow>>::value);
1720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_move_constructible<optional<NonMovable>>::value);
1730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // test noexcept
1740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_nothrow_move_constructible<optional<int>>::value);
1750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(
1760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      std::is_nothrow_move_constructible<optional<MoveableThrow>>::value);
1770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(
1780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      std::is_nothrow_move_constructible<optional<MoveableNoThrow>>::value);
1790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
1800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, Destructor) {
1820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  struct Trivial {};
1830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  struct NonTrivial {
1850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    ~NonTrivial() {}
1860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  };
1870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_trivially_destructible<optional<int>>::value);
1890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_trivially_destructible<optional<Trivial>>::value);
1900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_trivially_destructible<optional<NonTrivial>>::value);
1910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
1920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
1930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, InPlaceConstructor) {
1940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<ConstexprType> opt0{in_place_t()};
1950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt0, "");
1960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt0->x == 0, "");
1970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<ConstexprType> opt1{in_place_t(), 1};
1980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt1, "");
1990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt1->x == 1, "");
2000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#ifndef SKIP_CONSTEXPR_TEST_DUE_TO_CLANG_BUG
2010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<ConstexprType> opt2{in_place_t(), {1, 2}};
2020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt2, "");
2030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt2->x == 2, "");
2040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
2050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // TODO(b/34201852): uncomment these when std::is_constructible<T, Args&&...>
2070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // SFINAE is added to optional::optional(in_place_t, Args&&...).
2080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // struct I {
2090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  //   I(in_place_t);
2100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // };
2110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // EXPECT_FALSE((std::is_constructible<optional<I>, in_place_t>::value));
2130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // EXPECT_FALSE((std::is_constructible<optional<I>, const
2140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // in_place_t&>::value));
2150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
2160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// template<U=T> optional(U&&);
2180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ValueConstructor) {
2190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> opt0(0);
2200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt0, "");
2210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(*opt0 == 0, "");
2220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_convertible<int, optional<int>>::value));
2230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // Copy initialization ( = "abc") won't work due to optional(optional&&)
2240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // is not constexpr. Use list initialization instead. This invokes
2250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // optional<ConstexprType>::optional<U>(U&&), with U = const char (&) [4],
2260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // which direct-initializes the ConstexprType value held by the optional
2270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // via ConstexprType::ConstexprType(const char*).
2280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<ConstexprType> opt1 = {"abc"};
2290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt1, "");
2300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(-1 == opt1->x, "");
2310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(
2320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      (std::is_convertible<const char*, optional<ConstexprType>>::value));
2330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // direct initialization
2340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<ConstexprType> opt2{2};
2350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt2, "");
2360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(2 == opt2->x, "");
2370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((std::is_convertible<int, optional<ConstexprType>>::value));
2380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // this invokes optional<int>::optional(int&&)
2400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // NOTE: this has different behavior than assignment, e.g.
2410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // "opt3 = {};" clears the optional rather than setting the value to 0
2420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> opt3({});
2430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt3, "");
2440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(*opt3 == 0, "");
2450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // this invokes the move constructor with a default constructed optional
2470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // because non-template function is a better match than template function.
2480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<ConstexprType> opt4({});
2490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt4);
2500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
2510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct Implicit {};
2530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct Explicit {};
2550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct Convert {
2570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Convert(const Implicit&)  // NOLINT(runtime/explicit)
2580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(true), move(false) {}
2590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Convert(Implicit&&)  // NOLINT(runtime/explicit)
2600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(true), move(true) {}
2610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  explicit Convert(const Explicit&) : implicit(false), move(false) {}
2620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  explicit Convert(Explicit&&) : implicit(false), move(true) {}
2630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  bool implicit;
2650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  bool move;
2660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
2670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct ConvertFromOptional {
2690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ConvertFromOptional(const Implicit&)  // NOLINT(runtime/explicit)
2700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(true), move(false), from_optional(false) {}
2710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ConvertFromOptional(Implicit&&)  // NOLINT(runtime/explicit)
2720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(true), move(true), from_optional(false) {}
2730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ConvertFromOptional(const optional<Implicit>&)  // NOLINT(runtime/explicit)
2740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(true), move(false), from_optional(true) {}
2750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ConvertFromOptional(optional<Implicit>&&)  // NOLINT(runtime/explicit)
2760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(true), move(true), from_optional(true) {}
2770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  explicit ConvertFromOptional(const Explicit&)
2780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(false), move(false), from_optional(false) {}
2790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  explicit ConvertFromOptional(Explicit&&)
2800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(false), move(true), from_optional(false) {}
2810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  explicit ConvertFromOptional(const optional<Explicit>&)
2820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(false), move(false), from_optional(true) {}
2830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  explicit ConvertFromOptional(optional<Explicit>&&)
2840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      : implicit(false), move(true), from_optional(true) {}
2850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  bool implicit;
2870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  bool move;
2880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  bool from_optional;
2890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
2900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
2910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ConvertingConstructor) {
2920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Implicit> i_empty;
2930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Implicit> i(in_place);
2940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Explicit> e_empty;
2950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Explicit> e(in_place);
2960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
2970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // implicitly constructing optional<Convert> from optional<Implicit>
2980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Convert> empty = i_empty;
2990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(!!empty);
3000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Convert> opt_copy = i;
3010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt_copy);
3020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt_copy->implicit);
3030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt_copy->move);
3040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Convert> opt_move = optional<Implicit>(in_place);
3050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt_move);
3060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt_move->implicit);
3070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt_move->move);
3080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
3090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
3100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // explicitly constructing optional<Convert> from optional<Explicit>
3110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Convert> empty(e_empty);
3120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(!!empty);
3130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Convert> opt_copy(e);
3140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt_copy);
3150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt_copy->implicit);
3160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt_copy->move);
3170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE((std::is_convertible<const optional<Explicit>&,
3180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                      optional<Convert>>::value));
3190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Convert> opt_move{optional<Explicit>(in_place)};
3200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt_move);
3210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt_move->implicit);
3220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt_move->move);
3230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(
3240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar        (std::is_convertible<optional<Explicit>&&, optional<Convert>>::value));
3250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
3260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
3270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // implicitly constructing optional<ConvertFromOptional> from
3280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // optional<Implicit> via ConvertFromOptional(optional<Implicit>&&)
3290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // check that ConvertFromOptional(Implicit&&) is NOT called
3300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    static_assert(
3310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar        gtl::internal_optional::is_constructible_convertible_from_optional<
3320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar            ConvertFromOptional, Implicit>::value,
3330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar        "");
3340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<ConvertFromOptional> opt0 = i_empty;
3350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt0);
3360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt0->implicit);
3370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt0->move);
3380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt0->from_optional);
3390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<ConvertFromOptional> opt1 = optional<Implicit>();
3400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt1);
3410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt1->implicit);
3420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt1->move);
3430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt1->from_optional);
3440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
3450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
3460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // implicitly constructing optional<ConvertFromOptional> from
3470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // optional<Explicit> via ConvertFromOptional(optional<Explicit>&&)
3480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    // check that ConvertFromOptional(Explicit&&) is NOT called
3490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<ConvertFromOptional> opt0(e_empty);
3500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt0);
3510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt0->implicit);
3520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt0->move);
3530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt0->from_optional);
3540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE((std::is_convertible<const optional<Explicit>&,
3550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                      optional<ConvertFromOptional>>::value));
3560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<ConvertFromOptional> opt1{optional<Explicit>()};
3570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt1);
3580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(opt1->implicit);
3590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt1->move);
3600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(opt1->from_optional);
3610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE((std::is_convertible<optional<Explicit>&&,
3620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                      optional<ConvertFromOptional>>::value));
3630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
3640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
3650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
3660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, StructorBasic) {
3670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
3680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
3690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
3700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> empty;
3710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_FALSE(!!empty);
3720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> opt0(in_place);
3730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt0);
3740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> opt1(in_place, 1);
3750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt1);
3760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> opt2(in_place, 1, 2);
3770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    EXPECT_TRUE(!!opt2);
3780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
3790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
3800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct1);
3810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct2);
3820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(3, listener.destruct);
3830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
3840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
3850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, CopyMoveStructor) {
3860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
3870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
3880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> original(in_place);
3890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
3900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(0, listener.copy);
3910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(0, listener.move);
3920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> copy(original);
3930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
3940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.copy);
3950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(0, listener.move);
3960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> move(std::move(original));
3970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
3980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.copy);
3990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.move);
4000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
4010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ListInit) {
4030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
4040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
4050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> listinit1(in_place, {1});
4060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> listinit2(in_place, {1, 2});
4070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.listinit);
4080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
4090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, AssignFromNullopt) {
4110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> opt(1);
4120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = nullopt;
4130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
4140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
4160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
4170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt1(in_place);
4180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt1 = nullopt;
4190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(opt1);
4200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
4210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.destruct);
4220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_nothrow_assignable<optional<int>, nullopt_t>::value));
4240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(
4250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      (std::is_nothrow_assignable<optional<Listenable>, nullopt_t>::value));
4260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
4270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, CopyAssignment) {
4290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  const optional<int> empty, opt1 = 1, opt2 = 2;
4300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> empty_to_opt1, opt1_to_opt2, opt2_to_empty;
4310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!empty_to_opt1);
4330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  empty_to_opt1 = empty;
4340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!empty_to_opt1);
4350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  empty_to_opt1 = opt1;
4360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!empty_to_opt1);
4370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, empty_to_opt1.value());
4380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt1_to_opt2);
4400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt1_to_opt2 = opt1;
4410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt1_to_opt2);
4420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, opt1_to_opt2.value());
4430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt1_to_opt2 = opt2;
4440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt1_to_opt2);
4450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, opt1_to_opt2.value());
4460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt2_to_empty);
4480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt2_to_empty = opt2;
4490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt2_to_empty);
4500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, opt2_to_empty.value());
4510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt2_to_empty = empty;
4520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt2_to_empty);
4530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_copy_assignable<optional<Copyable>>::value);
4550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_copy_assignable<optional<MoveableThrow>>::value);
4560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_copy_assignable<optional<MoveableNoThrow>>::value);
4570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_copy_assignable<optional<NonMovable>>::value);
4580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
4590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, MoveAssignment) {
4610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
4620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
4630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> empty1, empty2, set1(in_place), set2(in_place);
4650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.construct0);
4660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> empty_to_empty, empty_to_set, set_to_empty(in_place),
4670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      set_to_set(in_place);
4680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(4, listener.construct0);
4690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  empty_to_empty = std::move(empty1);
4700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  empty_to_set = std::move(set1);
4710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  set_to_empty = std::move(empty2);
4720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  set_to_set = std::move(set2);
4730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(0, listener.copy);
4740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.move);
4750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.destruct);
4760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.move_assign);
4770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_assignable<optional<Copyable>>::value);
4790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_assignable<optional<MoveableThrow>>::value);
4800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(std::is_move_assignable<optional<MoveableNoThrow>>::value);
4810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_move_assignable<optional<NonMovable>>::value);
4820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(std::is_nothrow_move_assignable<optional<MoveableThrow>>::value);
4840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(
4850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      std::is_nothrow_move_assignable<optional<MoveableNoThrow>>::value);
4860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
4870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct NoConvertToOptional {
4890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // disable implicit conversion from const NoConvertToOptional&
4900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // to optional<NoConvertToOptional>.
4910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  NoConvertToOptional(const NoConvertToOptional&) = delete;
4920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
4930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
4940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct CopyConvert {
4950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvert(const NoConvertToOptional&);
4960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvert& operator=(const CopyConvert&) = delete;
4970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvert& operator=(const NoConvertToOptional&);
4980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
4990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct CopyConvertFromOptional {
5010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvertFromOptional(const NoConvertToOptional&);
5020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvertFromOptional(const optional<NoConvertToOptional>&);
5030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvertFromOptional& operator=(const CopyConvertFromOptional&) = delete;
5040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvertFromOptional& operator=(const NoConvertToOptional&);
5050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CopyConvertFromOptional& operator=(const optional<NoConvertToOptional>&);
5060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
5070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct MoveConvert {
5090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvert(NoConvertToOptional&&);
5100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvert& operator=(const MoveConvert&) = delete;
5110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvert& operator=(NoConvertToOptional&&);
5120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
5130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct MoveConvertFromOptional {
5150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvertFromOptional(NoConvertToOptional&&);
5160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvertFromOptional(optional<NoConvertToOptional>&&);
5170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvertFromOptional& operator=(const MoveConvertFromOptional&) = delete;
5180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvertFromOptional& operator=(NoConvertToOptional&&);
5190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveConvertFromOptional& operator=(optional<NoConvertToOptional>&&);
5200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
5210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// template <class U = T> optional<T>& operator=(U&& v);
5230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ValueAssignment) {
5240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> opt;
5250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
5260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = 42;
5270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
5280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42, opt.value());
5290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = nullopt;
5300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
5310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = 42;
5320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
5330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42, opt.value());
5340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = 43;
5350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
5360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(43, opt.value());
5370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = {};  // this should clear optional
5380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
5390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt = {44};
5410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
5420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(44, opt.value());
5430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = const NoConvertToOptional&
5450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_assignable<optional<CopyConvert>&,
5460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                  const NoConvertToOptional&>::value));
5470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = const optional<NoConvertToOptional>&
5480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_assignable<optional<CopyConvertFromOptional>&,
5490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                  const NoConvertToOptional&>::value));
5500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = const NoConvertToOptional& triggers SFINAE because
5510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
5520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((std::is_assignable<optional<MoveConvert>&,
5530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                   const NoConvertToOptional&>::value));
5540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = NoConvertToOptional
5550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_assignable<optional<MoveConvert>&,
5560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                  NoConvertToOptional&&>::value));
5570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = const NoConvertToOptional& triggers SFINAE because
5580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // std::is_constructible_v<MoveConvertFromOptional, const
5590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // NoConvertToOptional&> is false
5600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((std::is_assignable<optional<MoveConvertFromOptional>&,
5610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                   const NoConvertToOptional&>::value));
5620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = NoConvertToOptional
5630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_assignable<optional<MoveConvertFromOptional>&,
5640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                  NoConvertToOptional&&>::value));
5650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = const optional<NoConvertToOptional>&
5660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(
5670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      (std::is_assignable<optional<CopyConvertFromOptional>&,
5680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                          const optional<NoConvertToOptional>&>::value));
5690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // U = optional<NoConvertToOptional>
5700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_assignable<optional<MoveConvertFromOptional>&,
5710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                  optional<NoConvertToOptional>&&>::value));
5720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
5730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// template <class U> optional<T>& operator=(const optional<U>& rhs);
5750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// template <class U> optional<T>& operator=(optional<U>&& rhs);
5760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ConvertingAssignment) {
5770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> opt_i;
5780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<char> opt_c('c');
5790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt_i = opt_c;
5800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt_i);
5810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(*opt_c, *opt_i);
5820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt_i = optional<char>();
5830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt_i);
5840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt_i = optional<char>('d');
5850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt_i);
5860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ('d', *opt_i);
5870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<string> opt_str;
5890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<const char*> opt_cstr("abc");
5900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt_str = opt_cstr;
5910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt_str);
5920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(string("abc"), *opt_str);
5930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt_str = optional<const char*>();
5940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt_str);
5950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt_str = optional<const char*>("def");
5960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt_str);
5970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(string("def"), *opt_str);
5980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
5990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // operator=(const optional<U>&) with U = NoConvertToOptional
6000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(
6010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      (std::is_assignable<optional<CopyConvert>,
6020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                          const optional<NoConvertToOptional>&>::value));
6030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // operator=(const optional<U>&) with U = NoConvertToOptional
6040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // triggers SFINAE because
6050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
6060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(
6070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      (std::is_assignable<optional<MoveConvert>&,
6080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                          const optional<NoConvertToOptional>&>::value));
6090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // operator=(optional<U>&&) with U = NoConvertToOptional
6100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_assignable<optional<MoveConvert>&,
6110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                                  optional<NoConvertToOptional>&&>::value));
6120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // operator=(const optional<U>&) with U = NoConvertToOptional triggers SFINAE
6130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // because std::is_constructible_v<MoveConvertFromOptional,
6140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // const NoConvertToOptional&> is false.
6150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // operator=(U&&) with U = const optional<NoConverToOptional>& triggers SFINAE
6160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // because std::is_constructible<MoveConvertFromOptional,
6170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // optional<NoConvertToOptional>&&> is true.
6180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(
6190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      (std::is_assignable<optional<MoveConvertFromOptional>&,
6200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar                          const optional<NoConvertToOptional>&>::value));
6210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
6220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
6230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ResetAndHasValue) {
6240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
6250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
6260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt;
6270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
6280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(opt.has_value());
6290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.emplace();
6300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
6310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(opt.has_value());
6320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.reset();
6330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
6340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(opt.has_value());
6350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.destruct);
6360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.reset();
6370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
6380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(opt.has_value());
6390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
6400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> empty;
6410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(!empty.has_value(), "");
6420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> nonempty(1);
6430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(nonempty.has_value(), "");
6440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
6450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
6460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, Emplace) {
6470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
6480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
6490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt;
6500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
6510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.emplace(1);
6520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
6530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.emplace(1, 2);
6540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct1);
6550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct2);
6560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.destruct);
6570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
6580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
6590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ListEmplace) {
6600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
6610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
6620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt;
6630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt);
6640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.emplace({1});
6650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt);
6660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  opt.emplace({1, 2});
6670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.listinit);
6680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.destruct);
6690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
6700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
6710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, Swap) {
6720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> opt_empty, opt1 = 1, opt2 = 2;
6730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt_empty);
6740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt1);
6750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, opt1.value());
6760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt2);
6770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, opt2.value());
6780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  swap(opt_empty, opt1);
6790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt1);
6800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt_empty);
6810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, opt_empty.value());
6820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt2);
6830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, opt2.value());
6840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  swap(opt_empty, opt1);
6850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt_empty);
6860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt1);
6870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, opt1.value());
6880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt2);
6890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, opt2.value());
6900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  swap(opt1, opt2);
6910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE(!!opt_empty);
6920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt1);
6930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, opt1.value());
6940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(!!opt2);
6950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, opt2.value());
6960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
6970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(noexcept(opt1.swap(opt2)));
6980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE(noexcept(swap(opt1, opt2)));
6990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
7000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, PointerStuff) {
7020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<string> opt(in_place, "foo");
7030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("foo", *opt);
7040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  const auto& opt_const = opt;
7050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("foo", *opt_const);
7060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(opt->size(), 3);
7070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(opt_const->size(), 3);
7080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<ConstexprType> opt1(1);
7100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(opt1->x == 1, "");
7110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
7120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// gcc has a bug pre 4.9 where it doesn't do correct overload resolution
7140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// between rvalue reference qualified member methods. Skip that test to make
7150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// the build green again when using the old compiler.
7160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#if defined(__GNUC__) && !defined(__clang__)
7170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
7180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#define SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
7190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
7200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
7210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, Value) {
7230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using O = optional<string>;
7240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using CO = const optional<string>;
7250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  O lvalue(in_place, "lvalue");
7260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CO clvalue(in_place, "clvalue");
7270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("lvalue", lvalue.value());
7280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("clvalue", clvalue.value());
7290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("xvalue", O(in_place, "xvalue").value());
7300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#ifndef SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
7310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("cxvalue", CO(in_place, "cxvalue").value());
7320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("&", TypeQuals(lvalue.value()));
7330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("c&", TypeQuals(clvalue.value()));
7340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("&&", TypeQuals(O(in_place, "xvalue").value()));
7350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("c&&", TypeQuals(CO(in_place, "cxvalue").value()));
7360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
7370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
7380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, DerefOperator) {
7400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using O = optional<string>;
7410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using CO = const optional<string>;
7420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  O lvalue(in_place, "lvalue");
7430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  CO clvalue(in_place, "clvalue");
7440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("lvalue", *lvalue);
7450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("clvalue", *clvalue);
7460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("xvalue", *O(in_place, "xvalue"));
7470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#ifndef SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
7480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("cxvalue", *CO(in_place, "cxvalue"));
7490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("&", TypeQuals(*lvalue));
7500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("c&", TypeQuals(*clvalue));
7510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("&&", TypeQuals(*O(in_place, "xvalue")));
7520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ("c&&", TypeQuals(*CO(in_place, "cxvalue")));
7530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
7540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<int> opt1(1);
7560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(*opt1 == 1, "");
7570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#if !defined(SKIP_CONSTEXPR_TEST_DUE_TO_CLANG_BUG) && \
7590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    !defined(SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
7600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using COI = const optional<int>;
7610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(*COI(2) == 2, "");
7620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
7630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
7640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ValueOr) {
7660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<double> opt_empty, opt_set = 1.2;
7670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42.0, opt_empty.value_or(42));
7680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1.2, opt_set.value_or(42));
7690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42.0, optional<double>().value_or(42));
7700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1.2, optional<double>(1.2).value_or(42));
7710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#ifndef SKIP_CONSTEXPR_TEST_DUE_TO_CLANG_BUG
7730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<double> copt_empty;
7740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(42.0 == copt_empty.value_or(42), "");
7750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr optional<double> copt_set = {1.2};
7770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(1.2 == copt_set.value_or(42), "");
7780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using COD = const optional<double>;
7800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(42.0 == COD().value_or(42), "");
7810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(1.2 == COD(1.2).value_or(42), "");
7820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#endif
7830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
7840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar// make_optional cannot be constexpr until C++17
7860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, make_optional) {
7870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  auto opt_int = make_optional(42);
7880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_same<decltype(opt_int), optional<int>>::value));
7890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(42, opt_int);
7900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
7920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
7930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
7940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt0 = make_optional<Listenable>();
7950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
7960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt1 = make_optional<Listenable>(1);
7970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct1);
7980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt2 = make_optional<Listenable>(1, 2);
7990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct2);
8000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt3 = make_optional<Listenable>({1});
8010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<Listenable> opt4 = make_optional<Listenable>({1, 2});
8020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.listinit);
8030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
8040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, Comparisons) {
8060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optional<int> ae, be, a2 = 2, b2 = 2, a4 = 4, b4 = 4;
8070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#define optionalTest_Comparisons_EXPECT_LESS(x, y) \
8090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) == (y));                        \
8100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) != (y));                         \
8110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) < (y));                          \
8120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) > (y));                         \
8130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) <= (y));                         \
8140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) >= (y));
8150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#define optionalTest_Comparisons_EXPECT_SAME(x, y) \
8170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) == (y));                         \
8180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) != (y));                        \
8190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) < (y));                         \
8200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) > (y));                         \
8210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) <= (y));                         \
8220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) >= (y));
8230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar#define optionalTest_Comparisons_EXPECT_GREATER(x, y) \
8250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) == (y));                           \
8260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) != (y));                            \
8270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) < (y));                            \
8280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) > (y));                             \
8290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((x) <= (y));                           \
8300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((x) >= (y));
8310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // LHS: nullopt, ae, a2, 3, a4
8330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // RHS: nullopt, be, b2, 3, b4
8340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(nullopt,nullopt);
8360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_SAME(nullopt, be);
8370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(nullopt, b2);
8380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(nullopt,3);
8390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(nullopt, b4);
8400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_SAME(ae, nullopt);
8420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_SAME(ae, be);
8430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(ae, b2);
8440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(ae, 3);
8450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(ae, b4);
8460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(a2, nullopt);
8480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(a2, be);
8490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_SAME(a2, b2);
8500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(a2, 3);
8510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(a2, b4);
8520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(3,nullopt);
8540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(3, be);
8550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(3, b2);
8560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_SAME(3, 3);
8570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_LESS(3, b4);
8580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(a4, nullopt);
8600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(a4, be);
8610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(a4, b2);
8620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_GREATER(a4, 3);
8630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  optionalTest_Comparisons_EXPECT_SAME(a4, b4);
8640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
8650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, SwapRegression) {
8670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
8680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
8690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
8710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> a;
8720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> b(in_place);
8730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    a.swap(b);
8740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
8750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
8770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.move);
8780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.destruct);
8790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
8810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> a(in_place);
8820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> b;
8830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    a.swap(b);
8840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
8850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.construct0);
8870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.move);
8880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(4, listener.destruct);
8890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
8900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, BigStringLeakCheck) {
8920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  constexpr size_t n = 1 << 16;
8930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  using OS = optional<string>;
8950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
8960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS a;
8970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS b = nullopt;
8980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS c = string(n, 'c');
8990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sd(n, 'd');
9000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS d = sd;
9010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS e(in_place, n, 'e');
9020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS f;
9030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  f.emplace(n, 'f');
9040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ca(a);
9060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS cb(b);
9070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS cc(c);
9080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS cd(d);
9090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ce(e);
9100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS oa;
9120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ob = nullopt;
9130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS oc = string(n, 'c');
9140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sod(n, 'd');
9150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS od = sod;
9160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS oe(in_place, n, 'e');
9170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS of;
9180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  of.emplace(n, 'f');
9190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ma(std::move(oa));
9210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS mb(std::move(ob));
9220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS mc(std::move(oc));
9230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS md(std::move(od));
9240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS me(std::move(oe));
9250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS mf(std::move(of));
9260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa1;
9280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab1 = nullopt;
9290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac1 = string(n, 'c');
9300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad1(n, 'd');
9310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad1 = sad1;
9320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae1(in_place, n, 'e');
9330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af1;
9340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af1.emplace(n, 'f');
9350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa2;
9370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab2 = nullopt;
9380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac2 = string(n, 'c');
9390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad2(n, 'd');
9400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad2 = sad2;
9410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae2(in_place, n, 'e');
9420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af2;
9430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af2.emplace(n, 'f');
9440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  aa1 = af2;
9460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ab1 = ae2;
9470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ac1 = ad2;
9480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ad1 = ac2;
9490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ae1 = ab2;
9500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af1 = aa2;
9510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa3;
9530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab3 = nullopt;
9540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac3 = string(n, 'c');
9550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad3(n, 'd');
9560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad3 = sad3;
9570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae3(in_place, n, 'e');
9580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af3;
9590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af3.emplace(n, 'f');
9600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  aa3 = nullopt;
9620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ab3 = nullopt;
9630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ac3 = nullopt;
9640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ad3 = nullopt;
9650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ae3 = nullopt;
9660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af3 = nullopt;
9670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa4;
9690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab4 = nullopt;
9700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac4 = string(n, 'c');
9710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad4(n, 'd');
9720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad4 = sad4;
9730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae4(in_place, n, 'e');
9740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af4;
9750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af4.emplace(n, 'f');
9760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  aa4 = OS(in_place, n, 'a');
9780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ab4 = OS(in_place, n, 'b');
9790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ac4 = OS(in_place, n, 'c');
9800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ad4 = OS(in_place, n, 'd');
9810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ae4 = OS(in_place, n, 'e');
9820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af4 = OS(in_place, n, 'f');
9830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa5;
9850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab5 = nullopt;
9860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac5 = string(n, 'c');
9870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad5(n, 'd');
9880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad5 = sad5;
9890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae5(in_place, n, 'e');
9900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af5;
9910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af5.emplace(n, 'f');
9920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
9930d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string saa5(n, 'a');
9940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sab5(n, 'a');
9950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sac5(n, 'a');
9960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad52(n, 'a');
9970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sae5(n, 'a');
9980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string saf5(n, 'a');
9990d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10000d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  aa5 = saa5;
10010d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ab5 = sab5;
10020d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ac5 = sac5;
10030d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ad5 = sad52;
10040d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ae5 = sae5;
10050d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af5 = saf5;
10060d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10070d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa6;
10080d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab6 = nullopt;
10090d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac6 = string(n, 'c');
10100d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad6(n, 'd');
10110d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad6 = sad6;
10120d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae6(in_place, n, 'e');
10130d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af6;
10140d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af6.emplace(n, 'f');
10150d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10160d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  aa6 = string(n, 'a');
10170d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ab6 = string(n, 'b');
10180d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ac6 = string(n, 'c');
10190d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ad6 = string(n, 'd');
10200d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ae6 = string(n, 'e');
10210d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af6 = string(n, 'f');
10220d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10230d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS aa7;
10240d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ab7 = nullopt;
10250d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ac7 = string(n, 'c');
10260d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  string sad7(n, 'd');
10270d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ad7 = sad7;
10280d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS ae7(in_place, n, 'e');
10290d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  OS af7;
10300d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af7.emplace(n, 'f');
10310d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10320d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  aa7.emplace(n, 'A');
10330d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ab7.emplace(n, 'B');
10340d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ac7.emplace(n, 'C');
10350d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ad7.emplace(n, 'D');
10360d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  ae7.emplace(n, 'E');
10370d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  af7.emplace(n, 'F');
10380d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
10390d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10400d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, MoveAssignRegression) {
10410d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  StructorListener listener;
10420d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  Listenable::listener = &listener;
10430d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10440d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  {
10450d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    optional<Listenable> a;
10460d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    Listenable b;
10470d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    a = std::move(b);
10480d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
10490d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10500d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.construct0);
10510d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(1, listener.move);
10520d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_EQ(2, listener.destruct);
10530d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
10540d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10550d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, ValueType) {
10560d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_same<optional<int>::value_type, int>::value));
10570d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_TRUE((std::is_same<optional<string>::value_type, string>::value));
10580d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_FALSE((std::is_same<optional<int>::value_type, nullopt_t>::value));
10590d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
10600d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10610d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, Hash) {
10620d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  std::hash<optional<int>> hash;
10630d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  std::set<size_t> hashcodes;
10640d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  hashcodes.insert(hash(nullopt));
10650d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  for (int i = 0; i < 100; ++i) {
10660d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    hashcodes.insert(hash(i));
10670d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
10680d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  EXPECT_GT(hashcodes.size(), 90);
10690d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
10700d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10710d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct MoveMeNoThrow {
10720d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveMeNoThrow() : x(0) {}
10730d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
10740d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar    LOG(FATAL) << "Should not be called.";
10750d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  }
10760d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
10770d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int x;
10780d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
10790d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10800d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebarstruct MoveMeThrow {
10810d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveMeThrow() : x(0) {}
10820d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}
10830d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  MoveMeThrow(MoveMeThrow&& other) : x(other.x) {}
10840d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  int x;
10850d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar};
10860d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10870d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin LebarTEST(optionalTest, NoExcept) {
10880d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(
10890d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      std::is_nothrow_move_constructible<optional<MoveMeNoThrow>>::value, "");
10900d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  static_assert(
10910d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar      !std::is_nothrow_move_constructible<optional<MoveMeThrow>>::value, "");
10920d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  std::vector<optional<MoveMeNoThrow>> v;
1093eb10a4c494d95e7c17ddc44ef35197d08f2f6b33A. Unique TensorFlower  v.reserve(10);
10940d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar  for (int i = 0; i < 10; ++i) v.emplace_back();
10950d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}
10960d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar
10970d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}  // namespace
10980d2a543850e4a78a1b232e6eb473d30b7ad2854fJustin Lebar}  // namespace tensorflow
1099