Remove the implementation of `absl::optional`, which was only needed
prior to C++17. `absl::optional` is now an alias for `std::optional`.
It is recommended that clients simply use `std::optional`.

PiperOrigin-RevId: 729860560
Change-Id: I8f3a23ed46c451cb441771cc544df79e6c326b67
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index de8bc27..789acf0 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -430,14 +430,11 @@
   "time/internal/cctz/src/tzfile.h"
   "time/internal/cctz/src/zone_info_source.cc"
   "types/any.h"
-  "types/bad_optional_access.cc"
-  "types/bad_optional_access.h"
   "types/bad_variant_access.cc"
   "types/bad_variant_access.h"
   "types/compare.h"
   "types/internal/variant.h"
   "types/optional.h"
-  "types/internal/optional.h"
   "types/span.h"
   "types/internal/span.h"
   "types/variant.h"
@@ -491,7 +488,6 @@
   "any"
   "any_invocable"
   "atomic_hook"
-  "bad_optional_access"
   "bad_variant_access"
   "base"
   "base_internal"
diff --git a/absl/base/config.h b/absl/base/config.h
index f5cd03a..510c485 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -519,22 +519,11 @@
 #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0
 #endif
 
-// ABSL_HAVE_STD_ANY/ABSL_USES_STD_ANY
+// Deprecated macros for polyfill detection.
 #define ABSL_HAVE_STD_ANY 1
 #define ABSL_USES_STD_ANY 1
-
-// ABSL_HAVE_STD_OPTIONAL
-//
-// Checks whether C++17 std::optional is available.
-#ifdef ABSL_HAVE_STD_OPTIONAL
-#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set."
-#elif defined(__cpp_lib_optional) && __cpp_lib_optional >= 201606L
 #define ABSL_HAVE_STD_OPTIONAL 1
-#elif defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
-    ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
-    !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE
-#define ABSL_HAVE_STD_OPTIONAL 1
-#endif
+#define ABSL_USES_STD_OPTIONAL 1
 
 // ABSL_HAVE_STD_VARIANT
 //
@@ -577,21 +566,6 @@
 #define ABSL_HAVE_STD_ORDERING 1
 #endif
 
-// ABSL_USES_STD_OPTIONAL
-//
-// Indicates whether absl::optional is an alias for std::optional.
-#if !defined(ABSL_OPTION_USE_STD_OPTIONAL)
-#error options.h is misconfigured.
-#elif ABSL_OPTION_USE_STD_OPTIONAL == 0 || \
-    (ABSL_OPTION_USE_STD_OPTIONAL == 2 && !defined(ABSL_HAVE_STD_OPTIONAL))
-#undef ABSL_USES_STD_OPTIONAL
-#elif ABSL_OPTION_USE_STD_OPTIONAL == 1 || \
-    (ABSL_OPTION_USE_STD_OPTIONAL == 2 && defined(ABSL_HAVE_STD_OPTIONAL))
-#define ABSL_USES_STD_OPTIONAL 1
-#else
-#error options.h is misconfigured.
-#endif
-
 // ABSL_USES_STD_VARIANT
 //
 // Indicates whether absl::variant is an alias for std::variant.
diff --git a/absl/base/options.h b/absl/base/options.h
index 582c4fd..593b952 100644
--- a/absl/base/options.h
+++ b/absl/base/options.h
@@ -73,33 +73,6 @@
 // Type Compatibility Options
 // -----------------------------------------------------------------------------
 
-// ABSL_OPTION_USE_STD_OPTIONAL
-//
-// This option controls whether absl::optional is implemented as an alias to
-// std::optional, or as an independent implementation.
-//
-// A value of 0 means to use Abseil's implementation.  This requires only C++11
-// support, and is expected to work on every toolchain we support.
-//
-// A value of 1 means to use an alias to std::optional.  This requires that all
-// code using Abseil is built in C++17 mode or later.
-//
-// A value of 2 means to detect the C++ version being used to compile Abseil,
-// and use an alias only if a working std::optional is available.  This option
-// is useful when you are building your program from source.  It should not be
-// used otherwise -- for example, if you are distributing Abseil in a binary
-// package manager -- since in mode 2, absl::optional will name a different
-// type, with a different mangled name and binary layout, depending on the
-// compiler flags passed by the end user.  For more info, see
-// https://abseil.io/about/design/dropin-types.
-
-// User code should not inspect this macro.  To check in the preprocessor if
-// absl::optional is a typedef of std::optional, use the feature macro
-// ABSL_USES_STD_OPTIONAL.
-
-#define ABSL_OPTION_USE_STD_OPTIONAL 2
-
-
 // ABSL_OPTION_USE_STD_STRING_VIEW
 //
 // This option controls whether absl::string_view is implemented as an alias to
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index 564d69a..6160daa 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -91,32 +91,18 @@
 
 cc_library(
     name = "optional",
-    srcs = ["internal/optional.h"],
     hdrs = ["optional.h"],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
-        ":bad_optional_access",
-        "//absl/base:base_internal",
         "//absl/base:config",
-        "//absl/base:core_headers",
-        "//absl/base:nullability",
-        "//absl/memory",
-        "//absl/meta:type_traits",
         "//absl/utility",
     ],
 )
 
 cc_library(
     name = "bad_optional_access",
-    srcs = ["bad_optional_access.cc"],
-    hdrs = ["bad_optional_access.h"],
-    copts = ABSL_DEFAULT_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    deps = [
-        "//absl/base:config",
-        "//absl/base:raw_logging_internal",
-    ],
+    deprecation = "bad_optional_access dependency is empty can be removed",
 )
 
 cc_library(
@@ -131,41 +117,6 @@
     ],
 )
 
-cc_test(
-    name = "optional_test",
-    size = "small",
-    srcs = [
-        "optional_test.cc",
-    ],
-    copts = ABSL_TEST_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    deps = [
-        ":optional",
-        "//absl/base:config",
-        "//absl/log",
-        "//absl/meta:type_traits",
-        "//absl/strings",
-        "@googletest//:gtest",
-        "@googletest//:gtest_main",
-    ],
-)
-
-cc_test(
-    name = "optional_exception_safety_test",
-    srcs = [
-        "optional_exception_safety_test.cc",
-    ],
-    copts = ABSL_TEST_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    deps = [
-        ":optional",
-        "//absl/base:config",
-        "//absl/base:exception_safety_testing",
-        "@googletest//:gtest",
-        "@googletest//:gtest_main",
-    ],
-)
-
 cc_library(
     name = "variant",
     srcs = ["internal/variant.h"],
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt
index 3c1f19e..a18bf3d 100644
--- a/absl/types/CMakeLists.txt
+++ b/absl/types/CMakeLists.txt
@@ -92,39 +92,16 @@
     optional
   HDRS
     "optional.h"
-  SRCS
-    "internal/optional.h"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
-    absl::bad_optional_access
-    absl::base_internal
     absl::config
-    absl::core_headers
-    absl::memory
-    absl::nullability
-    absl::type_traits
     absl::utility
   PUBLIC
 )
 
 absl_cc_library(
   NAME
-    bad_optional_access
-  HDRS
-    "bad_optional_access.h"
-  SRCS
-    "bad_optional_access.cc"
-  COPTS
-    ${ABSL_DEFAULT_COPTS}
-  DEPS
-    absl::config
-    absl::raw_logging_internal
-  PUBLIC
-)
-
-absl_cc_library(
-  NAME
     bad_variant_access
   HDRS
     "bad_variant_access.h"
@@ -138,36 +115,6 @@
   PUBLIC
 )
 
-absl_cc_test(
-  NAME
-    optional_test
-  SRCS
-    "optional_test.cc"
-  COPTS
-    ${ABSL_TEST_COPTS}
-  DEPS
-    absl::optional
-    absl::config
-    absl::log
-    absl::strings
-    absl::type_traits
-    GTest::gmock_main
-)
-
-absl_cc_test(
-  NAME
-    optional_exception_safety_test
-  SRCS
-    "optional_exception_safety_test.cc"
-  COPTS
-    ${ABSL_TEST_COPTS}
-  DEPS
-    absl::optional
-    absl::config
-    absl::exception_safety_testing
-    GTest::gmock_main
-)
-
 absl_cc_library(
   NAME
     variant
diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc
deleted file mode 100644
index 2552cc8..0000000
--- a/absl/types/bad_optional_access.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/types/bad_optional_access.h"
-
-#ifndef ABSL_USES_STD_OPTIONAL
-
-#include <cstdlib>
-
-#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-bad_optional_access::~bad_optional_access() = default;
-
-const char* bad_optional_access::what() const noexcept {
-  return "optional has no value";
-}
-
-namespace optional_internal {
-
-void throw_bad_optional_access() {
-#ifdef ABSL_HAVE_EXCEPTIONS
-  throw bad_optional_access();
-#else
-  ABSL_RAW_LOG(FATAL, "Bad optional access");
-  abort();
-#endif
-}
-
-}  // namespace optional_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#else
-
-// https://github.com/abseil/abseil-cpp/issues/1465
-// CMake builds on Apple platforms error when libraries are empty.
-// Our CMake configuration can avoid this error on header-only libraries,
-// but since this library is conditionally empty, including a single
-// variable is an easy workaround.
-#ifdef __APPLE__
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace types_internal {
-extern const char kAvoidEmptyBadOptionalAccessLibraryWarning;
-const char kAvoidEmptyBadOptionalAccessLibraryWarning = 0;
-}  // namespace types_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-#endif  // __APPLE__
-
-#endif  // ABSL_USES_STD_OPTIONAL
diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h
deleted file mode 100644
index 049e72a..0000000
--- a/absl/types/bad_optional_access.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// bad_optional_access.h
-// -----------------------------------------------------------------------------
-//
-// This header file defines the `absl::bad_optional_access` type.
-
-#ifndef ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_
-#define ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_
-
-#include <stdexcept>
-
-#include "absl/base/config.h"
-
-#ifdef ABSL_USES_STD_OPTIONAL
-
-#include <optional>
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-using std::bad_optional_access;
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#else  // ABSL_USES_STD_OPTIONAL
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-// -----------------------------------------------------------------------------
-// bad_optional_access
-// -----------------------------------------------------------------------------
-//
-// An `absl::bad_optional_access` type is an exception type that is thrown when
-// attempting to access an `absl::optional` object that does not contain a
-// value.
-//
-// Example:
-//
-//   absl::optional<int> o;
-//
-//   try {
-//     int n = o.value();
-//   } catch(const absl::bad_optional_access& e) {
-//     std::cout << "Bad optional access: " << e.what() << '\n';
-//   }
-class bad_optional_access : public std::exception {
- public:
-  bad_optional_access() = default;
-  ~bad_optional_access() override;
-  const char* what() const noexcept override;
-};
-
-namespace optional_internal {
-
-// throw delegator
-[[noreturn]] ABSL_DLL void throw_bad_optional_access();
-
-}  // namespace optional_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#endif  // ABSL_USES_STD_OPTIONAL
-
-#endif  // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_
diff --git a/absl/types/internal/optional.h b/absl/types/internal/optional.h
deleted file mode 100644
index 660bdfc..0000000
--- a/absl/types/internal/optional.h
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef ABSL_TYPES_INTERNAL_OPTIONAL_H_
-#define ABSL_TYPES_INTERNAL_OPTIONAL_H_
-
-#include <functional>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/meta/type_traits.h"
-#include "absl/utility/utility.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-// Forward declaration
-template <typename T>
-class optional;
-
-namespace optional_internal {
-
-// This tag type is used as a constructor parameter type for `nullopt_t`.
-struct init_t {
-  explicit init_t() = default;
-};
-
-struct empty_struct {};
-
-// This class stores the data in optional<T>.
-// It is specialized based on whether T is trivially destructible.
-// This is the specialization for non trivially destructible type.
-template <typename T, bool unused = std::is_trivially_destructible<T>::value>
-class optional_data_dtor_base {
-  struct dummy_type {
-    static_assert(sizeof(T) % sizeof(empty_struct) == 0, "");
-    // Use an array to avoid GCC 6 placement-new warning.
-    empty_struct data[sizeof(T) / sizeof(empty_struct)];
-  };
-
- protected:
-  // Whether there is data or not.
-  bool engaged_;
-  // Data storage
-  union {
-    T data_;
-    dummy_type dummy_;
-  };
-
-  void destruct() noexcept {
-    if (engaged_) {
-      // `data_` must be initialized if `engaged_` is true.
-#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif
-      data_.~T();
-#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
-#pragma GCC diagnostic pop
-#endif
-      engaged_ = false;
-    }
-  }
-
-  // dummy_ must be initialized for constexpr constructor.
-  constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{{}} {}
-
-  template <typename... Args>
-  constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args)
-      : engaged_(true), data_(std::forward<Args>(args)...) {}
-
-  ~optional_data_dtor_base() { destruct(); }
-};
-
-// Specialization for trivially destructible type.
-template <typename T>
-class optional_data_dtor_base<T, true> {
-  struct dummy_type {
-    static_assert(sizeof(T) % sizeof(empty_struct) == 0, "");
-    // Use array to avoid GCC 6 placement-new warning.
-    empty_struct data[sizeof(T) / sizeof(empty_struct)];
-  };
-
- protected:
-  // Whether there is data or not.
-  bool engaged_;
-  // Data storage
-  union {
-    T data_;
-    dummy_type dummy_;
-  };
-  void destruct() noexcept { engaged_ = false; }
-
-  // dummy_ must be initialized for constexpr constructor.
-  constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{{}} {}
-
-  template <typename... Args>
-  constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args)
-      : engaged_(true), data_(std::forward<Args>(args)...) {}
-};
-
-template <typename T>
-class optional_data_base : public optional_data_dtor_base<T> {
- protected:
-  using base = optional_data_dtor_base<T>;
-  using base::base;
-
-  template <typename... Args>
-  void construct(Args&&... args) {
-    // Use dummy_'s address to work around casting cv-qualified T* to void*.
-    ::new (static_cast<void*>(&this->dummy_)) T(std::forward<Args>(args)...);
-    this->engaged_ = true;
-  }
-
-  template <typename U>
-  void assign(U&& u) {
-    if (this->engaged_) {
-      this->data_ = std::forward<U>(u);
-    } else {
-      construct(std::forward<U>(u));
-    }
-  }
-};
-
-// TODO(absl-team): Add another class using
-// std::is_trivially_move_constructible trait when available to match
-// http://cplusplus.github.io/LWG/lwg-defects.html#2900, for types that
-// have trivial move but nontrivial copy.
-// Also, we should be checking is_trivially_copyable here, which is not
-// supported now, so we use is_trivially_* traits instead.
-template <typename T,
-          bool unused = absl::is_trivially_copy_constructible<T>::value&&
-              absl::is_trivially_copy_assignable<typename std::remove_cv<
-                  T>::type>::value&& std::is_trivially_destructible<T>::value>
-class optional_data;
-
-// Trivially copyable types
-template <typename T>
-class optional_data<T, true> : public optional_data_base<T> {
- protected:
-  using optional_data_base<T>::optional_data_base;
-};
-
-template <typename T>
-class optional_data<T, false> : public optional_data_base<T> {
- protected:
-  using optional_data_base<T>::optional_data_base;
-
-  optional_data() = default;
-
-  optional_data(const optional_data& rhs) : optional_data_base<T>() {
-    if (rhs.engaged_) {
-      this->construct(rhs.data_);
-    }
-  }
-
-  optional_data(optional_data&& rhs) noexcept(
-      absl::default_allocator_is_nothrow::value ||
-      std::is_nothrow_move_constructible<T>::value)
-      : optional_data_base<T>() {
-    if (rhs.engaged_) {
-      this->construct(std::move(rhs.data_));
-    }
-  }
-
-  optional_data& operator=(const optional_data& rhs) {
-    if (rhs.engaged_) {
-      this->assign(rhs.data_);
-    } else {
-      this->destruct();
-    }
-    return *this;
-  }
-
-  optional_data& operator=(optional_data&& rhs) noexcept(
-      std::is_nothrow_move_assignable<T>::value&&
-          std::is_nothrow_move_constructible<T>::value) {
-    if (rhs.engaged_) {
-      this->assign(std::move(rhs.data_));
-    } else {
-      this->destruct();
-    }
-    return *this;
-  }
-};
-
-// Ordered by level of restriction, from low to high.
-// Copyable implies movable.
-enum class copy_traits { copyable = 0, movable = 1, non_movable = 2 };
-
-// Base class for enabling/disabling copy/move constructor.
-template <copy_traits>
-class optional_ctor_base;
-
-template <>
-class optional_ctor_base<copy_traits::copyable> {
- public:
-  constexpr optional_ctor_base() = default;
-  optional_ctor_base(const optional_ctor_base&) = default;
-  optional_ctor_base(optional_ctor_base&&) = default;
-  optional_ctor_base& operator=(const optional_ctor_base&) = default;
-  optional_ctor_base& operator=(optional_ctor_base&&) = default;
-};
-
-template <>
-class optional_ctor_base<copy_traits::movable> {
- public:
-  constexpr optional_ctor_base() = default;
-  optional_ctor_base(const optional_ctor_base&) = delete;
-  optional_ctor_base(optional_ctor_base&&) = default;
-  optional_ctor_base& operator=(const optional_ctor_base&) = default;
-  optional_ctor_base& operator=(optional_ctor_base&&) = default;
-};
-
-template <>
-class optional_ctor_base<copy_traits::non_movable> {
- public:
-  constexpr optional_ctor_base() = default;
-  optional_ctor_base(const optional_ctor_base&) = delete;
-  optional_ctor_base(optional_ctor_base&&) = delete;
-  optional_ctor_base& operator=(const optional_ctor_base&) = default;
-  optional_ctor_base& operator=(optional_ctor_base&&) = default;
-};
-
-// Base class for enabling/disabling copy/move assignment.
-template <copy_traits>
-class optional_assign_base;
-
-template <>
-class optional_assign_base<copy_traits::copyable> {
- public:
-  constexpr optional_assign_base() = default;
-  optional_assign_base(const optional_assign_base&) = default;
-  optional_assign_base(optional_assign_base&&) = default;
-  optional_assign_base& operator=(const optional_assign_base&) = default;
-  optional_assign_base& operator=(optional_assign_base&&) = default;
-};
-
-template <>
-class optional_assign_base<copy_traits::movable> {
- public:
-  constexpr optional_assign_base() = default;
-  optional_assign_base(const optional_assign_base&) = default;
-  optional_assign_base(optional_assign_base&&) = default;
-  optional_assign_base& operator=(const optional_assign_base&) = delete;
-  optional_assign_base& operator=(optional_assign_base&&) = default;
-};
-
-template <>
-class optional_assign_base<copy_traits::non_movable> {
- public:
-  constexpr optional_assign_base() = default;
-  optional_assign_base(const optional_assign_base&) = default;
-  optional_assign_base(optional_assign_base&&) = default;
-  optional_assign_base& operator=(const optional_assign_base&) = delete;
-  optional_assign_base& operator=(optional_assign_base&&) = delete;
-};
-
-template <typename T>
-struct ctor_copy_traits {
-  static constexpr copy_traits traits =
-      std::is_copy_constructible<T>::value
-          ? copy_traits::copyable
-          : std::is_move_constructible<T>::value ? copy_traits::movable
-                                                 : copy_traits::non_movable;
-};
-
-template <typename T>
-struct assign_copy_traits {
-  static constexpr copy_traits traits =
-      absl::is_copy_assignable<T>::value && std::is_copy_constructible<T>::value
-          ? copy_traits::copyable
-          : absl::is_move_assignable<T>::value &&
-                    std::is_move_constructible<T>::value
-                ? copy_traits::movable
-                : copy_traits::non_movable;
-};
-
-// Whether T is constructible or convertible from optional<U>.
-template <typename T, typename U>
-struct is_constructible_convertible_from_optional
-    : std::integral_constant<
-          bool, std::is_constructible<T, optional<U>&>::value ||
-                    std::is_constructible<T, optional<U>&&>::value ||
-                    std::is_constructible<T, const optional<U>&>::value ||
-                    std::is_constructible<T, const optional<U>&&>::value ||
-                    std::is_convertible<optional<U>&, T>::value ||
-                    std::is_convertible<optional<U>&&, T>::value ||
-                    std::is_convertible<const optional<U>&, T>::value ||
-                    std::is_convertible<const optional<U>&&, T>::value> {};
-
-// Whether T is constructible or convertible or assignable from optional<U>.
-template <typename T, typename U>
-struct is_constructible_convertible_assignable_from_optional
-    : std::integral_constant<
-          bool, is_constructible_convertible_from_optional<T, U>::value ||
-                    std::is_assignable<T&, optional<U>&>::value ||
-                    std::is_assignable<T&, optional<U>&&>::value ||
-                    std::is_assignable<T&, const optional<U>&>::value ||
-                    std::is_assignable<T&, const optional<U>&&>::value> {};
-
-// Helper function used by [optional.relops], [optional.comp_with_t],
-// for checking whether an expression is convertible to bool.
-bool convertible_to_bool(bool);
-
-// Base class for std::hash<absl::optional<T>>:
-// If std::hash<std::remove_const_t<T>> is enabled, it provides operator() to
-// compute the hash; Otherwise, it is disabled.
-// Reference N4659 23.14.15 [unord.hash].
-template <typename T, typename = size_t>
-struct optional_hash_base {
-  optional_hash_base() = delete;
-  optional_hash_base(const optional_hash_base&) = delete;
-  optional_hash_base(optional_hash_base&&) = delete;
-  optional_hash_base& operator=(const optional_hash_base&) = delete;
-  optional_hash_base& operator=(optional_hash_base&&) = delete;
-};
-
-template <typename T>
-struct optional_hash_base<T, decltype(std::hash<absl::remove_const_t<T> >()(
-                                 std::declval<absl::remove_const_t<T> >()))> {
-  using argument_type = absl::optional<T>;
-  using result_type = size_t;
-  size_t operator()(const absl::optional<T>& opt) const {
-    absl::type_traits_internal::AssertHashEnabled<absl::remove_const_t<T>>();
-    if (opt) {
-      return std::hash<absl::remove_const_t<T> >()(*opt);
-    } else {
-      return static_cast<size_t>(0x297814aaad196e6dULL);
-    }
-  }
-};
-
-}  // namespace optional_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#endif  // ABSL_TYPES_INTERNAL_OPTIONAL_H_
diff --git a/absl/types/optional.h b/absl/types/optional.h
index 97ac02e..65bba64 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -16,32 +16,18 @@
 // optional.h
 // -----------------------------------------------------------------------------
 //
-// This header file defines the `absl::optional` type for holding a value which
-// may or may not be present. This type is useful for providing value semantics
-// for operations that may either wish to return or hold "something-or-nothing".
-//
-// Example:
-//
-//   // A common way to signal operation failure is to provide an output
-//   // parameter and a bool return type:
-//   bool AcquireResource(const Input&, Resource * out);
-//
-//   // Providing an absl::optional return type provides a cleaner API:
-//   absl::optional<Resource> AcquireResource(const Input&);
-//
-// `absl::optional` is a C++11 compatible version of the C++17 `std::optional`
-// abstraction and is designed to be a drop-in replacement for code compliant
-// with C++17.
+// Historical note: Abseil once provided an implementation of `absl::optional`
+// as a polyfill for `std::optional` prior to C++17. Now that C++17 is required,
+// `absl::optional` is an alias for `std::optional`.
+
 #ifndef ABSL_TYPES_OPTIONAL_H_
 #define ABSL_TYPES_OPTIONAL_H_
 
-#include "absl/base/config.h"   // TODO(calabrese) IWYU removal?
+#include <optional>
+
+#include "absl/base/config.h"
 #include "absl/utility/utility.h"
 
-#ifdef ABSL_USES_STD_OPTIONAL
-
-#include <optional>  // IWYU pragma: export
-
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 using std::bad_optional_access;
@@ -52,728 +38,4 @@
 ABSL_NAMESPACE_END
 }  // namespace absl
 
-#else  // ABSL_USES_STD_OPTIONAL
-
-#include <cassert>
-#include <functional>
-#include <initializer_list>
-#include <type_traits>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/base/nullability.h"
-#include "absl/meta/type_traits.h"
-#include "absl/types/bad_optional_access.h"
-#include "absl/types/internal/optional.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-// nullopt_t
-//
-// Class type for `absl::nullopt` used to indicate an `absl::optional<T>` type
-// that does not contain a value.
-struct nullopt_t {
-  // It must not be default-constructible to avoid ambiguity for opt = {}.
-  explicit constexpr nullopt_t(optional_internal::init_t) noexcept {}
-};
-
-// nullopt
-//
-// A tag constant of type `absl::nullopt_t` used to indicate an empty
-// `absl::optional` in certain functions, such as construction or assignment.
-inline constexpr nullopt_t nullopt = nullopt_t(optional_internal::init_t());
-
-// -----------------------------------------------------------------------------
-// absl::optional
-// -----------------------------------------------------------------------------
-//
-// A value of type `absl::optional<T>` holds either a value of `T` or an
-// "empty" value.  When it holds a value of `T`, it stores it as a direct
-// sub-object, so `sizeof(optional<T>)` is approximately
-// `sizeof(T) + sizeof(bool)`.
-//
-// This implementation is based on the specification in the latest draft of the
-// C++17 `std::optional` specification as of May 2017, section 20.6.
-//
-// Differences between `absl::optional<T>` and `std::optional<T>` include:
-//
-//    * `constexpr` is not used for non-const member functions.
-//      (dependency on some differences between C++11 and C++14.)
-//    * `absl::nullopt` and `absl::in_place` are not declared `constexpr`. We
-//      need the inline variable support in C++17 for external linkage.
-//    * Throws `absl::bad_optional_access` instead of
-//      `std::bad_optional_access`.
-//    * `make_optional()` cannot be declared `constexpr` due to the absence of
-//      guaranteed copy elision.
-//    * The move constructor's `noexcept` specification is stronger, i.e. if the
-//      default allocator is non-throwing (via setting
-//      `ABSL_ALLOCATOR_NOTHROW`), it evaluates to `noexcept(true)`, because
-//      we assume
-//       a) move constructors should only throw due to allocation failure and
-//       b) if T's move constructor allocates, it uses the same allocation
-//          function as the default allocator.
-//
-template <typename T>
-class optional : private optional_internal::optional_data<T>,
-                 private optional_internal::optional_ctor_base<
-                     optional_internal::ctor_copy_traits<T>::traits>,
-                 private optional_internal::optional_assign_base<
-                     optional_internal::assign_copy_traits<T>::traits> {
-  using data_base = optional_internal::optional_data<T>;
-
- public:
-  typedef T value_type;
-
-  // Constructors
-
-  // Constructs an `optional` holding an empty value, NOT a default constructed
-  // `T`.
-  constexpr optional() noexcept = default;
-
-  // Constructs an `optional` initialized with `nullopt` to hold an empty value.
-  constexpr optional(nullopt_t) noexcept {}  // NOLINT(runtime/explicit)
-
-  // Copy constructor, standard semantics
-  optional(const optional&) = default;
-
-  // Move constructor, standard semantics
-  optional(optional&&) = default;
-
-  // Constructs a non-empty `optional` direct-initialized value of type `T` from
-  // the arguments `std::forward<Args>(args)...`  within the `optional`.
-  // (The `in_place_t` is a tag used to indicate that the contained object
-  // should be constructed in-place.)
-  template <typename InPlaceT, typename... Args,
-            absl::enable_if_t<absl::conjunction<
-                std::is_same<InPlaceT, in_place_t>,
-                std::is_constructible<T, Args&&...> >::value>* = nullptr>
-  constexpr explicit optional(InPlaceT, Args&&... args)
-      : data_base(in_place_t(), std::forward<Args>(args)...) {}
-
-  // Constructs a non-empty `optional` direct-initialized value of type `T` from
-  // the arguments of an initializer_list and `std::forward<Args>(args)...`.
-  // (The `in_place_t` is a tag used to indicate that the contained object
-  // should be constructed in-place.)
-  template <typename U, typename... Args,
-            typename = typename std::enable_if<std::is_constructible<
-                T, std::initializer_list<U>&, Args&&...>::value>::type>
-  constexpr explicit optional(in_place_t, std::initializer_list<U> il,
-                              Args&&... args)
-      : data_base(in_place_t(), il, std::forward<Args>(args)...) {}
-
-  // Value constructor (implicit)
-  template <
-      typename U = T,
-      typename std::enable_if<
-          absl::conjunction<absl::negation<std::is_same<
-                                in_place_t, typename std::decay<U>::type> >,
-                            absl::negation<std::is_same<
-                                optional<T>, typename std::decay<U>::type> >,
-                            std::is_convertible<U&&, T>,
-                            std::is_constructible<T, U&&> >::value,
-          bool>::type = false>
-  constexpr optional(U&& v) : data_base(in_place_t(), std::forward<U>(v)) {}
-
-  // Value constructor (explicit)
-  template <
-      typename U = T,
-      typename std::enable_if<
-          absl::conjunction<absl::negation<std::is_same<
-                                in_place_t, typename std::decay<U>::type> >,
-                            absl::negation<std::is_same<
-                                optional<T>, typename std::decay<U>::type> >,
-                            absl::negation<std::is_convertible<U&&, T> >,
-                            std::is_constructible<T, U&&> >::value,
-          bool>::type = false>
-  explicit constexpr optional(U&& v)
-      : data_base(in_place_t(), std::forward<U>(v)) {}
-
-  // Converting copy constructor (implicit)
-  template <typename U,
-            typename std::enable_if<
-                absl::conjunction<
-                    absl::negation<std::is_same<T, U> >,
-                    std::is_constructible<T, const U&>,
-                    absl::negation<
-                        optional_internal::
-                            is_constructible_convertible_from_optional<T, U> >,
-                    std::is_convertible<const U&, T> >::value,
-                bool>::type = false>
-  optional(const optional<U>& rhs) {
-    if (rhs) {
-      this->construct(*rhs);
-    }
-  }
-
-  // Converting copy constructor (explicit)
-  template <typename U,
-            typename std::enable_if<
-                absl::conjunction<
-                    absl::negation<std::is_same<T, U>>,
-                    std::is_constructible<T, const U&>,
-                    absl::negation<
-                        optional_internal::
-                            is_constructible_convertible_from_optional<T, U>>,
-                    absl::negation<std::is_convertible<const U&, T>>>::value,
-                bool>::type = false>
-  explicit optional(const optional<U>& rhs) {
-    if (rhs) {
-      this->construct(*rhs);
-    }
-  }
-
-  // Converting move constructor (implicit)
-  template <typename U,
-            typename std::enable_if<
-                absl::conjunction<
-                    absl::negation<std::is_same<T, U> >,
-                    std::is_constructible<T, U&&>,
-                    absl::negation<
-                        optional_internal::
-                            is_constructible_convertible_from_optional<T, U> >,
-                    std::is_convertible<U&&, T> >::value,
-                bool>::type = false>
-  optional(optional<U>&& rhs) {
-    if (rhs) {
-      this->construct(std::move(*rhs));
-    }
-  }
-
-  // Converting move constructor (explicit)
-  template <
-      typename U,
-      typename std::enable_if<
-          absl::conjunction<
-              absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
-              absl::negation<
-                  optional_internal::is_constructible_convertible_from_optional<
-                      T, U>>,
-              absl::negation<std::is_convertible<U&&, T>>>::value,
-          bool>::type = false>
-  explicit optional(optional<U>&& rhs) {
-    if (rhs) {
-      this->construct(std::move(*rhs));
-    }
-  }
-
-  // Destructor. Trivial if `T` is trivially destructible.
-  ~optional() = default;
-
-  // Assignment Operators
-
-  // Assignment from `nullopt`
-  //
-  // Example:
-  //
-  //   struct S { int value; };
-  //   optional<S> opt = absl::nullopt;  // Could also use opt = { };
-  optional& operator=(nullopt_t) noexcept {
-    this->destruct();
-    return *this;
-  }
-
-  // Copy assignment operator, standard semantics
-  optional& operator=(const optional& src) = default;
-
-  // Move assignment operator, standard semantics
-  optional& operator=(optional&& src) = default;
-
-  // Value assignment operators
-  template <typename U = T,
-            int&...,  // Workaround an internal compiler error in GCC 5 to 10.
-            typename = typename std::enable_if<absl::conjunction<
-                absl::negation<
-                    std::is_same<optional<T>, typename std::decay<U>::type> >,
-                absl::negation<absl::conjunction<
-                    std::is_scalar<T>,
-                    std::is_same<T, typename std::decay<U>::type> > >,
-                std::is_constructible<T, U>,
-                std::is_assignable<T&, U> >::value>::type>
-  optional& operator=(U&& v) {
-    this->assign(std::forward<U>(v));
-    return *this;
-  }
-
-  template <
-      typename U,
-      int&...,  // Workaround an internal compiler error in GCC 5 to 10.
-      typename = typename std::enable_if<absl::conjunction<
-          absl::negation<std::is_same<T, U> >,
-          std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>,
-          absl::negation<
-              optional_internal::
-                  is_constructible_convertible_assignable_from_optional<
-                      T, U> > >::value>::type>
-  optional& operator=(const optional<U>& rhs) {
-    if (rhs) {
-      this->assign(*rhs);
-    } else {
-      this->destruct();
-    }
-    return *this;
-  }
-
-  template <typename U,
-            int&...,  // Workaround an internal compiler error in GCC 5 to 10.
-            typename = typename std::enable_if<absl::conjunction<
-                absl::negation<std::is_same<T, U> >,
-                std::is_constructible<T, U>, std::is_assignable<T&, U>,
-                absl::negation<
-                    optional_internal::
-                        is_constructible_convertible_assignable_from_optional<
-                            T, U> > >::value>::type>
-  optional& operator=(optional<U>&& rhs) {
-    if (rhs) {
-      this->assign(std::move(*rhs));
-    } else {
-      this->destruct();
-    }
-    return *this;
-  }
-
-  // Modifiers
-
-  // optional::reset()
-  //
-  // Destroys the inner `T` value of an `absl::optional` if one is present.
-  ABSL_ATTRIBUTE_REINITIALIZES void reset() noexcept { this->destruct(); }
-
-  // optional::emplace()
-  //
-  // (Re)constructs the underlying `T` in-place with the given forwarded
-  // arguments.
-  //
-  // Example:
-  //
-  //   optional<Foo> opt;
-  //   opt.emplace(arg1,arg2,arg3);  // Constructs Foo(arg1,arg2,arg3)
-  //
-  // If the optional is non-empty, and the `args` refer to subobjects of the
-  // current object, then behaviour is undefined, because the current object
-  // will be destructed before the new object is constructed with `args`.
-  template <typename... Args,
-            typename = typename std::enable_if<
-                std::is_constructible<T, Args&&...>::value>::type>
-  T& emplace(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    this->destruct();
-    this->construct(std::forward<Args>(args)...);
-    return reference();
-  }
-
-  // Emplace reconstruction overload for an initializer list and the given
-  // forwarded arguments.
-  //
-  // Example:
-  //
-  //   struct Foo {
-  //     Foo(std::initializer_list<int>);
-  //   };
-  //
-  //   optional<Foo> opt;
-  //   opt.emplace({1,2,3});  // Constructs Foo({1,2,3})
-  template <typename U, typename... Args,
-            typename = typename std::enable_if<std::is_constructible<
-                T, std::initializer_list<U>&, Args&&...>::value>::type>
-  T& emplace(std::initializer_list<U> il,
-             Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    this->destruct();
-    this->construct(il, std::forward<Args>(args)...);
-    return reference();
-  }
-
-  // Swaps
-
-  // Swap, standard semantics
-  void swap(optional& rhs) noexcept(
-      std::is_nothrow_move_constructible<T>::value&&
-          type_traits_internal::IsNothrowSwappable<T>::value) {
-    if (*this) {
-      if (rhs) {
-        type_traits_internal::Swap(**this, *rhs);
-      } else {
-        rhs.construct(std::move(**this));
-        this->destruct();
-      }
-    } else {
-      if (rhs) {
-        this->construct(std::move(*rhs));
-        rhs.destruct();
-      } else {
-        // No effect (swap(disengaged, disengaged)).
-      }
-    }
-  }
-
-  // Observers
-
-  // optional::operator->()
-  //
-  // Accesses the underlying `T` value's member `m` of an `optional`. If the
-  // `optional` is empty, behavior is undefined.
-  //
-  // If you need myOpt->foo in constexpr, use (*myOpt).foo instead.
-  absl::Nonnull<const T*> operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    ABSL_HARDENING_ASSERT(this->engaged_);
-    return std::addressof(this->data_);
-  }
-  absl::Nonnull<T*> operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    ABSL_HARDENING_ASSERT(this->engaged_);
-    return std::addressof(this->data_);
-  }
-
-  // optional::operator*()
-  //
-  // Accesses the underlying `T` value of an `optional`. If the `optional` is
-  // empty, behavior is undefined.
-  constexpr const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    ABSL_HARDENING_ASSERT(this->engaged_);
-    return reference();
-  }
-  T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    ABSL_HARDENING_ASSERT(this->engaged_);
-    return reference();
-  }
-  constexpr const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    ABSL_HARDENING_ASSERT(this->engaged_);
-    return std::move(reference());
-  }
-  T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    ABSL_HARDENING_ASSERT(this->engaged_);
-    return std::move(reference());
-  }
-
-  // optional::operator bool()
-  //
-  // Returns false if and only if the `optional` is empty.
-  //
-  //   if (opt) {
-  //     // do something with *opt or opt->;
-  //   } else {
-  //     // opt is empty.
-  //   }
-  //
-  constexpr explicit operator bool() const noexcept { return this->engaged_; }
-
-  // optional::has_value()
-  //
-  // Determines whether the `optional` contains a value. Returns `false` if and
-  // only if `*this` is empty.
-  constexpr bool has_value() const noexcept { return this->engaged_; }
-
-// Suppress bogus warning on MSVC: MSVC complains call to reference() after
-// throw_bad_optional_access() is unreachable.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4702)
-#endif  // _MSC_VER
-  // optional::value()
-  //
-  // Returns a reference to an `optional`s underlying value. The constness
-  // and lvalue/rvalue-ness of the `optional` is preserved to the view of
-  // the `T` sub-object. Throws `absl::bad_optional_access` when the `optional`
-  // is empty.
-  constexpr const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return static_cast<bool>(*this)
-               ? reference()
-               : (optional_internal::throw_bad_optional_access(), reference());
-  }
-  T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return static_cast<bool>(*this)
-               ? reference()
-               : (optional_internal::throw_bad_optional_access(), reference());
-  }
-  T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND {  // NOLINT(build/c++11)
-    return std::move(
-        static_cast<bool>(*this)
-            ? reference()
-            : (optional_internal::throw_bad_optional_access(), reference()));
-  }
-  constexpr const T&& value()
-      const&& ABSL_ATTRIBUTE_LIFETIME_BOUND {  // NOLINT(build/c++11)
-    return std::move(
-        static_cast<bool>(*this)
-            ? reference()
-            : (optional_internal::throw_bad_optional_access(), reference()));
-  }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif  // _MSC_VER
-
-  // optional::value_or()
-  //
-  // Returns either the value of `T` or a passed default `v` if the `optional`
-  // is empty.
-  template <typename U>
-  constexpr T value_or(U&& v) const& {
-    static_assert(std::is_copy_constructible<value_type>::value,
-                  "optional<T>::value_or: T must be copy constructible");
-    static_assert(std::is_convertible<U&&, value_type>::value,
-                  "optional<T>::value_or: U must be convertible to T");
-    return static_cast<bool>(*this) ? **this
-                                    : static_cast<T>(std::forward<U>(v));
-  }
-  template <typename U>
-  T value_or(U&& v) && {  // NOLINT(build/c++11)
-    static_assert(std::is_move_constructible<value_type>::value,
-                  "optional<T>::value_or: T must be move constructible");
-    static_assert(std::is_convertible<U&&, value_type>::value,
-                  "optional<T>::value_or: U must be convertible to T");
-    return static_cast<bool>(*this) ? std::move(**this)
-                                    : static_cast<T>(std::forward<U>(v));
-  }
-
- private:
-  // Private accessors for internal storage viewed as reference to T.
-  constexpr const T& reference() const { return this->data_; }
-  T& reference() { return this->data_; }
-
-  // T constraint checks.  You can't have an optional of nullopt_t, in_place_t
-  // or a reference.
-  static_assert(
-      !std::is_same<nullopt_t, typename std::remove_cv<T>::type>::value,
-      "optional<nullopt_t> is not allowed.");
-  static_assert(
-      !std::is_same<in_place_t, typename std::remove_cv<T>::type>::value,
-      "optional<in_place_t> is not allowed.");
-  static_assert(!std::is_reference<T>::value,
-                "optional<reference> is not allowed.");
-};
-
-// Non-member functions
-
-// swap()
-//
-// Performs a swap between two `absl::optional` objects, using standard
-// semantics.
-template <typename T, typename std::enable_if<
-                          std::is_move_constructible<T>::value &&
-                              type_traits_internal::IsSwappable<T>::value,
-                          bool>::type = false>
-void swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) {
-  a.swap(b);
-}
-
-// make_optional()
-//
-// Creates a non-empty `optional<T>` where the type of `T` is deduced. An
-// `absl::optional` can also be explicitly instantiated with
-// `make_optional<T>(v)`.
-//
-// Note: `make_optional()` constructions may be declared `constexpr` for
-// trivially copyable types `T`. Non-trivial types require copy elision
-// support in C++17 for `make_optional` to support `constexpr` on such
-// non-trivial types.
-//
-// Example:
-//
-//   constexpr absl::optional<int> opt = absl::make_optional(1);
-//   static_assert(opt.value() == 1, "");
-template <typename T>
-constexpr optional<typename std::decay<T>::type> make_optional(T&& v) {
-  return optional<typename std::decay<T>::type>(std::forward<T>(v));
-}
-
-template <typename T, typename... Args>
-constexpr optional<T> make_optional(Args&&... args) {
-  return optional<T>(in_place_t(), std::forward<Args>(args)...);
-}
-
-template <typename T, typename U, typename... Args>
-constexpr optional<T> make_optional(std::initializer_list<U> il,
-                                    Args&&... args) {
-  return optional<T>(in_place_t(), il, std::forward<Args>(args)...);
-}
-
-// Relational operators [optional.relops]
-
-// Empty optionals are considered equal to each other and less than non-empty
-// optionals. Supports relations between optional<T> and optional<U>, between
-// optional<T> and U, and between optional<T> and nullopt.
-//
-// Note: We're careful to support T having non-bool relationals.
-
-// Requires: The expression, e.g. "*x == *y" shall be well-formed and its result
-// shall be convertible to bool.
-// The C++17 (N4606) "Returns:" statements are translated into
-// code in an obvious way here, and the original text retained as function docs.
-// Returns: If bool(x) != bool(y), false; otherwise if bool(x) == false, true;
-// otherwise *x == *y.
-template <typename T, typename U>
-constexpr auto operator==(const optional<T>& x, const optional<U>& y)
-    -> decltype(optional_internal::convertible_to_bool(*x == *y)) {
-  return static_cast<bool>(x) != static_cast<bool>(y)
-             ? false
-             : static_cast<bool>(x) == false ? true
-                                             : static_cast<bool>(*x == *y);
-}
-
-// Returns: If bool(x) != bool(y), true; otherwise, if bool(x) == false, false;
-// otherwise *x != *y.
-template <typename T, typename U>
-constexpr auto operator!=(const optional<T>& x, const optional<U>& y)
-    -> decltype(optional_internal::convertible_to_bool(*x != *y)) {
-  return static_cast<bool>(x) != static_cast<bool>(y)
-             ? true
-             : static_cast<bool>(x) == false ? false
-                                             : static_cast<bool>(*x != *y);
-}
-// Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y.
-template <typename T, typename U>
-constexpr auto operator<(const optional<T>& x, const optional<U>& y)
-    -> decltype(optional_internal::convertible_to_bool(*x < *y)) {
-  return !y ? false : !x ? true : static_cast<bool>(*x < *y);
-}
-// Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y.
-template <typename T, typename U>
-constexpr auto operator>(const optional<T>& x, const optional<U>& y)
-    -> decltype(optional_internal::convertible_to_bool(*x > *y)) {
-  return !x ? false : !y ? true : static_cast<bool>(*x > *y);
-}
-// Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y.
-template <typename T, typename U>
-constexpr auto operator<=(const optional<T>& x, const optional<U>& y)
-    -> decltype(optional_internal::convertible_to_bool(*x <= *y)) {
-  return !x ? true : !y ? false : static_cast<bool>(*x <= *y);
-}
-// Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y.
-template <typename T, typename U>
-constexpr auto operator>=(const optional<T>& x, const optional<U>& y)
-    -> decltype(optional_internal::convertible_to_bool(*x >= *y)) {
-  return !y ? true : !x ? false : static_cast<bool>(*x >= *y);
-}
-
-// Comparison with nullopt [optional.nullops]
-// The C++17 (N4606) "Returns:" statements are used directly here.
-template <typename T>
-constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept {
-  return !x;
-}
-template <typename T>
-constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept {
-  return !x;
-}
-template <typename T>
-constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept {
-  return static_cast<bool>(x);
-}
-template <typename T>
-constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept {
-  return static_cast<bool>(x);
-}
-template <typename T>
-constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
-  return false;
-}
-template <typename T>
-constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept {
-  return static_cast<bool>(x);
-}
-template <typename T>
-constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept {
-  return !x;
-}
-template <typename T>
-constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
-  return true;
-}
-template <typename T>
-constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept {
-  return static_cast<bool>(x);
-}
-template <typename T>
-constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
-  return false;
-}
-template <typename T>
-constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
-  return true;
-}
-template <typename T>
-constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept {
-  return !x;
-}
-
-// Comparison with T [optional.comp_with_t]
-
-// Requires: The expression, e.g. "*x == v" shall be well-formed and its result
-// shall be convertible to bool.
-// The C++17 (N4606) "Equivalent to:" statements are used directly here.
-template <typename T, typename U>
-constexpr auto operator==(const optional<T>& x, const U& v)
-    -> decltype(optional_internal::convertible_to_bool(*x == v)) {
-  return static_cast<bool>(x) ? static_cast<bool>(*x == v) : false;
-}
-template <typename T, typename U>
-constexpr auto operator==(const U& v, const optional<T>& x)
-    -> decltype(optional_internal::convertible_to_bool(v == *x)) {
-  return static_cast<bool>(x) ? static_cast<bool>(v == *x) : false;
-}
-template <typename T, typename U>
-constexpr auto operator!=(const optional<T>& x, const U& v)
-    -> decltype(optional_internal::convertible_to_bool(*x != v)) {
-  return static_cast<bool>(x) ? static_cast<bool>(*x != v) : true;
-}
-template <typename T, typename U>
-constexpr auto operator!=(const U& v, const optional<T>& x)
-    -> decltype(optional_internal::convertible_to_bool(v != *x)) {
-  return static_cast<bool>(x) ? static_cast<bool>(v != *x) : true;
-}
-template <typename T, typename U>
-constexpr auto operator<(const optional<T>& x, const U& v)
-    -> decltype(optional_internal::convertible_to_bool(*x < v)) {
-  return static_cast<bool>(x) ? static_cast<bool>(*x < v) : true;
-}
-template <typename T, typename U>
-constexpr auto operator<(const U& v, const optional<T>& x)
-    -> decltype(optional_internal::convertible_to_bool(v < *x)) {
-  return static_cast<bool>(x) ? static_cast<bool>(v < *x) : false;
-}
-template <typename T, typename U>
-constexpr auto operator<=(const optional<T>& x, const U& v)
-    -> decltype(optional_internal::convertible_to_bool(*x <= v)) {
-  return static_cast<bool>(x) ? static_cast<bool>(*x <= v) : true;
-}
-template <typename T, typename U>
-constexpr auto operator<=(const U& v, const optional<T>& x)
-    -> decltype(optional_internal::convertible_to_bool(v <= *x)) {
-  return static_cast<bool>(x) ? static_cast<bool>(v <= *x) : false;
-}
-template <typename T, typename U>
-constexpr auto operator>(const optional<T>& x, const U& v)
-    -> decltype(optional_internal::convertible_to_bool(*x > v)) {
-  return static_cast<bool>(x) ? static_cast<bool>(*x > v) : false;
-}
-template <typename T, typename U>
-constexpr auto operator>(const U& v, const optional<T>& x)
-    -> decltype(optional_internal::convertible_to_bool(v > *x)) {
-  return static_cast<bool>(x) ? static_cast<bool>(v > *x) : true;
-}
-template <typename T, typename U>
-constexpr auto operator>=(const optional<T>& x, const U& v)
-    -> decltype(optional_internal::convertible_to_bool(*x >= v)) {
-  return static_cast<bool>(x) ? static_cast<bool>(*x >= v) : false;
-}
-template <typename T, typename U>
-constexpr auto operator>=(const U& v, const optional<T>& x)
-    -> decltype(optional_internal::convertible_to_bool(v >= *x)) {
-  return static_cast<bool>(x) ? static_cast<bool>(v >= *x) : true;
-}
-
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-namespace std {
-
-// std::hash specialization for absl::optional.
-template <typename T>
-struct hash<absl::optional<T> >
-    : absl::optional_internal::optional_hash_base<T> {};
-
-}  // namespace std
-
-#undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS
-
-#endif  // ABSL_USES_STD_OPTIONAL
-
 #endif  // ABSL_TYPES_OPTIONAL_H_
diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc
deleted file mode 100644
index 8e5fe85..0000000
--- a/absl/types/optional_exception_safety_test.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/types/optional.h"
-
-#include "absl/base/config.h"
-
-// This test is a no-op when absl::optional is an alias for std::optional and
-// when exceptions are not enabled.
-#if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS)
-
-#include "gtest/gtest.h"
-#include "absl/base/internal/exception_safety_testing.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-namespace {
-
-using ::testing::AssertionFailure;
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::MakeExceptionSafetyTester;
-
-using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
-using Optional = absl::optional<Thrower>;
-
-using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
-using MoveOptional = absl::optional<MoveThrower>;
-
-constexpr int kInitialInteger = 5;
-constexpr int kUpdatedInteger = 10;
-
-template <typename OptionalT>
-bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try {
-  return (static_cast<void>(optional.value()), false);
-} catch (const absl::bad_optional_access&) {
-  return true;
-}
-
-template <typename OptionalT>
-AssertionResult OptionalInvariants(OptionalT* optional_ptr) {
-  // Check the current state post-throw for validity
-  auto& optional = *optional_ptr;
-
-  if (optional.has_value() && ValueThrowsBadOptionalAccess(optional)) {
-    return AssertionFailure()
-           << "Optional with value should not throw bad_optional_access when "
-              "accessing the value.";
-  }
-  if (!optional.has_value() && !ValueThrowsBadOptionalAccess(optional)) {
-    return AssertionFailure()
-           << "Optional without a value should throw bad_optional_access when "
-              "accessing the value.";
-  }
-
-  // Reset to a known state
-  optional.reset();
-
-  // Confirm that the known post-reset state is valid
-  if (optional.has_value()) {
-    return AssertionFailure()
-           << "Optional should not contain a value after being reset.";
-  }
-  if (!ValueThrowsBadOptionalAccess(optional)) {
-    return AssertionFailure() << "Optional should throw bad_optional_access "
-                                 "when accessing the value after being reset.";
-  }
-
-  return AssertionSuccess();
-}
-
-template <typename OptionalT>
-AssertionResult CheckDisengaged(OptionalT* optional_ptr) {
-  auto& optional = *optional_ptr;
-
-  if (optional.has_value()) {
-    return AssertionFailure()
-           << "Expected optional to not contain a value but a value was found.";
-  }
-
-  return AssertionSuccess();
-}
-
-template <typename OptionalT>
-AssertionResult CheckEngaged(OptionalT* optional_ptr) {
-  auto& optional = *optional_ptr;
-
-  if (!optional.has_value()) {
-    return AssertionFailure()
-           << "Expected optional to contain a value but no value was found.";
-  }
-
-  return AssertionSuccess();
-}
-
-TEST(OptionalExceptionSafety, ThrowingConstructors) {
-  auto thrower_nonempty = Optional(Thrower(kInitialInteger));
-  testing::TestThrowingCtor<Optional>(thrower_nonempty);
-
-  auto integer_nonempty = absl::optional<int>(kInitialInteger);
-  testing::TestThrowingCtor<Optional>(integer_nonempty);
-  testing::TestThrowingCtor<Optional>(std::move(integer_nonempty));  // NOLINT
-
-  testing::TestThrowingCtor<Optional>(kInitialInteger);
-  using ThrowerVec = std::vector<Thrower, testing::ThrowingAllocator<Thrower>>;
-  testing::TestThrowingCtor<absl::optional<ThrowerVec>>(
-      absl::in_place,
-      std::initializer_list<Thrower>{Thrower(), Thrower(), Thrower()},
-      testing::ThrowingAllocator<Thrower>());
-}
-
-TEST(OptionalExceptionSafety, NothrowConstructors) {
-  // This constructor is marked noexcept. If it throws, the program will
-  // terminate.
-  testing::TestThrowingCtor<MoveOptional>(MoveOptional(kUpdatedInteger));
-}
-
-TEST(OptionalExceptionSafety, Emplace) {
-  // Test the basic guarantee plus test the result of optional::has_value()
-  // is false in all cases
-  auto disengaged_test = MakeExceptionSafetyTester().WithContracts(
-      OptionalInvariants<Optional>, CheckDisengaged<Optional>);
-  auto disengaged_test_empty = disengaged_test.WithInitialValue(Optional());
-  auto disengaged_test_nonempty =
-      disengaged_test.WithInitialValue(Optional(kInitialInteger));
-
-  auto emplace_thrower_directly = [](Optional* optional_ptr) {
-    optional_ptr->emplace(kUpdatedInteger);
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_directly));
-  EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_directly));
-
-  auto emplace_thrower_copy = [](Optional* optional_ptr) {
-    auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
-    optional_ptr->emplace(thrower);
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_copy));
-  EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_copy));
-}
-
-TEST(OptionalExceptionSafety, EverythingThrowsSwap) {
-  // Test the basic guarantee plus test the result of optional::has_value()
-  // remains the same
-  auto test =
-      MakeExceptionSafetyTester().WithContracts(OptionalInvariants<Optional>);
-  auto disengaged_test_empty = test.WithInitialValue(Optional())
-                                   .WithContracts(CheckDisengaged<Optional>);
-  auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
-                                   .WithContracts(CheckEngaged<Optional>);
-
-  auto swap_empty = [](Optional* optional_ptr) {
-    auto empty = Optional();
-    optional_ptr->swap(empty);
-  };
-  EXPECT_TRUE(engaged_test_nonempty.Test(swap_empty));
-
-  auto swap_nonempty = [](Optional* optional_ptr) {
-    auto nonempty =
-        Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
-    optional_ptr->swap(nonempty);
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(swap_nonempty));
-  EXPECT_TRUE(engaged_test_nonempty.Test(swap_nonempty));
-}
-
-TEST(OptionalExceptionSafety, NoThrowMoveSwap) {
-  // Tests the nothrow guarantee for optional of T with non-throwing move
-  {
-    auto empty = MoveOptional();
-    auto nonempty = MoveOptional(kInitialInteger);
-    EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty.swap(empty); }));
-  }
-  {
-    auto nonempty = MoveOptional(kUpdatedInteger);
-    auto empty = MoveOptional();
-    EXPECT_TRUE(testing::TestNothrowOp([&]() { empty.swap(nonempty); }));
-  }
-  {
-    auto nonempty_from = MoveOptional(kUpdatedInteger);
-    auto nonempty_to = MoveOptional(kInitialInteger);
-    EXPECT_TRUE(
-        testing::TestNothrowOp([&]() { nonempty_to.swap(nonempty_from); }));
-  }
-}
-
-TEST(OptionalExceptionSafety, CopyAssign) {
-  // Test the basic guarantee plus test the result of optional::has_value()
-  // remains the same
-  auto test =
-      MakeExceptionSafetyTester().WithContracts(OptionalInvariants<Optional>);
-  auto disengaged_test_empty = test.WithInitialValue(Optional())
-                                   .WithContracts(CheckDisengaged<Optional>);
-  auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
-                                   .WithContracts(CheckEngaged<Optional>);
-
-  auto copyassign_nonempty = [](Optional* optional_ptr) {
-    auto nonempty =
-        Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
-    *optional_ptr = nonempty;
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(copyassign_nonempty));
-  EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_nonempty));
-
-  auto copyassign_thrower = [](Optional* optional_ptr) {
-    auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
-    *optional_ptr = thrower;
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(copyassign_thrower));
-  EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_thrower));
-}
-
-TEST(OptionalExceptionSafety, MoveAssign) {
-  // Test the basic guarantee plus test the result of optional::has_value()
-  // remains the same
-  auto test =
-      MakeExceptionSafetyTester().WithContracts(OptionalInvariants<Optional>);
-  auto disengaged_test_empty = test.WithInitialValue(Optional())
-                                   .WithContracts(CheckDisengaged<Optional>);
-  auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
-                                   .WithContracts(CheckEngaged<Optional>);
-
-  auto moveassign_empty = [](Optional* optional_ptr) {
-    auto empty = Optional();
-    *optional_ptr = std::move(empty);
-  };
-  EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_empty));
-
-  auto moveassign_nonempty = [](Optional* optional_ptr) {
-    auto nonempty =
-        Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
-    *optional_ptr = std::move(nonempty);
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(moveassign_nonempty));
-  EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_nonempty));
-
-  auto moveassign_thrower = [](Optional* optional_ptr) {
-    auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
-    *optional_ptr = std::move(thrower);
-  };
-  EXPECT_TRUE(disengaged_test_empty.Test(moveassign_thrower));
-  EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_thrower));
-}
-
-TEST(OptionalExceptionSafety, NothrowMoveAssign) {
-  // Tests the nothrow guarantee for optional of T with non-throwing move
-  {
-    auto empty = MoveOptional();
-    auto nonempty = MoveOptional(kInitialInteger);
-    EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty = std::move(empty); }));
-  }
-  {
-    auto nonempty = MoveOptional(kInitialInteger);
-    auto empty = MoveOptional();
-    EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(nonempty); }));
-  }
-  {
-    auto nonempty_from = MoveOptional(kUpdatedInteger);
-    auto nonempty_to = MoveOptional(kInitialInteger);
-    EXPECT_TRUE(testing::TestNothrowOp(
-        [&]() { nonempty_to = std::move(nonempty_from); }));
-  }
-  {
-    auto thrower = MoveThrower(kUpdatedInteger);
-    auto empty = MoveOptional();
-    EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(thrower); }));
-  }
-  {
-    auto thrower = MoveThrower(kUpdatedInteger);
-    auto nonempty = MoveOptional(kInitialInteger);
-    EXPECT_TRUE(
-        testing::TestNothrowOp([&]() { nonempty = std::move(thrower); }));
-  }
-}
-
-}  // namespace
-
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#endif  // #if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS)
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
deleted file mode 100644
index 115e20c..0000000
--- a/absl/types/optional_test.cc
+++ /dev/null
@@ -1,1615 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/types/optional.h"
-
-// This test is a no-op when absl::optional is an alias for std::optional.
-#if !defined(ABSL_USES_STD_OPTIONAL)
-
-#include <string>
-#include <type_traits>
-#include <utility>
-
-#include "gtest/gtest.h"
-#include "absl/base/config.h"
-#include "absl/log/log.h"
-#include "absl/meta/type_traits.h"
-#include "absl/strings/string_view.h"
-
-#if defined(__cplusplus) && __cplusplus >= 202002L
-// In C++20, volatile-qualified return types are deprecated.
-#define ABSL_VOLATILE_RETURN_TYPES_DEPRECATED 1
-#endif
-
-// The following types help test an internal compiler error in GCC5 though
-// GCC10. The case OptionalTest.InternalCompilerErrorInGcc5ToGcc10 crashes the
-// compiler without a workaround. This test case should remain at the beginning
-// of the file as the internal compiler error is sensitive to other constructs
-// in this file.
-template <class T, class...>
-using GccIceHelper1 = T;
-template <typename T>
-struct GccIceHelper2 {};
-template <typename T>
-class GccIce {
-  template <typename U,
-            typename SecondTemplateArgHasToExistForSomeReason = void,
-            typename DependentType = void,
-            typename = std::is_assignable<GccIceHelper1<T, DependentType>&, U>>
-  GccIce& operator=(GccIceHelper2<U> const&) {}
-};
-
-TEST(OptionalTest, InternalCompilerErrorInGcc5ToGcc10) {
-  GccIce<int> instantiate_ice_with_same_type_as_optional;
-  static_cast<void>(instantiate_ice_with_same_type_as_optional);
-  absl::optional<int> val1;
-  absl::optional<int> val2;
-  val1 = val2;
-}
-
-struct Hashable {};
-
-namespace std {
-template <>
-struct hash<Hashable> {
-  size_t operator()(const Hashable&) { return 0; }
-};
-}  // namespace std
-
-struct NonHashable {};
-
-namespace {
-
-std::string TypeQuals(std::string&) { return "&"; }
-std::string TypeQuals(std::string&&) { return "&&"; }
-std::string TypeQuals(const std::string&) { return "c&"; }
-std::string TypeQuals(const std::string&&) { return "c&&"; }
-
-struct StructorListener {
-  int construct0 = 0;
-  int construct1 = 0;
-  int construct2 = 0;
-  int listinit = 0;
-  int copy = 0;
-  int move = 0;
-  int copy_assign = 0;
-  int move_assign = 0;
-  int destruct = 0;
-  int volatile_copy = 0;
-  int volatile_move = 0;
-  int volatile_copy_assign = 0;
-  int volatile_move_assign = 0;
-};
-
-// Suppress MSVC warnings.
-// 4521: multiple copy constructors specified
-// 4522: multiple assignment operators specified
-// We wrote multiple of them to test that the correct overloads are selected.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4521)
-#pragma warning(disable : 4522)
-#endif
-struct Listenable {
-  static StructorListener* listener;
-
-  Listenable() { ++listener->construct0; }
-  explicit Listenable(int /*unused*/) { ++listener->construct1; }
-  Listenable(int /*unused*/, int /*unused*/) { ++listener->construct2; }
-  Listenable(std::initializer_list<int> /*unused*/) { ++listener->listinit; }
-  Listenable(const Listenable& /*unused*/) { ++listener->copy; }
-  Listenable(const volatile Listenable& /*unused*/) {
-    ++listener->volatile_copy;
-  }
-  Listenable(volatile Listenable&& /*unused*/) { ++listener->volatile_move; }
-  Listenable(Listenable&& /*unused*/) { ++listener->move; }
-  Listenable& operator=(const Listenable& /*unused*/) {
-    ++listener->copy_assign;
-    return *this;
-  }
-  Listenable& operator=(Listenable&& /*unused*/) {
-    ++listener->move_assign;
-    return *this;
-  }
-  // use void return type instead of volatile T& to work around GCC warning
-  // when the assignment's returned reference is ignored.
-  void operator=(const volatile Listenable& /*unused*/) volatile {
-    ++listener->volatile_copy_assign;
-  }
-  void operator=(volatile Listenable&& /*unused*/) volatile {
-    ++listener->volatile_move_assign;
-  }
-  ~Listenable() { ++listener->destruct; }
-};
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-StructorListener* Listenable::listener = nullptr;
-
-struct ConstexprType {
-  enum CtorTypes {
-    kCtorDefault,
-    kCtorInt,
-    kCtorInitializerList,
-    kCtorConstChar
-  };
-  constexpr ConstexprType() : x(kCtorDefault) {}
-  constexpr explicit ConstexprType(int i) : x(kCtorInt) {}
-  constexpr ConstexprType(std::initializer_list<int> il)
-      : x(kCtorInitializerList) {}
-  constexpr ConstexprType(const char*)  // NOLINT(runtime/explicit)
-      : x(kCtorConstChar) {}
-  int x;
-};
-
-struct Copyable {
-  Copyable() {}
-  Copyable(const Copyable&) {}
-  Copyable& operator=(const Copyable&) { return *this; }
-};
-
-struct MoveableThrow {
-  MoveableThrow() {}
-  MoveableThrow(MoveableThrow&&) {}
-  MoveableThrow& operator=(MoveableThrow&&) { return *this; }
-};
-
-struct MoveableNoThrow {
-  MoveableNoThrow() {}
-  MoveableNoThrow(MoveableNoThrow&&) noexcept {}
-  MoveableNoThrow& operator=(MoveableNoThrow&&) noexcept { return *this; }
-};
-
-struct NonMovable {
-  NonMovable() {}
-  NonMovable(const NonMovable&) = delete;
-  NonMovable& operator=(const NonMovable&) = delete;
-  NonMovable(NonMovable&&) = delete;
-  NonMovable& operator=(NonMovable&&) = delete;
-};
-
-struct NoDefault {
-  NoDefault() = delete;
-  NoDefault(const NoDefault&) {}
-  NoDefault& operator=(const NoDefault&) { return *this; }
-};
-
-struct ConvertsFromInPlaceT {
-  ConvertsFromInPlaceT(absl::in_place_t) {}  // NOLINT
-};
-
-TEST(optionalTest, DefaultConstructor) {
-  absl::optional<int> empty;
-  EXPECT_FALSE(empty);
-  constexpr absl::optional<int> cempty;
-  static_assert(!cempty.has_value(), "");
-  EXPECT_TRUE(
-      std::is_nothrow_default_constructible<absl::optional<int>>::value);
-}
-
-TEST(optionalTest, nulloptConstructor) {
-  absl::optional<int> empty(absl::nullopt);
-  EXPECT_FALSE(empty);
-  constexpr absl::optional<int> cempty{absl::nullopt};
-  static_assert(!cempty.has_value(), "");
-  EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>,
-                                             absl::nullopt_t>::value));
-}
-
-TEST(optionalTest, CopyConstructor) {
-  {
-    absl::optional<int> empty, opt42 = 42;
-    absl::optional<int> empty_copy(empty);
-    EXPECT_FALSE(empty_copy);
-    absl::optional<int> opt42_copy(opt42);
-    EXPECT_TRUE(opt42_copy);
-    EXPECT_EQ(42, *opt42_copy);
-  }
-  {
-    absl::optional<const int> empty, opt42 = 42;
-    absl::optional<const int> empty_copy(empty);
-    EXPECT_FALSE(empty_copy);
-    absl::optional<const int> opt42_copy(opt42);
-    EXPECT_TRUE(opt42_copy);
-    EXPECT_EQ(42, *opt42_copy);
-  }
-#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  {
-    absl::optional<volatile int> empty, opt42 = 42;
-    absl::optional<volatile int> empty_copy(empty);
-    EXPECT_FALSE(empty_copy);
-    absl::optional<volatile int> opt42_copy(opt42);
-    EXPECT_TRUE(opt42_copy);
-    EXPECT_EQ(42, *opt42_copy);
-  }
-#endif
-  // test copyablility
-  EXPECT_TRUE(std::is_copy_constructible<absl::optional<int>>::value);
-  EXPECT_TRUE(std::is_copy_constructible<absl::optional<Copyable>>::value);
-  EXPECT_FALSE(
-      std::is_copy_constructible<absl::optional<MoveableThrow>>::value);
-  EXPECT_FALSE(
-      std::is_copy_constructible<absl::optional<MoveableNoThrow>>::value);
-  EXPECT_FALSE(std::is_copy_constructible<absl::optional<NonMovable>>::value);
-
-  EXPECT_FALSE(
-      absl::is_trivially_copy_constructible<absl::optional<Copyable>>::value);
-  EXPECT_TRUE(
-      absl::is_trivially_copy_constructible<absl::optional<int>>::value);
-  EXPECT_TRUE(
-      absl::is_trivially_copy_constructible<absl::optional<const int>>::value);
-#if !defined(_MSC_VER) && !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  // See defect report "Trivial copy/move constructor for class with volatile
-  // member" at
-  // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094
-  // A class with non-static data member of volatile-qualified type should still
-  // have a trivial copy constructor if the data member is trivial.
-  // Also a cv-qualified scalar type should be trivially copyable.
-  EXPECT_TRUE(absl::is_trivially_copy_constructible<
-              absl::optional<volatile int>>::value);
-#endif  // !defined(_MSC_VER) && !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-
-  // constexpr copy constructor for trivially copyable types
-  {
-    constexpr absl::optional<int> o1;
-    constexpr absl::optional<int> o2 = o1;
-    static_assert(!o2, "");
-  }
-  {
-    constexpr absl::optional<int> o1 = 42;
-    constexpr absl::optional<int> o2 = o1;
-    static_assert(o2, "");
-    static_assert(*o2 == 42, "");
-  }
-  {
-    struct TrivialCopyable {
-      constexpr TrivialCopyable() : x(0) {}
-      constexpr explicit TrivialCopyable(int i) : x(i) {}
-      int x;
-    };
-    constexpr absl::optional<TrivialCopyable> o1(42);
-    constexpr absl::optional<TrivialCopyable> o2 = o1;
-    static_assert(o2, "");
-    static_assert((*o2).x == 42, "");
-#ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
-    EXPECT_TRUE(absl::is_trivially_copy_constructible<
-                absl::optional<TrivialCopyable>>::value);
-    EXPECT_TRUE(absl::is_trivially_copy_constructible<
-                absl::optional<const TrivialCopyable>>::value);
-#endif
-#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-    EXPECT_FALSE(std::is_copy_constructible<
-                 absl::optional<volatile TrivialCopyable>>::value);
-#endif  // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  }
-}
-
-TEST(optionalTest, MoveConstructor) {
-  absl::optional<int> empty, opt42 = 42;
-  absl::optional<int> empty_move(std::move(empty));
-  EXPECT_FALSE(empty_move);
-  absl::optional<int> opt42_move(std::move(opt42));
-  EXPECT_TRUE(opt42_move);
-  EXPECT_EQ(42, opt42_move);
-  // test movability
-  EXPECT_TRUE(std::is_move_constructible<absl::optional<int>>::value);
-  EXPECT_TRUE(std::is_move_constructible<absl::optional<Copyable>>::value);
-  EXPECT_TRUE(std::is_move_constructible<absl::optional<MoveableThrow>>::value);
-  EXPECT_TRUE(
-      std::is_move_constructible<absl::optional<MoveableNoThrow>>::value);
-  EXPECT_FALSE(std::is_move_constructible<absl::optional<NonMovable>>::value);
-  // test noexcept
-  EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value);
-  EXPECT_EQ(
-      absl::default_allocator_is_nothrow::value,
-      std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value);
-  EXPECT_TRUE(std::is_nothrow_move_constructible<
-              absl::optional<MoveableNoThrow>>::value);
-}
-
-TEST(optionalTest, Destructor) {
-  struct Trivial {};
-
-  struct NonTrivial {
-    NonTrivial(const NonTrivial&) {}
-    NonTrivial& operator=(const NonTrivial&) { return *this; }
-    ~NonTrivial() {}
-  };
-
-  EXPECT_TRUE(std::is_trivially_destructible<absl::optional<int>>::value);
-  EXPECT_TRUE(std::is_trivially_destructible<absl::optional<Trivial>>::value);
-  EXPECT_FALSE(
-      std::is_trivially_destructible<absl::optional<NonTrivial>>::value);
-}
-
-TEST(optionalTest, InPlaceConstructor) {
-  constexpr absl::optional<ConstexprType> opt0{absl::in_place_t()};
-  static_assert(opt0, "");
-  static_assert((*opt0).x == ConstexprType::kCtorDefault, "");
-  constexpr absl::optional<ConstexprType> opt1{absl::in_place_t(), 1};
-  static_assert(opt1, "");
-  static_assert((*opt1).x == ConstexprType::kCtorInt, "");
-  constexpr absl::optional<ConstexprType> opt2{absl::in_place_t(), {1, 2}};
-  static_assert(opt2, "");
-  static_assert((*opt2).x == ConstexprType::kCtorInitializerList, "");
-
-  EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
-                                      absl::in_place_t>::value));
-  EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
-                                      const absl::in_place_t&>::value));
-  EXPECT_TRUE(
-      (std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
-                             absl::in_place_t, absl::in_place_t>::value));
-
-  EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
-                                      absl::in_place_t>::value));
-  EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
-                                      absl::in_place_t&&>::value));
-}
-
-// template<U=T> optional(U&&);
-TEST(optionalTest, ValueConstructor) {
-  constexpr absl::optional<int> opt0(0);
-  static_assert(opt0, "");
-  static_assert(*opt0 == 0, "");
-  EXPECT_TRUE((std::is_convertible<int, absl::optional<int>>::value));
-  // Copy initialization ( = "abc") won't work due to optional(optional&&)
-  // is not constexpr. Use list initialization instead. This invokes
-  // absl::optional<ConstexprType>::absl::optional<U>(U&&), with U = const char
-  // (&) [4], which direct-initializes the ConstexprType value held by the
-  // optional via ConstexprType::ConstexprType(const char*).
-  constexpr absl::optional<ConstexprType> opt1 = {"abc"};
-  static_assert(opt1, "");
-  static_assert(ConstexprType::kCtorConstChar == (*opt1).x, "");
-  EXPECT_TRUE(
-      (std::is_convertible<const char*, absl::optional<ConstexprType>>::value));
-  // direct initialization
-  constexpr absl::optional<ConstexprType> opt2{2};
-  static_assert(opt2, "");
-  static_assert(ConstexprType::kCtorInt == (*opt2).x, "");
-  EXPECT_FALSE(
-      (std::is_convertible<int, absl::optional<ConstexprType>>::value));
-
-  // this invokes absl::optional<int>::optional(int&&)
-  // NOTE: this has different behavior than assignment, e.g.
-  // "opt3 = {};" clears the optional rather than setting the value to 0
-  // According to C++17 standard N4659 [over.ics.list] 16.3.3.1.5, (9.2)- "if
-  // the initializer list has no elements, the implicit conversion is the
-  // identity conversion", so `optional(int&&)` should be a better match than
-  // `optional(optional&&)` which is a user-defined conversion.
-  // Note: GCC 7 has a bug with this overload selection when compiled with
-  // `-std=c++17`.
-#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 7 && \
-    __cplusplus == 201703L
-#define ABSL_GCC7_OVER_ICS_LIST_BUG 1
-#endif
-#ifndef ABSL_GCC7_OVER_ICS_LIST_BUG
-  constexpr absl::optional<int> opt3({});
-  static_assert(opt3, "");
-  static_assert(*opt3 == 0, "");
-#endif
-
-  // this invokes the move constructor with a default constructed optional
-  // because non-template function is a better match than template function.
-  absl::optional<ConstexprType> opt4({});
-  EXPECT_FALSE(opt4);
-}
-
-struct Implicit {};
-
-struct Explicit {};
-
-struct Convert {
-  Convert(const Implicit&)  // NOLINT(runtime/explicit)
-      : implicit(true), move(false) {}
-  Convert(Implicit&&)  // NOLINT(runtime/explicit)
-      : implicit(true), move(true) {}
-  explicit Convert(const Explicit&) : implicit(false), move(false) {}
-  explicit Convert(Explicit&&) : implicit(false), move(true) {}
-
-  bool implicit;
-  bool move;
-};
-
-struct ConvertFromOptional {
-  ConvertFromOptional(const Implicit&)  // NOLINT(runtime/explicit)
-      : implicit(true), move(false), from_optional(false) {}
-  ConvertFromOptional(Implicit&&)  // NOLINT(runtime/explicit)
-      : implicit(true), move(true), from_optional(false) {}
-  ConvertFromOptional(
-      const absl::optional<Implicit>&)  // NOLINT(runtime/explicit)
-      : implicit(true), move(false), from_optional(true) {}
-  ConvertFromOptional(absl::optional<Implicit>&&)  // NOLINT(runtime/explicit)
-      : implicit(true), move(true), from_optional(true) {}
-  explicit ConvertFromOptional(const Explicit&)
-      : implicit(false), move(false), from_optional(false) {}
-  explicit ConvertFromOptional(Explicit&&)
-      : implicit(false), move(true), from_optional(false) {}
-  explicit ConvertFromOptional(const absl::optional<Explicit>&)
-      : implicit(false), move(false), from_optional(true) {}
-  explicit ConvertFromOptional(absl::optional<Explicit>&&)
-      : implicit(false), move(true), from_optional(true) {}
-
-  bool implicit;
-  bool move;
-  bool from_optional;
-};
-
-TEST(optionalTest, ConvertingConstructor) {
-  absl::optional<Implicit> i_empty;
-  absl::optional<Implicit> i(absl::in_place);
-  absl::optional<Explicit> e_empty;
-  absl::optional<Explicit> e(absl::in_place);
-  {
-    // implicitly constructing absl::optional<Convert> from
-    // absl::optional<Implicit>
-    absl::optional<Convert> empty = i_empty;
-    EXPECT_FALSE(empty);
-    absl::optional<Convert> opt_copy = i;
-    EXPECT_TRUE(opt_copy);
-    EXPECT_TRUE(opt_copy->implicit);
-    EXPECT_FALSE(opt_copy->move);
-    absl::optional<Convert> opt_move = absl::optional<Implicit>(absl::in_place);
-    EXPECT_TRUE(opt_move);
-    EXPECT_TRUE(opt_move->implicit);
-    EXPECT_TRUE(opt_move->move);
-  }
-  {
-    // explicitly constructing absl::optional<Convert> from
-    // absl::optional<Explicit>
-    absl::optional<Convert> empty(e_empty);
-    EXPECT_FALSE(empty);
-    absl::optional<Convert> opt_copy(e);
-    EXPECT_TRUE(opt_copy);
-    EXPECT_FALSE(opt_copy->implicit);
-    EXPECT_FALSE(opt_copy->move);
-    EXPECT_FALSE((std::is_convertible<const absl::optional<Explicit>&,
-                                      absl::optional<Convert>>::value));
-    absl::optional<Convert> opt_move{absl::optional<Explicit>(absl::in_place)};
-    EXPECT_TRUE(opt_move);
-    EXPECT_FALSE(opt_move->implicit);
-    EXPECT_TRUE(opt_move->move);
-    EXPECT_FALSE((std::is_convertible<absl::optional<Explicit>&&,
-                                      absl::optional<Convert>>::value));
-  }
-  {
-    // implicitly constructing absl::optional<ConvertFromOptional> from
-    // absl::optional<Implicit> via
-    // ConvertFromOptional(absl::optional<Implicit>&&) check that
-    // ConvertFromOptional(Implicit&&) is NOT called
-    static_assert(
-        std::is_convertible<absl::optional<Implicit>,
-                            absl::optional<ConvertFromOptional>>::value,
-        "");
-    absl::optional<ConvertFromOptional> opt0 = i_empty;
-    EXPECT_TRUE(opt0);
-    EXPECT_TRUE(opt0->implicit);
-    EXPECT_FALSE(opt0->move);
-    EXPECT_TRUE(opt0->from_optional);
-    absl::optional<ConvertFromOptional> opt1 = absl::optional<Implicit>();
-    EXPECT_TRUE(opt1);
-    EXPECT_TRUE(opt1->implicit);
-    EXPECT_TRUE(opt1->move);
-    EXPECT_TRUE(opt1->from_optional);
-  }
-  {
-    // implicitly constructing absl::optional<ConvertFromOptional> from
-    // absl::optional<Explicit> via
-    // ConvertFromOptional(absl::optional<Explicit>&&) check that
-    // ConvertFromOptional(Explicit&&) is NOT called
-    absl::optional<ConvertFromOptional> opt0(e_empty);
-    EXPECT_TRUE(opt0);
-    EXPECT_FALSE(opt0->implicit);
-    EXPECT_FALSE(opt0->move);
-    EXPECT_TRUE(opt0->from_optional);
-    EXPECT_FALSE(
-        (std::is_convertible<const absl::optional<Explicit>&,
-                             absl::optional<ConvertFromOptional>>::value));
-    absl::optional<ConvertFromOptional> opt1{absl::optional<Explicit>()};
-    EXPECT_TRUE(opt1);
-    EXPECT_FALSE(opt1->implicit);
-    EXPECT_TRUE(opt1->move);
-    EXPECT_TRUE(opt1->from_optional);
-    EXPECT_FALSE(
-        (std::is_convertible<absl::optional<Explicit>&&,
-                             absl::optional<ConvertFromOptional>>::value));
-  }
-}
-
-TEST(optionalTest, StructorBasic) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-  {
-    absl::optional<Listenable> empty;
-    EXPECT_FALSE(empty);
-    absl::optional<Listenable> opt0(absl::in_place);
-    EXPECT_TRUE(opt0);
-    absl::optional<Listenable> opt1(absl::in_place, 1);
-    EXPECT_TRUE(opt1);
-    absl::optional<Listenable> opt2(absl::in_place, 1, 2);
-    EXPECT_TRUE(opt2);
-  }
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(1, listener.construct1);
-  EXPECT_EQ(1, listener.construct2);
-  EXPECT_EQ(3, listener.destruct);
-}
-
-TEST(optionalTest, CopyMoveStructor) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-  absl::optional<Listenable> original(absl::in_place);
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(0, listener.copy);
-  EXPECT_EQ(0, listener.move);
-  absl::optional<Listenable> copy(original);
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(1, listener.copy);
-  EXPECT_EQ(0, listener.move);
-  absl::optional<Listenable> move(std::move(original));
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(1, listener.copy);
-  EXPECT_EQ(1, listener.move);
-}
-
-TEST(optionalTest, ListInit) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-  absl::optional<Listenable> listinit1(absl::in_place, {1});
-  absl::optional<Listenable> listinit2(absl::in_place, {1, 2});
-  EXPECT_EQ(2, listener.listinit);
-}
-
-TEST(optionalTest, AssignFromNullopt) {
-  absl::optional<int> opt(1);
-  opt = absl::nullopt;
-  EXPECT_FALSE(opt);
-
-  StructorListener listener;
-  Listenable::listener = &listener;
-  absl::optional<Listenable> opt1(absl::in_place);
-  opt1 = absl::nullopt;
-  EXPECT_FALSE(opt1);
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(1, listener.destruct);
-
-  EXPECT_TRUE((
-      std::is_nothrow_assignable<absl::optional<int>, absl::nullopt_t>::value));
-  EXPECT_TRUE((std::is_nothrow_assignable<absl::optional<Listenable>,
-                                          absl::nullopt_t>::value));
-}
-
-TEST(optionalTest, CopyAssignment) {
-  const absl::optional<int> empty, opt1 = 1, opt2 = 2;
-  absl::optional<int> empty_to_opt1, opt1_to_opt2, opt2_to_empty;
-
-  EXPECT_FALSE(empty_to_opt1);
-  empty_to_opt1 = empty;
-  EXPECT_FALSE(empty_to_opt1);
-  empty_to_opt1 = opt1;
-  EXPECT_TRUE(empty_to_opt1);
-  EXPECT_EQ(1, empty_to_opt1.value());
-
-  EXPECT_FALSE(opt1_to_opt2);
-  opt1_to_opt2 = opt1;
-  EXPECT_TRUE(opt1_to_opt2);
-  EXPECT_EQ(1, opt1_to_opt2.value());
-  opt1_to_opt2 = opt2;
-  EXPECT_TRUE(opt1_to_opt2);
-  EXPECT_EQ(2, opt1_to_opt2.value());
-
-  EXPECT_FALSE(opt2_to_empty);
-  opt2_to_empty = opt2;
-  EXPECT_TRUE(opt2_to_empty);
-  EXPECT_EQ(2, opt2_to_empty.value());
-  opt2_to_empty = empty;
-  EXPECT_FALSE(opt2_to_empty);
-
-  EXPECT_FALSE(absl::is_copy_assignable<absl::optional<const int>>::value);
-  EXPECT_TRUE(absl::is_copy_assignable<absl::optional<Copyable>>::value);
-  EXPECT_FALSE(absl::is_copy_assignable<absl::optional<MoveableThrow>>::value);
-  EXPECT_FALSE(
-      absl::is_copy_assignable<absl::optional<MoveableNoThrow>>::value);
-  EXPECT_FALSE(absl::is_copy_assignable<absl::optional<NonMovable>>::value);
-
-  EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value);
-  EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value);
-
-  struct Trivial {
-    int i;
-  };
-  struct NonTrivial {
-    NonTrivial& operator=(const NonTrivial&) { return *this; }
-    int i;
-  };
-
-  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
-  EXPECT_FALSE(absl::is_copy_assignable<const Trivial>::value);
-  EXPECT_FALSE(absl::is_copy_assignable<volatile Trivial>::value);
-  EXPECT_TRUE(absl::is_copy_assignable<NonTrivial>::value);
-  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value);
-
-#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  {
-    StructorListener listener;
-    Listenable::listener = &listener;
-
-    absl::optional<volatile Listenable> empty, set(absl::in_place);
-    EXPECT_EQ(1, listener.construct0);
-    absl::optional<volatile Listenable> empty_to_empty, empty_to_set,
-        set_to_empty(absl::in_place), set_to_set(absl::in_place);
-    EXPECT_EQ(3, listener.construct0);
-    empty_to_empty = empty;  // no effect
-    empty_to_set = set;      // copy construct
-    set_to_empty = empty;    // destruct
-    set_to_set = set;        // copy assign
-    EXPECT_EQ(1, listener.volatile_copy);
-    EXPECT_EQ(0, listener.volatile_move);
-    EXPECT_EQ(1, listener.destruct);
-    EXPECT_EQ(1, listener.volatile_copy_assign);
-  }
-#endif  // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-}
-
-TEST(optionalTest, MoveAssignment) {
-  {
-    StructorListener listener;
-    Listenable::listener = &listener;
-
-    absl::optional<Listenable> empty1, empty2, set1(absl::in_place),
-        set2(absl::in_place);
-    EXPECT_EQ(2, listener.construct0);
-    absl::optional<Listenable> empty_to_empty, empty_to_set,
-        set_to_empty(absl::in_place), set_to_set(absl::in_place);
-    EXPECT_EQ(4, listener.construct0);
-    empty_to_empty = std::move(empty1);
-    empty_to_set = std::move(set1);
-    set_to_empty = std::move(empty2);
-    set_to_set = std::move(set2);
-    EXPECT_EQ(0, listener.copy);
-    EXPECT_EQ(1, listener.move);
-    EXPECT_EQ(1, listener.destruct);
-    EXPECT_EQ(1, listener.move_assign);
-  }
-#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  {
-    StructorListener listener;
-    Listenable::listener = &listener;
-
-    absl::optional<volatile Listenable> empty1, empty2, set1(absl::in_place),
-        set2(absl::in_place);
-    EXPECT_EQ(2, listener.construct0);
-    absl::optional<volatile Listenable> empty_to_empty, empty_to_set,
-        set_to_empty(absl::in_place), set_to_set(absl::in_place);
-    EXPECT_EQ(4, listener.construct0);
-    empty_to_empty = std::move(empty1);  // no effect
-    empty_to_set = std::move(set1);      // move construct
-    set_to_empty = std::move(empty2);    // destruct
-    set_to_set = std::move(set2);        // move assign
-    EXPECT_EQ(0, listener.volatile_copy);
-    EXPECT_EQ(1, listener.volatile_move);
-    EXPECT_EQ(1, listener.destruct);
-    EXPECT_EQ(1, listener.volatile_move_assign);
-  }
-#endif  // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  EXPECT_FALSE(absl::is_move_assignable<absl::optional<const int>>::value);
-  EXPECT_TRUE(absl::is_move_assignable<absl::optional<Copyable>>::value);
-  EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableThrow>>::value);
-  EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableNoThrow>>::value);
-  EXPECT_FALSE(absl::is_move_assignable<absl::optional<NonMovable>>::value);
-
-  EXPECT_FALSE(
-      std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value);
-  EXPECT_TRUE(
-      std::is_nothrow_move_assignable<absl::optional<MoveableNoThrow>>::value);
-}
-
-struct NoConvertToOptional {
-  // disable implicit conversion from const NoConvertToOptional&
-  // to absl::optional<NoConvertToOptional>.
-  NoConvertToOptional(const NoConvertToOptional&) = delete;
-};
-
-struct CopyConvert {
-  CopyConvert(const NoConvertToOptional&);
-  CopyConvert& operator=(const CopyConvert&) = delete;
-  CopyConvert& operator=(const NoConvertToOptional&);
-};
-
-struct CopyConvertFromOptional {
-  CopyConvertFromOptional(const NoConvertToOptional&);
-  CopyConvertFromOptional(const absl::optional<NoConvertToOptional>&);
-  CopyConvertFromOptional& operator=(const CopyConvertFromOptional&) = delete;
-  CopyConvertFromOptional& operator=(const NoConvertToOptional&);
-  CopyConvertFromOptional& operator=(
-      const absl::optional<NoConvertToOptional>&);
-};
-
-struct MoveConvert {
-  MoveConvert(NoConvertToOptional&&);
-  MoveConvert& operator=(const MoveConvert&) = delete;
-  MoveConvert& operator=(NoConvertToOptional&&);
-};
-
-struct MoveConvertFromOptional {
-  MoveConvertFromOptional(NoConvertToOptional&&);
-  MoveConvertFromOptional(absl::optional<NoConvertToOptional>&&);
-  MoveConvertFromOptional& operator=(const MoveConvertFromOptional&) = delete;
-  MoveConvertFromOptional& operator=(NoConvertToOptional&&);
-  MoveConvertFromOptional& operator=(absl::optional<NoConvertToOptional>&&);
-};
-
-// template <typename U = T> absl::optional<T>& operator=(U&& v);
-TEST(optionalTest, ValueAssignment) {
-  absl::optional<int> opt;
-  EXPECT_FALSE(opt);
-  opt = 42;
-  EXPECT_TRUE(opt);
-  EXPECT_EQ(42, opt.value());
-  opt = absl::nullopt;
-  EXPECT_FALSE(opt);
-  opt = 42;
-  EXPECT_TRUE(opt);
-  EXPECT_EQ(42, opt.value());
-  opt = 43;
-  EXPECT_TRUE(opt);
-  EXPECT_EQ(43, opt.value());
-  opt = {};  // this should clear optional
-  EXPECT_FALSE(opt);
-
-  opt = {44};
-  EXPECT_TRUE(opt);
-  EXPECT_EQ(44, opt.value());
-
-  // U = const NoConvertToOptional&
-  EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvert>&,
-                                  const NoConvertToOptional&>::value));
-  // U = const absl::optional<NoConvertToOptional>&
-  EXPECT_TRUE((std::is_assignable<absl::optional<CopyConvertFromOptional>&,
-                                  const NoConvertToOptional&>::value));
-  // U = const NoConvertToOptional& triggers SFINAE because
-  // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
-  EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvert>&,
-                                   const NoConvertToOptional&>::value));
-  // U = NoConvertToOptional
-  EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvert>&,
-                                  NoConvertToOptional&&>::value));
-  // U = const NoConvertToOptional& triggers SFINAE because
-  // std::is_constructible_v<MoveConvertFromOptional, const
-  // NoConvertToOptional&> is false
-  EXPECT_FALSE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,
-                                   const NoConvertToOptional&>::value));
-  // U = NoConvertToOptional
-  EXPECT_TRUE((std::is_assignable<absl::optional<MoveConvertFromOptional>&,
-                                  NoConvertToOptional&&>::value));
-  // U = const absl::optional<NoConvertToOptional>&
-  EXPECT_TRUE(
-      (std::is_assignable<absl::optional<CopyConvertFromOptional>&,
-                          const absl::optional<NoConvertToOptional>&>::value));
-  // U = absl::optional<NoConvertToOptional>
-  EXPECT_TRUE(
-      (std::is_assignable<absl::optional<MoveConvertFromOptional>&,
-                          absl::optional<NoConvertToOptional>&&>::value));
-}
-
-// template <typename U> absl::optional<T>& operator=(const absl::optional<U>&
-// rhs); template <typename U> absl::optional<T>& operator=(absl::optional<U>&&
-// rhs);
-TEST(optionalTest, ConvertingAssignment) {
-  absl::optional<int> opt_i;
-  absl::optional<char> opt_c('c');
-  opt_i = opt_c;
-  EXPECT_TRUE(opt_i);
-  EXPECT_EQ(*opt_c, *opt_i);
-  opt_i = absl::optional<char>();
-  EXPECT_FALSE(opt_i);
-  opt_i = absl::optional<char>('d');
-  EXPECT_TRUE(opt_i);
-  EXPECT_EQ('d', *opt_i);
-
-  absl::optional<std::string> opt_str;
-  absl::optional<const char*> opt_cstr("abc");
-  opt_str = opt_cstr;
-  EXPECT_TRUE(opt_str);
-  EXPECT_EQ(std::string("abc"), *opt_str);
-  opt_str = absl::optional<const char*>();
-  EXPECT_FALSE(opt_str);
-  opt_str = absl::optional<const char*>("def");
-  EXPECT_TRUE(opt_str);
-  EXPECT_EQ(std::string("def"), *opt_str);
-
-  // operator=(const absl::optional<U>&) with U = NoConvertToOptional
-  EXPECT_TRUE(
-      (std::is_assignable<absl::optional<CopyConvert>,
-                          const absl::optional<NoConvertToOptional>&>::value));
-  // operator=(const absl::optional<U>&) with U = NoConvertToOptional
-  // triggers SFINAE because
-  // std::is_constructible_v<MoveConvert, const NoConvertToOptional&> is false
-  EXPECT_FALSE(
-      (std::is_assignable<absl::optional<MoveConvert>&,
-                          const absl::optional<NoConvertToOptional>&>::value));
-  // operator=(absl::optional<U>&&) with U = NoConvertToOptional
-  EXPECT_TRUE(
-      (std::is_assignable<absl::optional<MoveConvert>&,
-                          absl::optional<NoConvertToOptional>&&>::value));
-  // operator=(const absl::optional<U>&) with U = NoConvertToOptional triggers
-  // SFINAE because std::is_constructible_v<MoveConvertFromOptional, const
-  // NoConvertToOptional&> is false. operator=(U&&) with U = const
-  // absl::optional<NoConverToOptional>& triggers SFINAE because
-  // std::is_constructible<MoveConvertFromOptional,
-  // absl::optional<NoConvertToOptional>&&> is true.
-  EXPECT_FALSE(
-      (std::is_assignable<absl::optional<MoveConvertFromOptional>&,
-                          const absl::optional<NoConvertToOptional>&>::value));
-}
-
-TEST(optionalTest, ResetAndHasValue) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-  absl::optional<Listenable> opt;
-  EXPECT_FALSE(opt);
-  EXPECT_FALSE(opt.has_value());
-  opt.emplace();
-  EXPECT_TRUE(opt);
-  EXPECT_TRUE(opt.has_value());
-  opt.reset();
-  EXPECT_FALSE(opt);
-  EXPECT_FALSE(opt.has_value());
-  EXPECT_EQ(1, listener.destruct);
-  opt.reset();
-  EXPECT_FALSE(opt);
-  EXPECT_FALSE(opt.has_value());
-
-  constexpr absl::optional<int> empty;
-  static_assert(!empty.has_value(), "");
-  constexpr absl::optional<int> nonempty(1);
-  static_assert(nonempty.has_value(), "");
-}
-
-TEST(optionalTest, Emplace) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-  absl::optional<Listenable> opt;
-  EXPECT_FALSE(opt);
-  opt.emplace(1);
-  EXPECT_TRUE(opt);
-  opt.emplace(1, 2);
-  EXPECT_EQ(1, listener.construct1);
-  EXPECT_EQ(1, listener.construct2);
-  EXPECT_EQ(1, listener.destruct);
-
-  absl::optional<std::string> o;
-  EXPECT_TRUE((std::is_same<std::string&, decltype(o.emplace("abc"))>::value));
-  std::string& ref = o.emplace("abc");
-  EXPECT_EQ(&ref, &o.value());
-}
-
-TEST(optionalTest, ListEmplace) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-  absl::optional<Listenable> opt;
-  EXPECT_FALSE(opt);
-  opt.emplace({1});
-  EXPECT_TRUE(opt);
-  opt.emplace({1, 2});
-  EXPECT_EQ(2, listener.listinit);
-  EXPECT_EQ(1, listener.destruct);
-
-  absl::optional<Listenable> o;
-  EXPECT_TRUE((std::is_same<Listenable&, decltype(o.emplace({1}))>::value));
-  Listenable& ref = o.emplace({1});
-  EXPECT_EQ(&ref, &o.value());
-}
-
-TEST(optionalTest, Swap) {
-  absl::optional<int> opt_empty, opt1 = 1, opt2 = 2;
-  EXPECT_FALSE(opt_empty);
-  EXPECT_TRUE(opt1);
-  EXPECT_EQ(1, opt1.value());
-  EXPECT_TRUE(opt2);
-  EXPECT_EQ(2, opt2.value());
-  swap(opt_empty, opt1);
-  EXPECT_FALSE(opt1);
-  EXPECT_TRUE(opt_empty);
-  EXPECT_EQ(1, opt_empty.value());
-  EXPECT_TRUE(opt2);
-  EXPECT_EQ(2, opt2.value());
-  swap(opt_empty, opt1);
-  EXPECT_FALSE(opt_empty);
-  EXPECT_TRUE(opt1);
-  EXPECT_EQ(1, opt1.value());
-  EXPECT_TRUE(opt2);
-  EXPECT_EQ(2, opt2.value());
-  swap(opt1, opt2);
-  EXPECT_FALSE(opt_empty);
-  EXPECT_TRUE(opt1);
-  EXPECT_EQ(2, opt1.value());
-  EXPECT_TRUE(opt2);
-  EXPECT_EQ(1, opt2.value());
-
-  EXPECT_TRUE(noexcept(opt1.swap(opt2)));
-  EXPECT_TRUE(noexcept(swap(opt1, opt2)));
-}
-
-template <int v>
-struct DeletedOpAddr {
-  int value = v;
-  constexpr DeletedOpAddr() = default;
-  constexpr const DeletedOpAddr<v>* operator&() const = delete;  // NOLINT
-  DeletedOpAddr<v>* operator&() = delete;                        // NOLINT
-};
-
-// The static_assert featuring a constexpr call to operator->() is commented out
-// to document the fact that the current implementation of absl::optional<T>
-// expects such usecases to be malformed and not compile.
-TEST(optionalTest, OperatorAddr) {
-  constexpr int v = -1;
-  {  // constexpr
-    constexpr absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});
-    static_assert(opt.has_value(), "");
-    // static_assert(opt->value == v, "");
-    static_assert((*opt).value == v, "");
-  }
-  {  // non-constexpr
-    const absl::optional<DeletedOpAddr<v>> opt(absl::in_place_t{});
-    EXPECT_TRUE(opt.has_value());
-    EXPECT_TRUE(opt->value == v);
-    EXPECT_TRUE((*opt).value == v);
-  }
-}
-
-TEST(optionalTest, PointerStuff) {
-  absl::optional<std::string> opt(absl::in_place, "foo");
-  EXPECT_EQ("foo", *opt);
-  const auto& opt_const = opt;
-  EXPECT_EQ("foo", *opt_const);
-  EXPECT_EQ(opt->size(), 3u);
-  EXPECT_EQ(opt_const->size(), 3u);
-
-  constexpr absl::optional<ConstexprType> opt1(1);
-  static_assert((*opt1).x == ConstexprType::kCtorInt, "");
-}
-
-TEST(optionalTest, Value) {
-  using O = absl::optional<std::string>;
-  using CO = const absl::optional<std::string>;
-  using OC = absl::optional<const std::string>;
-  O lvalue(absl::in_place, "lvalue");
-  CO clvalue(absl::in_place, "clvalue");
-  OC lvalue_c(absl::in_place, "lvalue_c");
-  EXPECT_EQ("lvalue", lvalue.value());
-  EXPECT_EQ("clvalue", clvalue.value());
-  EXPECT_EQ("lvalue_c", lvalue_c.value());
-  EXPECT_EQ("xvalue", O(absl::in_place, "xvalue").value());
-  EXPECT_EQ("xvalue_c", OC(absl::in_place, "xvalue_c").value());
-  EXPECT_EQ("cxvalue", CO(absl::in_place, "cxvalue").value());
-  EXPECT_EQ("&", TypeQuals(lvalue.value()));
-  EXPECT_EQ("c&", TypeQuals(clvalue.value()));
-  EXPECT_EQ("c&", TypeQuals(lvalue_c.value()));
-  EXPECT_EQ("&&", TypeQuals(O(absl::in_place, "xvalue").value()));
-  EXPECT_EQ("c&&", TypeQuals(CO(absl::in_place, "cxvalue").value()));
-  EXPECT_EQ("c&&", TypeQuals(OC(absl::in_place, "xvalue_c").value()));
-
-#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  // test on volatile type
-  using OV = absl::optional<volatile int>;
-  OV lvalue_v(absl::in_place, 42);
-  EXPECT_EQ(42, lvalue_v.value());
-  EXPECT_EQ(42, OV(42).value());
-  EXPECT_TRUE((std::is_same<volatile int&, decltype(lvalue_v.value())>::value));
-  EXPECT_TRUE((std::is_same<volatile int&&, decltype(OV(42).value())>::value));
-#endif  // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-
-  // test exception throw on value()
-  absl::optional<int> empty;
-#ifdef ABSL_HAVE_EXCEPTIONS
-  EXPECT_THROW((void)empty.value(), absl::bad_optional_access);
-#else
-  EXPECT_DEATH_IF_SUPPORTED((void)empty.value(), "Bad optional access");
-#endif
-
-  // test constexpr value()
-  constexpr absl::optional<int> o1(1);
-  static_assert(1 == o1.value(), "");  // const &
-#ifndef _MSC_VER
-  using COI = const absl::optional<int>;
-  static_assert(2 == COI(2).value(), "");  // const &&
-#endif
-}
-
-TEST(optionalTest, DerefOperator) {
-  using O = absl::optional<std::string>;
-  using CO = const absl::optional<std::string>;
-  using OC = absl::optional<const std::string>;
-  O lvalue(absl::in_place, "lvalue");
-  CO clvalue(absl::in_place, "clvalue");
-  OC lvalue_c(absl::in_place, "lvalue_c");
-  EXPECT_EQ("lvalue", *lvalue);
-  EXPECT_EQ("clvalue", *clvalue);
-  EXPECT_EQ("lvalue_c", *lvalue_c);
-  EXPECT_EQ("xvalue", *O(absl::in_place, "xvalue"));
-  EXPECT_EQ("xvalue_c", *OC(absl::in_place, "xvalue_c"));
-  EXPECT_EQ("cxvalue", *CO(absl::in_place, "cxvalue"));
-  EXPECT_EQ("&", TypeQuals(*lvalue));
-  EXPECT_EQ("c&", TypeQuals(*clvalue));
-  EXPECT_EQ("&&", TypeQuals(*O(absl::in_place, "xvalue")));
-  EXPECT_EQ("c&&", TypeQuals(*CO(absl::in_place, "cxvalue")));
-  EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c")));
-
-#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-  // test on volatile type
-  using OV = absl::optional<volatile int>;
-  OV lvalue_v(absl::in_place, 42);
-  EXPECT_EQ(42, *lvalue_v);
-  EXPECT_EQ(42, *OV(42));
-  EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value));
-  EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value));
-#endif  // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
-
-  constexpr absl::optional<int> opt1(1);
-  static_assert(*opt1 == 1, "");
-#if !defined(_MSC_VER) && !defined(ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG)
-  using COI = const absl::optional<int>;
-  static_assert(*COI(2) == 2, "");
-#endif
-}
-
-TEST(optionalTest, ValueOr) {
-  absl::optional<double> opt_empty, opt_set = 1.2;
-  EXPECT_EQ(42.0, opt_empty.value_or(42));
-  EXPECT_EQ(1.2, opt_set.value_or(42));
-  EXPECT_EQ(42.0, absl::optional<double>().value_or(42));
-  EXPECT_EQ(1.2, absl::optional<double>(1.2).value_or(42));
-
-  constexpr absl::optional<double> copt_empty, copt_set = {1.2};
-  static_assert(42.0 == copt_empty.value_or(42), "");
-  static_assert(1.2 == copt_set.value_or(42), "");
-  using COD = const absl::optional<double>;
-  static_assert(42.0 == COD().value_or(42), "");
-  static_assert(1.2 == COD(1.2).value_or(42), "");
-}
-
-// make_optional cannot be constexpr until C++17
-TEST(optionalTest, make_optional) {
-  auto opt_int = absl::make_optional(42);
-  EXPECT_TRUE((std::is_same<decltype(opt_int), absl::optional<int>>::value));
-  EXPECT_EQ(42, opt_int);
-
-  StructorListener listener;
-  Listenable::listener = &listener;
-
-  absl::optional<Listenable> opt0 = absl::make_optional<Listenable>();
-  EXPECT_EQ(1, listener.construct0);
-  absl::optional<Listenable> opt1 = absl::make_optional<Listenable>(1);
-  EXPECT_EQ(1, listener.construct1);
-  absl::optional<Listenable> opt2 = absl::make_optional<Listenable>(1, 2);
-  EXPECT_EQ(1, listener.construct2);
-  absl::optional<Listenable> opt3 = absl::make_optional<Listenable>({1});
-  absl::optional<Listenable> opt4 = absl::make_optional<Listenable>({1, 2});
-  EXPECT_EQ(2, listener.listinit);
-
-  // Constexpr tests on trivially copyable types
-  // optional<T> has trivial copy/move ctors when T is trivially copyable.
-  // For nontrivial types with constexpr constructors, we need copy elision in
-  // C++17 for make_optional to be constexpr.
-  {
-    constexpr absl::optional<int> c_opt = absl::make_optional(42);
-    static_assert(c_opt.value() == 42, "");
-  }
-  {
-    struct TrivialCopyable {
-      constexpr TrivialCopyable() : x(0) {}
-      constexpr explicit TrivialCopyable(int i) : x(i) {}
-      int x;
-    };
-
-    constexpr TrivialCopyable v;
-    constexpr absl::optional<TrivialCopyable> c_opt0 = absl::make_optional(v);
-    static_assert((*c_opt0).x == 0, "");
-    constexpr absl::optional<TrivialCopyable> c_opt1 =
-        absl::make_optional<TrivialCopyable>();
-    static_assert((*c_opt1).x == 0, "");
-    constexpr absl::optional<TrivialCopyable> c_opt2 =
-        absl::make_optional<TrivialCopyable>(42);
-    static_assert((*c_opt2).x == 42, "");
-  }
-}
-
-template <typename T, typename U>
-void optionalTest_Comparisons_EXPECT_LESS(T x, U y) {
-  EXPECT_FALSE(x == y);
-  EXPECT_TRUE(x != y);
-  EXPECT_TRUE(x < y);
-  EXPECT_FALSE(x > y);
-  EXPECT_TRUE(x <= y);
-  EXPECT_FALSE(x >= y);
-}
-
-template <typename T, typename U>
-void optionalTest_Comparisons_EXPECT_SAME(T x, U y) {
-  EXPECT_TRUE(x == y);
-  EXPECT_FALSE(x != y);
-  EXPECT_FALSE(x < y);
-  EXPECT_FALSE(x > y);
-  EXPECT_TRUE(x <= y);
-  EXPECT_TRUE(x >= y);
-}
-
-template <typename T, typename U>
-void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) {
-  EXPECT_FALSE(x == y);
-  EXPECT_TRUE(x != y);
-  EXPECT_FALSE(x < y);
-  EXPECT_TRUE(x > y);
-  EXPECT_FALSE(x <= y);
-  EXPECT_TRUE(x >= y);
-}
-
-template <typename T, typename U, typename V>
-void TestComparisons() {
-  absl::optional<T> ae, a2{2}, a4{4};
-  absl::optional<U> be, b2{2}, b4{4};
-  V v3 = 3;
-
-  // LHS: absl::nullopt, ae, a2, v3, a4
-  // RHS: absl::nullopt, be, b2, v3, b4
-
-  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,absl::nullopt);
-  optionalTest_Comparisons_EXPECT_SAME(absl::nullopt, be);
-  optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b2);
-  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(absl::nullopt,v3);
-  optionalTest_Comparisons_EXPECT_LESS(absl::nullopt, b4);
-
-  optionalTest_Comparisons_EXPECT_SAME(ae, absl::nullopt);
-  optionalTest_Comparisons_EXPECT_SAME(ae, be);
-  optionalTest_Comparisons_EXPECT_LESS(ae, b2);
-  optionalTest_Comparisons_EXPECT_LESS(ae, v3);
-  optionalTest_Comparisons_EXPECT_LESS(ae, b4);
-
-  optionalTest_Comparisons_EXPECT_GREATER(a2, absl::nullopt);
-  optionalTest_Comparisons_EXPECT_GREATER(a2, be);
-  optionalTest_Comparisons_EXPECT_SAME(a2, b2);
-  optionalTest_Comparisons_EXPECT_LESS(a2, v3);
-  optionalTest_Comparisons_EXPECT_LESS(a2, b4);
-
-  // optionalTest_Comparisons_EXPECT_NOT_TO_WORK(v3,absl::nullopt);
-  optionalTest_Comparisons_EXPECT_GREATER(v3, be);
-  optionalTest_Comparisons_EXPECT_GREATER(v3, b2);
-  optionalTest_Comparisons_EXPECT_SAME(v3, v3);
-  optionalTest_Comparisons_EXPECT_LESS(v3, b4);
-
-  optionalTest_Comparisons_EXPECT_GREATER(a4, absl::nullopt);
-  optionalTest_Comparisons_EXPECT_GREATER(a4, be);
-  optionalTest_Comparisons_EXPECT_GREATER(a4, b2);
-  optionalTest_Comparisons_EXPECT_GREATER(a4, v3);
-  optionalTest_Comparisons_EXPECT_SAME(a4, b4);
-}
-
-struct Int1 {
-  Int1() = default;
-  Int1(int i) : i(i) {}  // NOLINT(runtime/explicit)
-  int i;
-};
-
-struct Int2 {
-  Int2() = default;
-  Int2(int i) : i(i) {}  // NOLINT(runtime/explicit)
-  int i;
-};
-
-// comparison between Int1 and Int2
-constexpr bool operator==(const Int1& lhs, const Int2& rhs) {
-  return lhs.i == rhs.i;
-}
-constexpr bool operator!=(const Int1& lhs, const Int2& rhs) {
-  return !(lhs == rhs);
-}
-constexpr bool operator<(const Int1& lhs, const Int2& rhs) {
-  return lhs.i < rhs.i;
-}
-constexpr bool operator<=(const Int1& lhs, const Int2& rhs) {
-  return lhs < rhs || lhs == rhs;
-}
-constexpr bool operator>(const Int1& lhs, const Int2& rhs) {
-  return !(lhs <= rhs);
-}
-constexpr bool operator>=(const Int1& lhs, const Int2& rhs) {
-  return !(lhs < rhs);
-}
-
-TEST(optionalTest, Comparisons) {
-  TestComparisons<int, int, int>();
-  TestComparisons<const int, int, int>();
-  TestComparisons<Int1, int, int>();
-  TestComparisons<int, Int2, int>();
-  TestComparisons<Int1, Int2, int>();
-
-  // compare absl::optional<std::string> with const char*
-  absl::optional<std::string> opt_str = "abc";
-  const char* cstr = "abc";
-  EXPECT_TRUE(opt_str == cstr);
-  // compare absl::optional<std::string> with absl::optional<const char*>
-  absl::optional<const char*> opt_cstr = cstr;
-  EXPECT_TRUE(opt_str == opt_cstr);
-  // compare absl::optional<std::string> with absl::optional<absl::string_view>
-  absl::optional<absl::string_view> e1;
-  absl::optional<std::string> e2;
-  EXPECT_TRUE(e1 == e2);
-}
-
-TEST(optionalTest, SwapRegression) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-
-  {
-    absl::optional<Listenable> a;
-    absl::optional<Listenable> b(absl::in_place);
-    a.swap(b);
-  }
-
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(1, listener.move);
-  EXPECT_EQ(2, listener.destruct);
-
-  {
-    absl::optional<Listenable> a(absl::in_place);
-    absl::optional<Listenable> b;
-    a.swap(b);
-  }
-
-  EXPECT_EQ(2, listener.construct0);
-  EXPECT_EQ(2, listener.move);
-  EXPECT_EQ(4, listener.destruct);
-}
-
-TEST(optionalTest, BigStringLeakCheck) {
-  constexpr size_t n = 1 << 16;
-
-  using OS = absl::optional<std::string>;
-
-  OS a;
-  OS b = absl::nullopt;
-  OS c = std::string(n, 'c');
-  std::string sd(n, 'd');
-  OS d = sd;
-  OS e(absl::in_place, n, 'e');
-  OS f;
-  f.emplace(n, 'f');
-
-  OS ca(a);
-  OS cb(b);
-  OS cc(c);
-  OS cd(d);
-  OS ce(e);
-
-  OS oa;
-  OS ob = absl::nullopt;
-  OS oc = std::string(n, 'c');
-  std::string sod(n, 'd');
-  OS od = sod;
-  OS oe(absl::in_place, n, 'e');
-  OS of;
-  of.emplace(n, 'f');
-
-  OS ma(std::move(oa));
-  OS mb(std::move(ob));
-  OS mc(std::move(oc));
-  OS md(std::move(od));
-  OS me(std::move(oe));
-  OS mf(std::move(of));
-
-  OS aa1;
-  OS ab1 = absl::nullopt;
-  OS ac1 = std::string(n, 'c');
-  std::string sad1(n, 'd');
-  OS ad1 = sad1;
-  OS ae1(absl::in_place, n, 'e');
-  OS af1;
-  af1.emplace(n, 'f');
-
-  OS aa2;
-  OS ab2 = absl::nullopt;
-  OS ac2 = std::string(n, 'c');
-  std::string sad2(n, 'd');
-  OS ad2 = sad2;
-  OS ae2(absl::in_place, n, 'e');
-  OS af2;
-  af2.emplace(n, 'f');
-
-  aa1 = af2;
-  ab1 = ae2;
-  ac1 = ad2;
-  ad1 = ac2;
-  ae1 = ab2;
-  af1 = aa2;
-
-  OS aa3;
-  OS ab3 = absl::nullopt;
-  OS ac3 = std::string(n, 'c');
-  std::string sad3(n, 'd');
-  OS ad3 = sad3;
-  OS ae3(absl::in_place, n, 'e');
-  OS af3;
-  af3.emplace(n, 'f');
-
-  aa3 = absl::nullopt;
-  ab3 = absl::nullopt;
-  ac3 = absl::nullopt;
-  ad3 = absl::nullopt;
-  ae3 = absl::nullopt;
-  af3 = absl::nullopt;
-
-  OS aa4;
-  OS ab4 = absl::nullopt;
-  OS ac4 = std::string(n, 'c');
-  std::string sad4(n, 'd');
-  OS ad4 = sad4;
-  OS ae4(absl::in_place, n, 'e');
-  OS af4;
-  af4.emplace(n, 'f');
-
-  aa4 = OS(absl::in_place, n, 'a');
-  ab4 = OS(absl::in_place, n, 'b');
-  ac4 = OS(absl::in_place, n, 'c');
-  ad4 = OS(absl::in_place, n, 'd');
-  ae4 = OS(absl::in_place, n, 'e');
-  af4 = OS(absl::in_place, n, 'f');
-
-  OS aa5;
-  OS ab5 = absl::nullopt;
-  OS ac5 = std::string(n, 'c');
-  std::string sad5(n, 'd');
-  OS ad5 = sad5;
-  OS ae5(absl::in_place, n, 'e');
-  OS af5;
-  af5.emplace(n, 'f');
-
-  std::string saa5(n, 'a');
-  std::string sab5(n, 'a');
-  std::string sac5(n, 'a');
-  std::string sad52(n, 'a');
-  std::string sae5(n, 'a');
-  std::string saf5(n, 'a');
-
-  aa5 = saa5;
-  ab5 = sab5;
-  ac5 = sac5;
-  ad5 = sad52;
-  ae5 = sae5;
-  af5 = saf5;
-
-  OS aa6;
-  OS ab6 = absl::nullopt;
-  OS ac6 = std::string(n, 'c');
-  std::string sad6(n, 'd');
-  OS ad6 = sad6;
-  OS ae6(absl::in_place, n, 'e');
-  OS af6;
-  af6.emplace(n, 'f');
-
-  aa6 = std::string(n, 'a');
-  ab6 = std::string(n, 'b');
-  ac6 = std::string(n, 'c');
-  ad6 = std::string(n, 'd');
-  ae6 = std::string(n, 'e');
-  af6 = std::string(n, 'f');
-
-  OS aa7;
-  OS ab7 = absl::nullopt;
-  OS ac7 = std::string(n, 'c');
-  std::string sad7(n, 'd');
-  OS ad7 = sad7;
-  OS ae7(absl::in_place, n, 'e');
-  OS af7;
-  af7.emplace(n, 'f');
-
-  aa7.emplace(n, 'A');
-  ab7.emplace(n, 'B');
-  ac7.emplace(n, 'C');
-  ad7.emplace(n, 'D');
-  ae7.emplace(n, 'E');
-  af7.emplace(n, 'F');
-}
-
-TEST(optionalTest, MoveAssignRegression) {
-  StructorListener listener;
-  Listenable::listener = &listener;
-
-  {
-    absl::optional<Listenable> a;
-    Listenable b;
-    a = std::move(b);
-  }
-
-  EXPECT_EQ(1, listener.construct0);
-  EXPECT_EQ(1, listener.move);
-  EXPECT_EQ(2, listener.destruct);
-}
-
-TEST(optionalTest, ValueType) {
-  EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value));
-  EXPECT_TRUE((std::is_same<absl::optional<std::string>::value_type,
-                            std::string>::value));
-  EXPECT_FALSE(
-      (std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value));
-}
-
-template <typename T>
-struct is_hash_enabled_for {
-  template <typename U, typename = decltype(std::hash<U>()(std::declval<U>()))>
-  static std::true_type test(int);
-
-  template <typename U>
-  static std::false_type test(...);
-
-  static constexpr bool value = decltype(test<T>(0))::value;
-};
-
-TEST(optionalTest, Hash) {
-  std::hash<absl::optional<int>> hash;
-  std::set<size_t> hashcodes;
-  hashcodes.insert(hash(absl::nullopt));
-  for (int i = 0; i < 100; ++i) {
-    hashcodes.insert(hash(i));
-  }
-  EXPECT_GT(hashcodes.size(), 90u);
-
-  static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");
-  static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");
-  static_assert(
-      absl::type_traits_internal::IsHashable<absl::optional<int>>::value, "");
-  static_assert(
-      absl::type_traits_internal::IsHashable<absl::optional<Hashable>>::value,
-      "");
-  absl::type_traits_internal::AssertHashEnabled<absl::optional<int>>();
-  absl::type_traits_internal::AssertHashEnabled<absl::optional<Hashable>>();
-
-#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
-  static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, "");
-  static_assert(!absl::type_traits_internal::IsHashable<
-                    absl::optional<NonHashable>>::value,
-                "");
-#endif
-
-  // libstdc++ std::optional is missing remove_const_t, i.e. it's using
-  // std::hash<T> rather than std::hash<std::remove_const_t<T>>.
-  // Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262
-#ifndef __GLIBCXX__
-  static_assert(is_hash_enabled_for<absl::optional<const int>>::value, "");
-  static_assert(is_hash_enabled_for<absl::optional<const Hashable>>::value, "");
-  std::hash<absl::optional<const int>> c_hash;
-  for (int i = 0; i < 100; ++i) {
-    EXPECT_EQ(hash(i), c_hash(i));
-  }
-#endif
-}
-
-struct MoveMeNoThrow {
-  MoveMeNoThrow() : x(0) {}
-  [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
-    LOG(FATAL) << "Should not be called.";
-  }
-  MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
-  int x;
-};
-
-struct MoveMeThrow {
-  MoveMeThrow() : x(0) {}
-  MoveMeThrow(const MoveMeThrow& other) : x(other.x) {}
-  MoveMeThrow(MoveMeThrow&& other) : x(other.x) {}
-  int x;
-};
-
-TEST(optionalTest, NoExcept) {
-  static_assert(
-      std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value,
-      "");
-  static_assert(absl::default_allocator_is_nothrow::value ==
-                    std::is_nothrow_move_constructible<
-                        absl::optional<MoveMeThrow>>::value,
-                "");
-  std::vector<absl::optional<MoveMeNoThrow>> v;
-  for (int i = 0; i < 10; ++i) v.emplace_back();
-}
-
-struct AnyLike {
-  AnyLike(AnyLike&&) = default;
-  AnyLike(const AnyLike&) = default;
-
-  template <typename ValueType,
-            typename T = typename std::decay<ValueType>::type,
-            typename std::enable_if<
-                !absl::disjunction<
-                    std::is_same<AnyLike, T>,
-                    absl::negation<std::is_copy_constructible<T>>>::value,
-                int>::type = 0>
-  AnyLike(ValueType&&) {}  // NOLINT(runtime/explicit)
-
-  AnyLike& operator=(AnyLike&&) = default;
-  AnyLike& operator=(const AnyLike&) = default;
-
-  template <typename ValueType,
-            typename T = typename std::decay<ValueType>::type>
-  typename std::enable_if<
-      absl::conjunction<absl::negation<std::is_same<AnyLike, T>>,
-                        std::is_copy_constructible<T>>::value,
-      AnyLike&>::type
-  operator=(ValueType&& /* rhs */) {
-    return *this;
-  }
-};
-
-TEST(optionalTest, ConstructionConstraints) {
-  EXPECT_TRUE((std::is_constructible<AnyLike, absl::optional<AnyLike>>::value));
-
-  EXPECT_TRUE(
-      (std::is_constructible<AnyLike, const absl::optional<AnyLike>&>::value));
-
-  EXPECT_TRUE((std::is_constructible<absl::optional<AnyLike>, AnyLike>::value));
-  EXPECT_TRUE(
-      (std::is_constructible<absl::optional<AnyLike>, const AnyLike&>::value));
-
-  EXPECT_TRUE((std::is_convertible<absl::optional<AnyLike>, AnyLike>::value));
-
-  EXPECT_TRUE(
-      (std::is_convertible<const absl::optional<AnyLike>&, AnyLike>::value));
-
-  EXPECT_TRUE((std::is_convertible<AnyLike, absl::optional<AnyLike>>::value));
-  EXPECT_TRUE(
-      (std::is_convertible<const AnyLike&, absl::optional<AnyLike>>::value));
-
-  EXPECT_TRUE(std::is_move_constructible<absl::optional<AnyLike>>::value);
-  EXPECT_TRUE(std::is_copy_constructible<absl::optional<AnyLike>>::value);
-}
-
-TEST(optionalTest, AssignmentConstraints) {
-  EXPECT_TRUE((std::is_assignable<AnyLike&, absl::optional<AnyLike>>::value));
-  EXPECT_TRUE(
-      (std::is_assignable<AnyLike&, const absl::optional<AnyLike>&>::value));
-  EXPECT_TRUE((std::is_assignable<absl::optional<AnyLike>&, AnyLike>::value));
-  EXPECT_TRUE(
-      (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value));
-  EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value);
-  EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
-}
-
-#if !defined(__EMSCRIPTEN__)
-struct NestedClassBug {
-  struct Inner {
-    bool dummy = false;
-  };
-  absl::optional<Inner> value;
-};
-
-TEST(optionalTest, InPlaceTSFINAEBug) {
-  NestedClassBug b;
-  ((void)b);
-  using Inner = NestedClassBug::Inner;
-
-  EXPECT_TRUE((std::is_default_constructible<Inner>::value));
-  EXPECT_TRUE((std::is_constructible<Inner>::value));
-  EXPECT_TRUE(
-      (std::is_constructible<absl::optional<Inner>, absl::in_place_t>::value));
-
-  absl::optional<Inner> o(absl::in_place);
-  EXPECT_TRUE(o.has_value());
-  o.emplace();
-  EXPECT_TRUE(o.has_value());
-}
-#endif  // !defined(__EMSCRIPTEN__)
-
-}  // namespace
-
-#endif  // #if !defined(ABSL_USES_STD_OPTIONAL)
diff --git a/absl/utility/utility.h b/absl/utility/utility.h
index 47074bd..c357e79 100644
--- a/absl/utility/utility.h
+++ b/absl/utility/utility.h
@@ -53,6 +53,8 @@
 using std::forward;
 using std::index_sequence;
 using std::index_sequence_for;
+using std::in_place;
+using std::in_place_t;
 using std::in_place_type;
 using std::in_place_type_t;
 using std::integer_sequence;
@@ -80,24 +82,6 @@
 
 // Tag types
 
-#ifdef ABSL_USES_STD_OPTIONAL
-
-using std::in_place_t;
-using std::in_place;
-
-#else  // ABSL_USES_STD_OPTIONAL
-
-// in_place_t
-//
-// Tag type used to specify in-place construction, such as with
-// `absl::optional`, designed to be a drop-in replacement for C++17's
-// `std::in_place_t`.
-struct in_place_t {};
-
-inline constexpr in_place_t in_place = {};
-
-#endif  // ABSL_USES_STD_OPTIONAL
-
 #ifdef ABSL_USES_STD_VARIANT
 using std::in_place_index;
 using std::in_place_index_t;