diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake
index 6d26169..58f98c8 100644
--- a/CMake/AbseilHelpers.cmake
+++ b/CMake/AbseilHelpers.cmake
@@ -16,7 +16,7 @@
 
 include(CMakeParseArguments)
 include(AbseilConfigureCopts)
-include(GNUInstallDirs)
+include(AbseilInstallDirs)
 
 # The IDE folder for Abseil that will be used if Abseil is included in a CMake
 # project that sets
@@ -59,7 +59,7 @@
 #   SRCS
 #     "b.cc"
 #   DEPS
-#     absl_internal_awesome # not "awesome"!
+#     absl::awesome # not "awesome" !
 #   PUBLIC
 # )
 #
@@ -68,7 +68,7 @@
 #     main_lib
 #   ...
 #   DEPS
-#     absl::fantastic_lib # since fantastic_lib is public
+#     absl::fantastic_lib
 # )
 #
 # TODO: Implement "ALWAYSLINK"
@@ -80,8 +80,12 @@
     ${ARGN}
   )
 
-  if (NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
-    set(_NAME "${ABSL_CC_LIB_NAME}")
+  if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
+    if(ABSL_ENABLE_INSTALL)
+      set(_NAME "${ABSL_CC_LIB_NAME}")
+    else()
+      set(_NAME "absl_${ABSL_CC_LIB_NAME}")
+    endif()
 
     # Check if this is a header-only library
     # Note that as of February 2019, many popular OS's (for example, Ubuntu
@@ -93,7 +97,7 @@
         list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
       endif()
     endforeach()
-    if ("${ABSL_CC_SRCS}" STREQUAL "")
+    if("${ABSL_CC_SRCS}" STREQUAL "")
       set(ABSL_CC_LIB_IS_INTERFACE 1)
     else()
       set(ABSL_CC_LIB_IS_INTERFACE 0)
@@ -105,13 +109,15 @@
       target_include_directories(${_NAME}
         PUBLIC
           $<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>
-          $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+          $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
       )
       target_compile_options(${_NAME}
         PRIVATE ${ABSL_CC_LIB_COPTS})
       target_link_libraries(${_NAME}
         PUBLIC ${ABSL_CC_LIB_DEPS}
-        PRIVATE ${ABSL_CC_LIB_LINKOPTS}
+        PRIVATE
+          ${ABSL_CC_LIB_LINKOPTS}
+          ${ABSL_DEFAULT_LINKOPTS}
       )
       target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES})
 
@@ -140,21 +146,24 @@
       target_include_directories(${_NAME}
         INTERFACE
           $<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>
-          $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+          $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
         )
       target_link_libraries(${_NAME}
-        INTERFACE ${ABSL_CC_LIB_DEPS} ${ABSL_CC_LIB_LINKOPTS}
+        INTERFACE
+          ${ABSL_CC_LIB_DEPS}
+          ${ABSL_CC_LIB_LINKOPTS}
+          ${ABSL_DEFAULT_LINKOPTS}
       )
       target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES})
     endif()
 
     # TODO currently we don't install googletest alongside abseil sources, so
     # installed abseil can't be tested.
-    if (NOT ABSL_CC_LIB_TESTONLY)
+    if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL)
       install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
-            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
+            LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
+            ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
       )
     endif()
 
diff --git a/CMake/AbseilInstallDirs.cmake b/CMake/AbseilInstallDirs.cmake
new file mode 100644
index 0000000..b67272f
--- /dev/null
+++ b/CMake/AbseilInstallDirs.cmake
@@ -0,0 +1,20 @@
+include(GNUInstallDirs)
+
+# absl_VERSION is only set if we are an LTS release being installed, in which
+# case it may be into a system directory and so we need to make subdirectories
+# for each installed version of Abseil.  This mechanism is implemented in
+# Abseil's internal Copybara (https://github.com/google/copybara) workflows and
+# isn't visible in the CMake buildsystem itself.
+
+if(absl_VERSION)
+  set(ABSL_SUBDIR "${PROJECT_NAME}_${PROJECT_VERSION}")
+  set(ABSL_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}/${ABSL_SUBDIR}")
+  set(ABSL_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${ABSL_SUBDIR}")
+  set(ABSL_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/{ABSL_SUBDIR}")
+  set(ABSL_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/${ABSL_SUBDIR}")
+else()
+  set(ABSL_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}")
+  set(ABSL_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+  set(ABSL_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
+  set(ABSL_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
+endif()
\ No newline at end of file
diff --git a/CMake/CMakeLists.txt.in b/CMake/Googletest/CMakeLists.txt.in
similarity index 100%
rename from CMake/CMakeLists.txt.in
rename to CMake/Googletest/CMakeLists.txt.in
diff --git a/CMake/DownloadGTest.cmake b/CMake/Googletest/DownloadGTest.cmake
similarity index 100%
rename from CMake/DownloadGTest.cmake
rename to CMake/Googletest/DownloadGTest.cmake
diff --git a/CMake/abslConfig.cmake.in b/CMake/abslConfig.cmake.in
index bf8c4f6..60847fa 100644
--- a/CMake/abslConfig.cmake.in
+++ b/CMake/abslConfig.cmake.in
@@ -1,5 +1,6 @@
-## absl CMake configuration file.  Note that there is no corresponding
-# abslConfigVersion.cmake since non-LTS Abseil isn't versioned.
+# absl CMake configuration file.
+
+include(FindThreads)
 
 @PACKAGE_INIT@
 
diff --git a/CMake/install_test_project/test.sh b/CMake/install_test_project/test.sh
index 3e77e79..99989b0 100755
--- a/CMake/install_test_project/test.sh
+++ b/CMake/install_test_project/test.sh
@@ -24,15 +24,6 @@
 
 # Fail on any error. Treat unset variables an error. Print commands as executed.
 set -euox pipefail
-absl_dir=/abseil-cpp
-absl_build_dir=/buildfs/absl-build
-project_dir="${absl_dir}"/CMake/install_test_project
-project_build_dir=/buildfs/project-build
-install_dir="${project_build_dir}"/install
-
-mkdir -p "${absl_build_dir}"
-mkdir -p "${project_build_dir}"
-mkdir -p "${install_dir}"
 
 install_absl() {
   pushd "${absl_build_dir}"
@@ -51,10 +42,41 @@
   mkdir -p "${absl_build_dir}"
 }
 
+lts_install=""
+
+while getopts ":l" lts; do
+  case "${lts}" in
+    l )
+      lts_install="true"
+      ;;
+  esac
+done
+
+absl_dir=/abseil-cpp
+absl_build_dir=/buildfs/absl-build
+project_dir="${absl_dir}"/CMake/install_test_project
+project_build_dir=/buildfs/project-build
+
+mkdir -p "${absl_build_dir}"
+mkdir -p "${project_build_dir}"
+
+if [[ "${lts_install}" ]]; then
+  install_dir="/usr/local"
+else
+  install_dir="${project_build_dir}"/install
+fi
+mkdir -p "${install_dir}"
+
 # Test build, install, and link against installed abseil
-install_absl "${install_dir}"
 pushd "${project_build_dir}"
-cmake "${project_dir}" -DCMAKE_PREFIX_PATH="${install_dir}"
+if [[ "${lts_install}" ]]; then
+  install_absl
+  cmake "${project_dir}"
+else
+  install_absl "${install_dir}"
+  cmake "${project_dir}" -DCMAKE_PREFIX_PATH="${install_dir}"
+fi
+
 cmake --build . --target simple
 
 output="$(${project_build_dir}/simple "printme" 2>&1)"
@@ -64,14 +86,16 @@
   exit 1
 fi
 
+popd
+
 # Test that we haven't accidentally made absl::abslblah
 pushd "${install_dir}"
 
 # Starting in CMake 3.12 the default install dir is lib$bit_width
-if [[ -d lib ]]; then
-  libdir="lib"
-elif [[ -d lib64 ]]; then
+if [[ -d lib64 ]]; then
   libdir="lib64"
+elif [[ -d lib ]]; then
+  libdir="lib"
 else
   echo "ls *, */*, */*/*:"
   ls *
@@ -80,7 +104,15 @@
   echo "unknown lib dir"
 fi
 
-if ! grep absl::strings "${libdir}"/cmake/absl/abslTargets.cmake;  then
+if [[ "${lts_install}" ]]; then
+  # LTS versions append the date of the release to the subdir.
+  # 9999/99/99 is the dummy date used in the local_lts workflow.
+  absl_subdir="absl_99999999"
+else
+  absl_subdir="absl"
+fi
+
+if ! grep absl::strings "${libdir}/cmake/${absl_subdir}/abslTargets.cmake"; then
   cat "${libdir}"/cmake/absl/abslTargets.cmake
   echo "CMake targets named incorrectly"
   exit 1
@@ -89,22 +121,24 @@
 uninstall_absl
 popd
 
-# Test that we warn if installed without a prefix or a system prefix
-output="$(install_absl 2>&1)"
-if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
-  echo "Install without prefix didn't warn as expected. Output:"
-  echo "${output}"
-  exit 1
-fi
-uninstall_absl
+if [[ ! "${lts_install}" ]]; then
+  # Test that we warn if installed without a prefix or a system prefix
+  output="$(install_absl 2>&1)"
+  if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
+    echo "Install without prefix didn't warn as expected. Output:"
+    echo "${output}"
+    exit 1
+  fi
+  uninstall_absl
 
-output="$(install_absl /usr 2>&1)"
-if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
-  echo "Install with /usr didn't warn as expected. Output:"
-  echo "${output}"
-  exit 1
+  output="$(install_absl /usr 2>&1)"
+  if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
+    echo "Install with /usr didn't warn as expected. Output:"
+    echo "${output}"
+    exit 1
+  fi
+  uninstall_absl
 fi
-uninstall_absl
 
 echo "Install test complete!"
 exit 0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f4fbdc..e7587f7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,13 +22,14 @@
 cmake_minimum_required(VERSION 3.5)
 
 # Compiler id for Apple Clang is now AppleClang.
-if (POLICY CMP0025)
-  cmake_policy(SET CMP0025 NEW)
-endif()
+cmake_policy(SET CMP0025 NEW)
 
 # if command can use IN_LIST
 cmake_policy(SET CMP0057 NEW)
 
+# Project version variables are the empty std::string if version is unspecified
+cmake_policy(SET CMP0048 NEW)
+
 project(absl)
 
 # when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
@@ -44,7 +45,7 @@
   ${CMAKE_CURRENT_LIST_DIR}/absl/copts
 )
 
-include(GNUInstallDirs)
+include(AbseilInstallDirs)
 include(CMakePackageConfigHelpers)
 include(AbseilHelpers)
 
@@ -85,21 +86,11 @@
   enable_testing()
 endif()
 
-# We don't support system-wide installation
-list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
-if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
-  message(WARNING "\
-The default and system-level install directories are unsupported except in LTS \
-releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
-source or build tree directly.\
-  ")
-endif()
-
 ## check targets
 if(BUILD_TESTING)
 
   if(${ABSL_USE_GOOGLETEST_HEAD})
-    include(CMake/DownloadGTest.cmake)
+    include(CMake/Googletest/DownloadGTest.cmake)
     set(absl_gtest_src_dir ${CMAKE_BINARY_DIR}/googletest-src)
     set(absl_gtest_build_dir ${CMAKE_BINARY_DIR}/googletest-build)
   endif()
@@ -118,25 +109,52 @@
 
 add_subdirectory(absl)
 
-# install as a subdirectory only
-install(EXPORT ${PROJECT_NAME}Targets
-  NAMESPACE absl::
-  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
-)
+if(ABSL_ENABLE_INSTALL)
+  # absl:lts-remove-begin(system installation is supported for LTS releases)
+  # We don't support system-wide installation
+  list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
+  if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
+    message(WARNING "\
+  The default and system-level install directories are unsupported except in LTS \
+  releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
+  source or build tree directly.\
+    ")
+  endif()
+  # absl:lts-remove-end
 
-configure_package_config_file(
-  CMake/abslConfig.cmake.in
-  "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
-  INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
-)
+  # install as a subdirectory only
+  install(EXPORT ${PROJECT_NAME}Targets
+    NAMESPACE absl::
+    DESTINATION "${ABSL_INSTALL_CONFIGDIR}"
+  )
 
-install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
-  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
-)
+  configure_package_config_file(
+    CMake/abslConfig.cmake.in
+    "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+    INSTALL_DESTINATION "${ABSL_INSTALL_CONFIGDIR}"
+  )
+  install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+    DESTINATION "${ABSL_INSTALL_CONFIGDIR}"
+  )
 
-install(DIRECTORY absl
-  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
-  FILES_MATCHING
-    PATTERN "*.inc"
-    PATTERN "*.h"
-)
+  # Abseil only has a version in LTS releases.  This mechanism is accomplished
+  # Abseil's internal Copybara (https://github.com/google/copybara) workflows and
+  # isn't visible in the CMake buildsystem itself.
+  if(absl_VERSION)
+    write_basic_package_version_file(
+      "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+      COMPATIBILITY ExactVersion
+    )
+
+    install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+      DESTINATION ${ABSL_INSTALL_CONFIGDIR}
+    )
+  endif()  # absl_VERSION
+
+  install(DIRECTORY absl
+    DESTINATION ${ABSL_INSTALL_INCLUDEDIR}
+    FILES_MATCHING
+      PATTERN "*.inc"
+      PATTERN "*.h"
+  )
+endif()  # ABSL_ENABLE_INSTALL
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index 8e3c177..853330d 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -25,13 +25,18 @@
     visibility = [":__subpackages__"],
 )
 
-# following configs are based on mapping defined in: https://git.io/v5Ijz
+config_setting(
+    name = "osx",
+    constraint_values = [
+        "@bazel_tools//platforms:osx",
+    ],
+)
+
 config_setting(
     name = "ios",
-    values = {
-        "cpu": "darwin",
-    },
-    visibility = [":__subpackages__"],
+    constraint_values = [
+        "@bazel_tools//platforms:ios",
+    ],
 )
 
 config_setting(
diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel
index 8d266db..c506f3b 100644
--- a/absl/algorithm/BUILD.bazel
+++ b/absl/algorithm/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -28,6 +29,7 @@
     name = "algorithm",
     hdrs = ["algorithm.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
 )
 
 cc_test(
@@ -35,6 +37,7 @@
     size = "small",
     srcs = ["algorithm_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":algorithm",
         "@com_google_googletest//:gtest_main",
@@ -45,6 +48,7 @@
     name = "algorithm_benchmark",
     srcs = ["equal_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["benchmark"],
     deps = [
         ":algorithm",
@@ -59,6 +63,7 @@
         "container.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":algorithm",
         "//absl/base:core_headers",
@@ -70,6 +75,7 @@
     name = "container_test",
     srcs = ["container_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":container",
         "//absl/base",
diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt
index c51eb10..9fbe36f 100644
--- a/absl/algorithm/CMakeLists.txt
+++ b/absl/algorithm/CMakeLists.txt
@@ -29,6 +29,8 @@
     algorithm_test
   SRCS
     "algorithm_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::algorithm
     gmock_main
@@ -53,6 +55,8 @@
     container_test
   SRCS
     "container_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::algorithm_container
     absl::base
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 804f62a..9fb1d8c 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
     "ABSL_EXCEPTIONS_FLAG",
     "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
@@ -40,6 +41,7 @@
         "internal/spinlock_wait.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl/base:__pkg__",
     ],
@@ -53,6 +55,7 @@
         "policy_checks.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
 )
 
 cc_library(
@@ -61,6 +64,7 @@
     hdrs = ["dynamic_annotations.h"],
     copts = ABSL_DEFAULT_COPTS,
     defines = ["__CLANG_SUPPORT_DYN_ANNOTATION__"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
 )
 
 cc_library(
@@ -74,6 +78,7 @@
         "thread_annotations.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":config",
     ],
@@ -92,7 +97,7 @@
     linkopts = select({
         "//absl:windows": [],
         "//conditions:default": ["-pthread"],
-    }),
+    }) + ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -115,6 +120,7 @@
         "internal/scheduling_mode.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -129,6 +135,7 @@
         "internal/sysinfo.cc",
         "internal/thread_identity.cc",
         "internal/unscaledcycleclock.cc",
+        "log_severity.cc",
     ],
     hdrs = [
         "call_once.h",
@@ -149,13 +156,14 @@
     linkopts = select({
         "//absl:windows": [],
         "//conditions:default": ["-pthread"],
-    }),
+    }) + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base_internal",
         ":config",
         ":core_headers",
         ":dynamic_annotations",
         ":spinlock_wait",
+        "//absl/meta:type_traits",
     ],
 )
 
@@ -164,6 +172,7 @@
     size = "small",
     srcs = ["internal/atomic_hook_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         ":core_headers",
@@ -178,6 +187,7 @@
         "bit_cast_test.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         ":core_headers",
@@ -190,7 +200,7 @@
     srcs = ["internal/throw_delegate.cc"],
     hdrs = ["internal/throw_delegate.h"],
     copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -204,7 +214,7 @@
     name = "throw_delegate_test",
     srcs = ["throw_delegate_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":throw_delegate",
         "@com_google_googletest//:gtest_main",
@@ -216,6 +226,7 @@
     testonly = 1,
     hdrs = ["internal/exception_testing.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -228,6 +239,7 @@
 cc_library(
     name = "pretty_function",
     hdrs = ["internal/pretty_function.h"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//absl:__subpackages__"],
 )
 
@@ -237,7 +249,7 @@
     srcs = ["internal/exception_safety_testing.cc"],
     hdrs = ["internal/exception_safety_testing.h"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":config",
         ":pretty_function",
@@ -253,7 +265,7 @@
     name = "exception_safety_testing_test",
     srcs = ["exception_safety_testing_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":exception_safety_testing",
         "//absl/memory",
@@ -271,6 +283,7 @@
         "internal/inline_variable_testing.h",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base_internal",
         "@com_google_googletest//:gtest_main",
@@ -282,6 +295,7 @@
     size = "small",
     srcs = ["invoke_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base_internal",
         "//absl/memory",
@@ -297,6 +311,7 @@
     testonly = 1,
     srcs = ["spinlock_test_common.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         ":core_headers",
@@ -312,7 +327,7 @@
     size = "medium",
     srcs = ["spinlock_test_common.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = ["no_test_wasm"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         ":core_headers",
@@ -327,6 +342,7 @@
     testonly = 1,
     srcs = ["internal/spinlock_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl/base:__pkg__",
     ],
@@ -343,6 +359,7 @@
     name = "spinlock_benchmark",
     testonly = 1,
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
         ":spinlock_benchmark_common",
@@ -356,6 +373,7 @@
         "internal/unaligned_access.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":config",
         ":core_headers",
@@ -378,9 +396,7 @@
     name = "config_test",
     srcs = ["config_test.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = [
-        "no_test_wasm",
-    ],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":config",
         "//absl/synchronization:thread_pool",
@@ -392,9 +408,7 @@
     name = "call_once_test",
     srcs = ["call_once_test.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = [
-        "no_test_wasm",
-    ],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         ":core_headers",
@@ -407,6 +421,7 @@
     name = "raw_logging_test",
     srcs = ["raw_logging_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         "//absl/strings",
@@ -419,6 +434,7 @@
     size = "small",
     srcs = ["internal/sysinfo_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         "//absl/synchronization",
@@ -431,6 +447,7 @@
     size = "small",
     srcs = ["internal/low_level_alloc_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["no_test_ios_x86_64"],
     deps = [":malloc_internal"],
 )
@@ -440,9 +457,7 @@
     size = "small",
     srcs = ["internal/thread_identity_test.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = [
-        "no_test_wasm",
-    ],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":base",
         ":core_headers",
@@ -455,6 +470,7 @@
     name = "thread_identity_benchmark",
     srcs = ["internal/thread_identity_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["benchmark"],
     visibility = ["//visibility:private"],
     deps = [
@@ -467,6 +483,7 @@
 cc_library(
     name = "bits",
     hdrs = ["internal/bits.h"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -478,6 +495,7 @@
     size = "small",
     srcs = ["internal/bits_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":bits",
         "@com_google_googletest//:gtest_main",
@@ -489,6 +507,7 @@
     testonly = 1,
     srcs = ["internal/scoped_set_env.cc"],
     hdrs = ["internal/scoped_set_env.h"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -500,8 +519,21 @@
     size = "small",
     srcs = ["internal/scoped_set_env_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":scoped_set_env",
         "@com_google_googletest//:gtest_main",
     ],
 )
+
+cc_test(
+    name = "log_severity_test",
+    size = "small",
+    srcs = ["log_severity_test.cc"],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":base",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index d8a311c..b9f35bc 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -26,6 +26,8 @@
     "internal/spinlock_posix.inc"
     "internal/spinlock_wait.cc"
     "internal/spinlock_win32.inc"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::core_headers
 )
@@ -88,6 +90,7 @@
     absl::core_headers
     absl::dynamic_annotations
     absl::spinlock_wait
+    Threads::Threads
 )
 
 absl_cc_library(
@@ -126,6 +129,7 @@
     "internal/sysinfo.cc"
     "internal/thread_identity.cc"
     "internal/unscaledcycleclock.cc"
+    "log_severity.cc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
@@ -134,6 +138,8 @@
     absl::core_headers
     absl::dynamic_annotations
     absl::spinlock_wait
+    absl::type_traits
+    Threads::Threads
   PUBLIC
 )
 
@@ -217,6 +223,8 @@
     atomic_hook_test
   SRCS
     "internal/atomic_hook_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::core_headers
@@ -228,6 +236,8 @@
     bit_cast_test
   SRCS
     "bit_cast_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::core_headers
@@ -239,6 +249,8 @@
     throw_delegate_test
   SRCS
     "throw_delegate_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::throw_delegate
@@ -253,6 +265,8 @@
     "inline_variable_test.cc"
     "inline_variable_test_a.cc"
     "inline_variable_test_b.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base_internal
     gtest_main
@@ -263,6 +277,8 @@
     invoke_test
   SRCS
     "invoke_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base_internal
     absl::memory
@@ -293,6 +309,8 @@
     spinlock_test
   SRCS
     "spinlock_test_common.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::core_headers
@@ -320,6 +338,8 @@
     endian_test
   SRCS
     "internal/endian_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::config
@@ -332,6 +352,8 @@
     config_test
   SRCS
     "config_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::config
     absl::synchronization
@@ -343,6 +365,8 @@
     call_once_test
   SRCS
     "call_once_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::core_headers
@@ -355,6 +379,8 @@
     raw_logging_test
   SRCS
     "raw_logging_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::strings
@@ -366,6 +392,8 @@
     sysinfo_test
   SRCS
     "internal/sysinfo_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::synchronization
@@ -377,6 +405,8 @@
     low_level_alloc_test
   SRCS
     "internal/low_level_alloc_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::malloc_internal
     Threads::Threads
@@ -387,6 +417,8 @@
     thread_identity_test
   SRCS
     "internal/thread_identity_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::base
     absl::core_headers
@@ -411,6 +443,8 @@
     bits_test
   SRCS
     "internal/bits_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::bits
     gtest_main
@@ -434,7 +468,31 @@
     scoped_set_env_test
   SRCS
     "internal/scoped_set_env_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::scoped_set_env
     gtest_main
 )
+
+absl_cc_test(
+  NAME
+    cmake_thread_test
+  SRCS
+    "internal/cmake_thread_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
+  DEPS
+    absl::base
+)
+
+absl_cc_test(
+  NAME
+    log_severity_test
+  SRCS
+    "log_severity_test.cc"
+  DEPS
+    absl::base
+    gmock
+    gtest_main
+)
diff --git a/absl/base/casts.h b/absl/base/casts.h
index 00196d2..a381c42 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -30,28 +30,20 @@
 
 #include "absl/base/internal/identity.h"
 #include "absl/base/macros.h"
+#include "absl/meta/type_traits.h"
 
 namespace absl {
 
 namespace internal_casts {
 
-// NOTE: Not a fully compliant implementation of `std::is_trivially_copyable`.
-// TODO(calabrese) Branch on implementations that directly provide
-// `std::is_trivially_copyable`, create a more rigorous workaround, and publicly
-// expose in meta/type_traits.
-template <class T>
-struct is_trivially_copyable
-    : std::integral_constant<
-          bool, std::is_destructible<T>::value&& __has_trivial_destructor(T) &&
-                    __has_trivial_copy(T) && __has_trivial_assign(T)> {};
-
 template <class Dest, class Source>
 struct is_bitcastable
-    : std::integral_constant<bool,
-                             sizeof(Dest) == sizeof(Source) &&
-                                 is_trivially_copyable<Source>::value &&
-                                 is_trivially_copyable<Dest>::value &&
-                                 std::is_default_constructible<Dest>::value> {};
+    : std::integral_constant<
+          bool,
+          sizeof(Dest) == sizeof(Source) &&
+              type_traits_internal::is_trivially_copyable<Source>::value &&
+              type_traits_internal::is_trivially_copyable<Dest>::value &&
+              std::is_default_constructible<Dest>::value> {};
 
 }  // namespace internal_casts
 
diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h
index ac33df9..65a54b4 100644
--- a/absl/base/dynamic_annotations.h
+++ b/absl/base/dynamic_annotations.h
@@ -377,7 +377,7 @@
   struct { char x[8] __attribute__ ((aligned (8))); } name
 #else
 #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)
-#define ADDRESS_SANITIZER_REDZONE(name)
+#define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")
 #endif  // ADDRESS_SANITIZER
 
 /* Undefine the macros intended only in this file. */
diff --git a/absl/types/optional.cc b/absl/base/internal/cmake_thread_test.cc
similarity index 65%
copy from absl/types/optional.cc
copy to absl/base/internal/cmake_thread_test.cc
index 44ff829..f70bb24 100644
--- a/absl/types/optional.cc
+++ b/absl/base/internal/cmake_thread_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 The Abseil Authors.
+// 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.
@@ -12,13 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/types/optional.h"
+#include <iostream>
+#include "absl/base/internal/thread_identity.h"
 
-#ifndef ABSL_HAVE_STD_OPTIONAL
-namespace absl {
-
-nullopt_t::init_t nullopt_t::init;
-extern const nullopt_t nullopt{nullopt_t::init};
-
-}  // namespace absl
-#endif  // ABSL_HAVE_STD_OPTIONAL
+int main() {
+  auto* tid = absl::base_internal::CurrentThreadIdentityIfPresent();
+  // Make sure the above call can't be optimized out
+  std::cout << (void*)tid << std::endl;
+}
diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc
index 4b553c2..e9844b7 100644
--- a/absl/base/internal/cycleclock.cc
+++ b/absl/base/internal/cycleclock.cc
@@ -55,10 +55,23 @@
 static constexpr double kFrequencyScale = 1.0 / (1 << kShift);
 static std::atomic<CycleClockSourceFunc> cycle_clock_source;
 
+CycleClockSourceFunc LoadCycleClockSource() {
+  // Optimize for the common case (no callback) by first doing a relaxed load;
+  // this is significantly faster on non-x86 platforms.
+  if (cycle_clock_source.load(std::memory_order_relaxed) == nullptr) {
+    return nullptr;
+  }
+  // This corresponds to the store(std::memory_order_release) in
+  // CycleClockSource::Register, and makes sure that any updates made prior to
+  // registering the callback are visible to this thread before the callback is
+  // invoked.
+  return cycle_clock_source.load(std::memory_order_acquire);
+}
+
 }  // namespace
 
 int64_t CycleClock::Now() {
-  auto fn = cycle_clock_source.load(std::memory_order_relaxed);
+  auto fn = LoadCycleClockSource();
   if (fn == nullptr) {
     return base_internal::UnscaledCycleClock::Now() >> kShift;
   }
@@ -70,7 +83,8 @@
 }
 
 void CycleClockSource::Register(CycleClockSourceFunc source) {
-  cycle_clock_source.store(source, std::memory_order_relaxed);
+  // Corresponds to the load(std::memory_order_acquire) in LoadCycleClockSource.
+  cycle_clock_source.store(source, std::memory_order_release);
 }
 
 #else
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index b5a05e8..878fe6c 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -36,7 +36,8 @@
 // This preprocessor token is also defined in raw_io.cc.  If you need to copy
 // this, consider moving both to config.h instead.
 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
-    defined(__Fuchsia__) || defined(__native_client__)
+    defined(__Fuchsia__) || defined(__native_client__) || \
+    defined(__EMSCRIPTEN__)
 #include <unistd.h>
 
 
diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc
index 247f3d8..82bbcc2 100644
--- a/absl/base/internal/sysinfo_test.cc
+++ b/absl/base/internal/sysinfo_test.cc
@@ -37,12 +37,12 @@
 }
 
 TEST(SysinfoTest, NominalCPUFrequency) {
-#if !(defined(__aarch64__) && defined(__linux__))
+#if !(defined(__aarch64__) && defined(__linux__)) && !defined(__EMSCRIPTEN__)
   EXPECT_GE(NominalCPUFrequency(), 1000.0)
       << "NominalCPUFrequency() did not return a reasonable value";
 #else
-  // TODO(absl-team): Aarch64 cannot read the CPU frequency from sysfs, so we
-  // get back 1.0. Fix once the value is available.
+  // Aarch64 cannot read the CPU frequency from sysfs, so we get back 1.0.
+  // Emscripten does not have a sysfs to read from at all.
   EXPECT_EQ(NominalCPUFrequency(), 1.0)
       << "CPU frequency detection was fixed! Please update unittest.";
 #endif
diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h
index 2d66737..2cf7c1d 100644
--- a/absl/base/internal/unaligned_access.h
+++ b/absl/base/internal/unaligned_access.h
@@ -25,15 +25,6 @@
 // unaligned APIs
 
 // Portable handling of unaligned loads, stores, and copies.
-// On some platforms, like ARM, the copy functions can be more efficient
-// then a load and a store.
-//
-// It is possible to implement all of these these using constant-length memcpy
-// calls, which is portable and will usually be inlined into simple loads and
-// stores if the architecture supports it. However, such inlining usually
-// happens in a pass that's quite late in compilation, which means the resulting
-// loads and stores cannot participate in many other optimizations, leading to
-// overall worse code.
 
 // The unaligned API is C++ only.  The declarations use C++ features
 // (namespaces, inline) which are absent or incompatible in C.
@@ -108,164 +99,8 @@
 #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
   (absl::base_internal::UnalignedStore64(_p, _val))
 
-#elif defined(UNDEFINED_BEHAVIOR_SANITIZER)
-
-namespace absl {
-namespace base_internal {
-
-inline uint16_t UnalignedLoad16(const void *p) {
-  uint16_t t;
-  memcpy(&t, p, sizeof t);
-  return t;
-}
-
-inline uint32_t UnalignedLoad32(const void *p) {
-  uint32_t t;
-  memcpy(&t, p, sizeof t);
-  return t;
-}
-
-inline uint64_t UnalignedLoad64(const void *p) {
-  uint64_t t;
-  memcpy(&t, p, sizeof t);
-  return t;
-}
-
-inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); }
-
-inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
-
-inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
-
-}  // namespace base_internal
-}  // namespace absl
-
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
-  (absl::base_internal::UnalignedLoad16(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
-  (absl::base_internal::UnalignedLoad32(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
-  (absl::base_internal::UnalignedLoad64(_p))
-
-#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
-  (absl::base_internal::UnalignedStore16(_p, _val))
-#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
-  (absl::base_internal::UnalignedStore32(_p, _val))
-#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (absl::base_internal::UnalignedStore64(_p, _val))
-
-#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \
-    defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) ||    \
-    defined(__ppc64__) || defined(__PPC64__)
-
-// x86 and x86-64 can perform unaligned loads/stores directly;
-// modern PowerPC hardware can also do unaligned integer loads and stores;
-// but note: the FPU still sends unaligned loads and stores to a trap handler!
-
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
-  (*reinterpret_cast<const uint16_t *>(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
-  (*reinterpret_cast<const uint32_t *>(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
-  (*reinterpret_cast<const uint64_t *>(_p))
-
-#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
-  (*reinterpret_cast<uint16_t *>(_p) = (_val))
-#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
-  (*reinterpret_cast<uint32_t *>(_p) = (_val))
-#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (*reinterpret_cast<uint64_t *>(_p) = (_val))
-
-#elif defined(__arm__) && \
-      !defined(__ARM_ARCH_5__) && \
-      !defined(__ARM_ARCH_5T__) && \
-      !defined(__ARM_ARCH_5TE__) && \
-      !defined(__ARM_ARCH_5TEJ__) && \
-      !defined(__ARM_ARCH_6__) && \
-      !defined(__ARM_ARCH_6J__) && \
-      !defined(__ARM_ARCH_6K__) && \
-      !defined(__ARM_ARCH_6Z__) && \
-      !defined(__ARM_ARCH_6ZK__) && \
-      !defined(__ARM_ARCH_6T2__)
-
-
-// ARMv7 and newer support native unaligned accesses, but only of 16-bit
-// and 32-bit values (not 64-bit); older versions either raise a fatal signal,
-// do an unaligned read and rotate the words around a bit, or do the reads very
-// slowly (trip through kernel mode). There's no simple #define that says just
-// "ARMv7 or higher", so we have to filter away all ARMv5 and ARMv6
-// sub-architectures. Newer gcc (>= 4.6) set an __ARM_FEATURE_ALIGNED #define,
-// so in time, maybe we can move on to that.
-//
-// This is a mess, but there's not much we can do about it.
-//
-// To further complicate matters, only LDR instructions (single reads) are
-// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we
-// explicitly tell the compiler that these accesses can be unaligned, it can and
-// will combine accesses. On armcc, the way to signal this is done by accessing
-// through the type (uint32_t __packed *), but GCC has no such attribute
-// (it ignores __attribute__((packed)) on individual variables). However,
-// we can tell it that a _struct_ is unaligned, which has the same effect,
-// so we do that.
-
-namespace absl {
-namespace base_internal {
-
-struct Unaligned16Struct {
-  uint16_t value;
-  uint8_t dummy;  // To make the size non-power-of-two.
-} ABSL_ATTRIBUTE_PACKED;
-
-struct Unaligned32Struct {
-  uint32_t value;
-  uint8_t dummy;  // To make the size non-power-of-two.
-} ABSL_ATTRIBUTE_PACKED;
-
-}  // namespace base_internal
-}  // namespace absl
-
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p)                                  \
-  ((reinterpret_cast<const ::absl::base_internal::Unaligned16Struct *>(_p)) \
-       ->value)
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p)                                  \
-  ((reinterpret_cast<const ::absl::base_internal::Unaligned32Struct *>(_p)) \
-       ->value)
-
-#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val)                      \
-  ((reinterpret_cast< ::absl::base_internal::Unaligned16Struct *>(_p)) \
-       ->value = (_val))
-#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val)                      \
-  ((reinterpret_cast< ::absl::base_internal::Unaligned32Struct *>(_p)) \
-       ->value = (_val))
-
-namespace absl {
-namespace base_internal {
-
-inline uint64_t UnalignedLoad64(const void *p) {
-  uint64_t t;
-  memcpy(&t, p, sizeof t);
-  return t;
-}
-
-inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
-
-}  // namespace base_internal
-}  // namespace absl
-
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
-  (absl::base_internal::UnalignedLoad64(_p))
-#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (absl::base_internal::UnalignedStore64(_p, _val))
-
 #else
 
-// ABSL_INTERNAL_NEED_ALIGNED_LOADS is defined when the underlying platform
-// doesn't support unaligned access.
-#define ABSL_INTERNAL_NEED_ALIGNED_LOADS
-
-// These functions are provided for architectures that don't support
-// unaligned loads and stores.
-
 namespace absl {
 namespace base_internal {
 
diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h
index 58950cc..2d361e9 100644
--- a/absl/base/internal/unscaledcycleclock.h
+++ b/absl/base/internal/unscaledcycleclock.h
@@ -59,7 +59,8 @@
 // CycleClock that runs at atleast 1 MHz. We've found some Android
 // ARM64 devices where this is not the case, so we disable it by
 // default on Android ARM64.
-#if defined(__native_client__) || TARGET_OS_IPHONE || \
+#if defined(__native_client__) ||                      \
+    (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
     (defined(__ANDROID__) && defined(__aarch64__))
 #define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 0
 #else
diff --git a/absl/types/optional.cc b/absl/base/log_severity.cc
similarity index 69%
rename from absl/types/optional.cc
rename to absl/base/log_severity.cc
index 44ff829..02a2a48 100644
--- a/absl/types/optional.cc
+++ b/absl/base/log_severity.cc
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/types/optional.h"
+#include "absl/base/log_severity.h"
 
-#ifndef ABSL_HAVE_STD_OPTIONAL
+#include <ostream>
+
 namespace absl {
 
-nullopt_t::init_t nullopt_t::init;
-extern const nullopt_t nullopt{nullopt_t::init};
-
+std::ostream& operator<<(std::ostream& os, absl::LogSeverity s) {
+  if (s == absl::NormalizeLogSeverity(s)) return os << absl::LogSeverityName(s);
+  return os << "absl::LogSeverity(" << static_cast<int>(s) << ")";
+}
 }  // namespace absl
-#endif  // ABSL_HAVE_STD_OPTIONAL
diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h
index b19a7ff..5a1d557 100644
--- a/absl/base/log_severity.h
+++ b/absl/base/log_severity.h
@@ -16,6 +16,7 @@
 #define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
 
 #include <array>
+#include <ostream>
 
 #include "absl/base/attributes.h"
 
@@ -61,6 +62,10 @@
   return NormalizeLogSeverity(static_cast<absl::LogSeverity>(s));
 }
 
+// The exact representation of a streamed `absl::LogSeverity` is deliberately
+// unspecified; do not rely on it.
+std::ostream& operator<<(std::ostream& os, absl::LogSeverity s);
+
 }  // namespace absl
 
 #endif  // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
diff --git a/absl/base/log_severity_test.cc b/absl/base/log_severity_test.cc
new file mode 100644
index 0000000..1de2d10
--- /dev/null
+++ b/absl/base/log_severity_test.cc
@@ -0,0 +1,43 @@
+// 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.
+
+#include "absl/base/log_severity.h"
+
+#include <sstream>
+#include <string>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace {
+using testing::Eq;
+
+std::string StreamHelper(absl::LogSeverity value) {
+  std::ostringstream stream;
+  stream << value;
+  return stream.str();
+}
+
+TEST(StreamTest, Works) {
+  EXPECT_THAT(StreamHelper(static_cast<absl::LogSeverity>(-100)),
+              Eq("absl::LogSeverity(-100)"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kInfo), Eq("INFO"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kWarning), Eq("WARNING"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kError), Eq("ERROR"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kFatal), Eq("FATAL"));
+  EXPECT_THAT(StreamHelper(static_cast<absl::LogSeverity>(4)),
+              Eq("absl::LogSeverity(4)"));
+}
+
+}  // namespace
diff --git a/absl/base/macros.h b/absl/base/macros.h
index 5b43d7c..ca62079 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -191,10 +191,11 @@
 // This macro is inspired by
 // https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
 #if defined(NDEBUG)
-#define ABSL_ASSERT(expr) (false ? (void)(expr) : (void)0)
+#define ABSL_ASSERT(expr) \
+  (false ? static_cast<void>(expr) : static_cast<void>(0))
 #else
-#define ABSL_ASSERT(expr)              \
-  (ABSL_PREDICT_TRUE((expr)) ? (void)0 \
+#define ABSL_ASSERT(expr)                           \
+  (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
                              : [] { assert(false && #expr); }())  // NOLINT
 #endif
 
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index cd914ba..f25a9ff 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_EXCEPTIONS_FLAG",
     "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
     "ABSL_TEST_COPTS",
@@ -30,6 +31,7 @@
     name = "compressed_tuple",
     hdrs = ["internal/compressed_tuple.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/utility",
     ],
@@ -39,6 +41,7 @@
     name = "compressed_tuple_test",
     srcs = ["internal/compressed_tuple_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":compressed_tuple",
         "//absl/memory",
@@ -51,6 +54,7 @@
     name = "fixed_array",
     hdrs = ["fixed_array.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":compressed_tuple",
         "//absl/algorithm",
@@ -65,7 +69,7 @@
     name = "fixed_array_test",
     srcs = ["fixed_array_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":fixed_array",
         "//absl/base:exception_testing",
@@ -79,6 +83,7 @@
     name = "fixed_array_test_noexceptions",
     srcs = ["fixed_array_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":fixed_array",
         "//absl/base:exception_testing",
@@ -92,7 +97,7 @@
     name = "fixed_array_exception_safety_test",
     srcs = ["fixed_array_exception_safety_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":fixed_array",
         "//absl/base:exception_safety_testing",
@@ -104,6 +109,7 @@
     name = "fixed_array_benchmark",
     srcs = ["fixed_array_benchmark.cc"],
     copts = ABSL_TEST_COPTS + ["$(STACK_FRAME_UNLIMITED)"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["benchmark"],
     deps = [
         ":fixed_array",
@@ -115,7 +121,9 @@
     name = "inlined_vector_internal",
     hdrs = ["internal/inlined_vector.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
+        ":compressed_tuple",
         "//absl/meta:type_traits",
     ],
 )
@@ -124,6 +132,7 @@
     name = "inlined_vector",
     hdrs = ["inlined_vector.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":inlined_vector_internal",
         "//absl/algorithm",
@@ -138,6 +147,7 @@
     testonly = 1,
     hdrs = ["internal/counting_allocator.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
 )
 
@@ -145,7 +155,7 @@
     name = "inlined_vector_test",
     srcs = ["inlined_vector_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":counting_allocator",
         ":inlined_vector",
@@ -164,6 +174,7 @@
     name = "inlined_vector_test_noexceptions",
     srcs = ["inlined_vector_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":counting_allocator",
         ":inlined_vector",
@@ -182,6 +193,7 @@
     name = "inlined_vector_benchmark",
     srcs = ["inlined_vector_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["benchmark"],
     deps = [
         ":inlined_vector",
@@ -197,6 +209,7 @@
     srcs = ["internal/test_instance_tracker.cc"],
     hdrs = ["internal/test_instance_tracker.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -206,6 +219,7 @@
     name = "test_instance_tracker_test",
     srcs = ["internal/test_instance_tracker_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":test_instance_tracker",
         "@com_google_googletest//:gtest_main",
@@ -230,6 +244,7 @@
     name = "flat_hash_map",
     hdrs = ["flat_hash_map.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":container_memory",
         ":hash_function_defaults",
@@ -243,6 +258,7 @@
     name = "flat_hash_map_test",
     srcs = ["flat_hash_map_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":flat_hash_map",
@@ -260,6 +276,7 @@
     name = "flat_hash_set",
     hdrs = ["flat_hash_set.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":container_memory",
         ":hash_function_defaults",
@@ -274,6 +291,7 @@
     name = "flat_hash_set_test",
     srcs = ["flat_hash_set_test.cc"],
     copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":flat_hash_set",
@@ -292,6 +310,7 @@
     name = "node_hash_map",
     hdrs = ["node_hash_map.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":container_memory",
         ":hash_function_defaults",
@@ -306,6 +325,7 @@
     name = "node_hash_map_test",
     srcs = ["node_hash_map_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":hash_generator_testing",
@@ -323,6 +343,7 @@
     name = "node_hash_set",
     hdrs = ["node_hash_set.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_function_defaults",
         ":node_hash_policy",
@@ -336,6 +357,7 @@
     name = "node_hash_set_test",
     srcs = ["node_hash_set_test.cc"],
     copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":node_hash_set",
@@ -351,6 +373,7 @@
     name = "container_memory",
     hdrs = ["internal/container_memory.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/memory",
         "//absl/utility",
@@ -361,6 +384,7 @@
     name = "container_memory_test",
     srcs = ["internal/container_memory_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":container_memory",
@@ -373,6 +397,7 @@
     name = "hash_function_defaults",
     hdrs = ["internal/hash_function_defaults.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:config",
         "//absl/hash",
@@ -384,6 +409,7 @@
     name = "hash_function_defaults_test",
     srcs = ["internal/hash_function_defaults_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS,
     deps = [
         ":hash_function_defaults",
@@ -399,6 +425,7 @@
     srcs = ["internal/hash_generator_testing.cc"],
     hdrs = ["internal/hash_generator_testing.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_policy_testing",
         "//absl/meta:type_traits",
@@ -411,6 +438,7 @@
     testonly = 1,
     hdrs = ["internal/hash_policy_testing.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/hash",
         "//absl/strings",
@@ -421,6 +449,7 @@
     name = "hash_policy_testing_test",
     srcs = ["internal/hash_policy_testing_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_policy_testing",
         "@com_google_googletest//:gtest_main",
@@ -431,6 +460,7 @@
     name = "hash_policy_traits",
     hdrs = ["internal/hash_policy_traits.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = ["//absl/meta:type_traits"],
 )
 
@@ -438,6 +468,7 @@
     name = "hash_policy_traits_test",
     srcs = ["internal/hash_policy_traits_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_policy_traits",
         "@com_google_googletest//:gtest_main",
@@ -448,6 +479,7 @@
     name = "hashtable_debug",
     hdrs = ["internal/hashtable_debug.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hashtable_debug_hooks",
     ],
@@ -457,6 +489,7 @@
     name = "hashtable_debug_hooks",
     hdrs = ["internal/hashtable_debug_hooks.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
 )
 
 cc_library(
@@ -467,6 +500,7 @@
     ],
     hdrs = ["internal/hashtablez_sampler.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":have_sse",
         "//absl/base",
@@ -481,6 +515,7 @@
 cc_test(
     name = "hashtablez_sampler_test",
     srcs = ["internal/hashtablez_sampler_test.cc"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hashtablez_sampler",
         ":have_sse",
@@ -496,12 +531,14 @@
     name = "node_hash_policy",
     hdrs = ["internal/node_hash_policy.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
 )
 
 cc_test(
     name = "node_hash_policy_test",
     srcs = ["internal/node_hash_policy_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_policy_traits",
         ":node_hash_policy",
@@ -513,6 +550,7 @@
     name = "raw_hash_map",
     hdrs = ["internal/raw_hash_map.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":container_memory",
         ":raw_hash_set",
@@ -523,6 +561,7 @@
     name = "have_sse",
     hdrs = ["internal/have_sse.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
 )
 
@@ -530,6 +569,7 @@
     name = "common",
     hdrs = ["internal/common.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/meta:type_traits",
         "//absl/types:optional",
@@ -541,6 +581,7 @@
     srcs = ["internal/raw_hash_set.cc"],
     hdrs = ["internal/raw_hash_set.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":common",
         ":compressed_tuple",
@@ -584,6 +625,7 @@
     size = "small",
     srcs = ["internal/raw_hash_set_allocator_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":raw_hash_set",
         ":tracked",
@@ -596,6 +638,7 @@
     name = "layout",
     hdrs = ["internal/layout.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:core_headers",
         "//absl/meta:type_traits",
@@ -610,6 +653,7 @@
     size = "small",
     srcs = ["internal/layout_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS,
     visibility = ["//visibility:private"],
     deps = [
@@ -626,6 +670,7 @@
     testonly = 1,
     hdrs = ["internal/tracked.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
 )
 
 cc_library(
@@ -633,6 +678,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_map_constructor_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_generator_testing",
         ":hash_policy_testing",
@@ -645,6 +691,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_map_lookup_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_generator_testing",
         ":hash_policy_testing",
@@ -657,6 +704,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_map_modifiers_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_generator_testing",
         ":hash_policy_testing",
@@ -669,6 +717,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_set_constructor_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_generator_testing",
         ":hash_policy_testing",
@@ -682,6 +731,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_set_members_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/meta:type_traits",
         "@com_google_googletest//:gtest",
@@ -693,6 +743,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_map_members_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/meta:type_traits",
         "@com_google_googletest//:gtest",
@@ -704,6 +755,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_set_lookup_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_generator_testing",
         ":hash_policy_testing",
@@ -716,6 +768,7 @@
     testonly = 1,
     hdrs = ["internal/unordered_set_modifiers_test.h"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash_generator_testing",
         ":hash_policy_testing",
@@ -727,6 +780,7 @@
     name = "unordered_set_test",
     srcs = ["internal/unordered_set_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":unordered_set_constructor_test",
@@ -741,6 +795,7 @@
     name = "unordered_map_test",
     srcs = ["internal/unordered_map_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = NOTEST_TAGS_NONMOBILE,
     deps = [
         ":unordered_map_constructor_test",
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 292fea2..9531d7f 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -27,7 +27,9 @@
   NAME
     compressed_tuple
   HDRS
-   "internal/compressed_tuple.h"
+    "internal/compressed_tuple.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::utility
   PUBLIC
@@ -38,6 +40,8 @@
     compressed_tuple_test
   SRCS
     "internal/compressed_tuple_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::compressed_tuple
     absl::memory
@@ -68,6 +72,7 @@
   SRCS
     "fixed_array_test.cc"
   COPTS
+    ${ABSL_TEST_COPTS}
     ${ABSL_EXCEPTIONS_FLAG}
   LINKOPTS
     ${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
@@ -84,6 +89,8 @@
     fixed_array_test_noexceptions
   SRCS
     "fixed_array_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::fixed_array
     absl::exception_testing
@@ -98,6 +105,7 @@
   SRCS
     "fixed_array_exception_safety_test.cc"
   COPTS
+    ${ABSL_TEST_COPTS}
     ${ABSL_EXCEPTIONS_FLAG}
   LINKOPTS
     ${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
@@ -115,6 +123,7 @@
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
+    absl::compressed_tuple
     absl::type_traits
   PUBLIC
 )
@@ -129,6 +138,7 @@
   DEPS
     absl::algorithm
     absl::core_headers
+    absl::inlined_vector_internal
     absl::throw_delegate
     absl::memory
   PUBLIC
@@ -149,6 +159,7 @@
   SRCS
     "inlined_vector_test.cc"
   COPTS
+    ${ABSL_TEST_COPTS}
     ${ABSL_EXCEPTIONS_FLAG}
   LINKOPTS
     ${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
@@ -170,6 +181,8 @@
     inlined_vector_test_noexceptions
   SRCS
     "inlined_vector_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::inlined_vector
     absl::test_instance_tracker
@@ -199,6 +212,8 @@
     test_instance_tracker_test
   SRCS
     "internal/test_instance_tracker_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::test_instance_tracker
     gmock_main
@@ -225,6 +240,8 @@
     flat_hash_map_test
   SRCS
     "flat_hash_map_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::flat_hash_map
     absl::hash_generator_testing
@@ -259,6 +276,7 @@
   SRCS
     "flat_hash_set_test.cc"
   COPTS
+    ${ABSL_TEST_COPTS}
     "-DUNORDERED_SET_CXX17"
   DEPS
     absl::flat_hash_set
@@ -294,6 +312,8 @@
     node_hash_map_test
   SRCS
     "node_hash_map_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hash_generator_testing
     absl::node_hash_map
@@ -327,6 +347,7 @@
   SRCS
     "node_hash_set_test.cc"
   COPTS
+    ${ABSL_TEST_COPTS}
     "-DUNORDERED_SET_CXX17"
   DEPS
     absl::hash_generator_testing
@@ -356,6 +377,8 @@
     container_memory_test
   SRCS
     "internal/container_memory_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::container_memory
     absl::strings
@@ -381,6 +404,8 @@
     hash_function_defaults_test
   SRCS
     "internal/hash_function_defaults_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hash_function_defaults
     absl::hash
@@ -422,6 +447,8 @@
     hash_policy_testing_test
   SRCS
     "internal/hash_policy_testing_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hash_policy_testing
     gmock_main
@@ -444,6 +471,8 @@
     hash_policy_traits_test
   SRCS
     "internal/hash_policy_traits_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hash_policy_traits
     gmock_main
@@ -470,6 +499,8 @@
     hashtablez_sampler_test
   SRCS
     "internal/hashtablez_sampler_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hashtablez_sampler
     absl::have_sse
@@ -521,6 +552,8 @@
     node_hash_policy_test
   SRCS
     "internal/node_hash_policy_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hash_policy_traits
     absl::node_hash_policy
@@ -585,6 +618,8 @@
     raw_hash_set_test
   SRCS
     "internal/raw_hash_set_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::container_memory
     absl::hash_function_defaults
@@ -602,6 +637,8 @@
     raw_hash_set_allocator_test
   SRCS
     "internal/raw_hash_set_allocator_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::raw_hash_set
     absl::tracked
@@ -630,6 +667,8 @@
     layout_test
   SRCS
     "internal/layout_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::layout
     absl::base
@@ -763,6 +802,8 @@
     unordered_set_test
   SRCS
     "internal/unordered_set_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::unordered_set_constructor_test
     absl::unordered_set_lookup_test
@@ -776,6 +817,8 @@
     unordered_map_test
   SRCS
     "internal/unordered_map_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::unordered_map_constructor_test
     absl::unordered_map_lookup_test
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 7798805..34e9aa0 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -70,22 +70,15 @@
       N > 0, "InlinedVector cannot be instantiated with `0` inlined elements.");
 
   using Storage = inlined_vector_internal::Storage<InlinedVector>;
-  using Tag = typename Storage::Tag;
-  using AllocatorAndTag = typename Storage::AllocatorAndTag;
-  using Allocation = typename Storage::Allocation;
+  using AllocatorTraits = typename Storage::AllocatorTraits;
 
   template <typename Iterator>
-  using IsAtLeastForwardIterator = std::is_convertible<
-      typename std::iterator_traits<Iterator>::iterator_category,
-      std::forward_iterator_tag>;
+  using EnableIfAtLeastForwardIterator = absl::enable_if_t<
+      inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value>;
 
   template <typename Iterator>
-  using EnableIfAtLeastForwardIterator =
-      absl::enable_if_t<IsAtLeastForwardIterator<Iterator>::value>;
-
-  template <typename Iterator>
-  using DisableIfAtLeastForwardIterator =
-      absl::enable_if_t<!IsAtLeastForwardIterator<Iterator>::value>;
+  using DisableIfAtLeastForwardIterator = absl::enable_if_t<
+      !inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value>;
 
   using rvalue_reference = typename Storage::rvalue_reference;
 
@@ -162,27 +155,28 @@
 
   // Creates a copy of an `other` inlined vector using `other`'s allocator.
   InlinedVector(const InlinedVector& other)
-      : InlinedVector(other, other.allocator()) {}
+      : InlinedVector(other, other.storage_.GetAllocator()) {}
 
   // Creates a copy of an `other` inlined vector using a specified allocator.
   InlinedVector(const InlinedVector& other, const allocator_type& alloc)
       : storage_(alloc) {
     reserve(other.size());
-    if (allocated()) {
-      UninitializedCopy(other.begin(), other.end(), allocated_space());
-      tag().set_allocated_size(other.size());
+    if (storage_.GetIsAllocated()) {
+      UninitializedCopy(other.begin(), other.end(),
+                        storage_.GetAllocatedData());
+      storage_.SetAllocatedSize(other.size());
     } else {
-      UninitializedCopy(other.begin(), other.end(), inlined_space());
-      tag().set_inline_size(other.size());
+      UninitializedCopy(other.begin(), other.end(), storage_.GetInlinedData());
+      storage_.SetInlinedSize(other.size());
     }
   }
 
   // Creates an inlined vector by moving in the contents of an `other` inlined
   // vector without performing any allocations. If `other` contains allocated
   // memory, the newly-created instance will take ownership of that memory
-  // (leaving `other` itself empty). However, if `other` does not contain any
-  // allocated memory, the new inlined vector will  will perform element-wise
-  // move construction of `other`s elements.
+  // (leaving `other` empty). However, if `other` does not contain allocated
+  // memory (i.e. is inlined), the new inlined vector will perform element-wise
+  // move construction of `other`'s elements.
   //
   // NOTE: since no allocation is performed for the inlined vector in either
   // case, the `noexcept(...)` specification depends on whether moving the
@@ -195,19 +189,21 @@
   InlinedVector(InlinedVector&& other) noexcept(
       absl::allocator_is_nothrow<allocator_type>::value ||
       std::is_nothrow_move_constructible<value_type>::value)
-      : storage_(other.allocator()) {
-    if (other.allocated()) {
+      : storage_(other.storage_.GetAllocator()) {
+    if (other.storage_.GetIsAllocated()) {
       // We can just steal the underlying buffer from the source.
       // That leaves the source empty, so we clear its size.
-      init_allocation(other.allocation());
-      tag().set_allocated_size(other.size());
-      other.tag() = Tag();
+      storage_.SetAllocatedData(other.storage_.GetAllocatedData());
+      storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity());
+      storage_.SetAllocatedSize(other.size());
+      other.storage_.SetInlinedSize(0);
     } else {
       UninitializedCopy(
-          std::make_move_iterator(other.inlined_space()),
-          std::make_move_iterator(other.inlined_space() + other.size()),
-          inlined_space());
-      tag().set_inline_size(other.size());
+          std::make_move_iterator(other.storage_.GetInlinedData()),
+          std::make_move_iterator(other.storage_.GetInlinedData() +
+                                  other.size()),
+          storage_.GetInlinedData());
+      storage_.SetInlinedSize(other.size());
     }
   }
 
@@ -227,26 +223,28 @@
   InlinedVector(InlinedVector&& other, const allocator_type& alloc) noexcept(
       absl::allocator_is_nothrow<allocator_type>::value)
       : storage_(alloc) {
-    if (other.allocated()) {
-      if (alloc == other.allocator()) {
+    if (other.storage_.GetIsAllocated()) {
+      if (alloc == other.storage_.GetAllocator()) {
         // We can just steal the allocation from the source.
-        tag() = other.tag();
-        init_allocation(other.allocation());
-        other.tag() = Tag();
+        storage_.SetAllocatedSize(other.size());
+        storage_.SetAllocatedData(other.storage_.GetAllocatedData());
+        storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity());
+        other.storage_.SetInlinedSize(0);
       } else {
         // We need to use our own allocator
         reserve(other.size());
         UninitializedCopy(std::make_move_iterator(other.begin()),
                           std::make_move_iterator(other.end()),
-                          allocated_space());
-        tag().set_allocated_size(other.size());
+                          storage_.GetAllocatedData());
+        storage_.SetAllocatedSize(other.size());
       }
     } else {
       UninitializedCopy(
-          std::make_move_iterator(other.inlined_space()),
-          std::make_move_iterator(other.inlined_space() + other.size()),
-          inlined_space());
-      tag().set_inline_size(other.size());
+          std::make_move_iterator(other.storage_.GetInlinedData()),
+          std::make_move_iterator(other.storage_.GetInlinedData() +
+                                  other.size()),
+          storage_.GetInlinedData());
+      storage_.SetInlinedSize(other.size());
     }
   }
 
@@ -264,7 +262,7 @@
   // `InlinedVector::size()`
   //
   // Returns the number of elements in the inlined vector.
-  size_type size() const noexcept { return tag().size(); }
+  size_type size() const noexcept { return storage_.GetSize(); }
 
   // `InlinedVector::max_size()`
   //
@@ -286,7 +284,8 @@
   // will no longer be inlined and `capacity()` will equal its capacity on the
   // allocated heap.
   size_type capacity() const noexcept {
-    return allocated() ? allocation().capacity() : static_cast<size_type>(N);
+    return storage_.GetIsAllocated() ? storage_.GetAllocatedCapacity()
+                                     : static_cast<size_type>(N);
   }
 
   // `InlinedVector::data()`
@@ -295,14 +294,16 @@
   // used to access and modify the contained elements.
   // Only results within the range [`0`, `size()`) are defined.
   pointer data() noexcept {
-    return allocated() ? allocated_space() : inlined_space();
+    return storage_.GetIsAllocated() ? storage_.GetAllocatedData()
+                                     : storage_.GetInlinedData();
   }
 
   // Overload of `InlinedVector::data()` to return a `const_pointer` to elements
   // of the inlined vector. This pointer can be used to access (but not modify)
   // the contained elements.
   const_pointer data() const noexcept {
-    return allocated() ? allocated_space() : inlined_space();
+    return storage_.GetIsAllocated() ? storage_.GetAllocatedData()
+                                     : storage_.GetInlinedData();
   }
 
   // `InlinedVector::operator[]()`
@@ -436,7 +437,7 @@
   // `InlinedVector::get_allocator()`
   //
   // Returns a copy of the allocator of the inlined vector.
-  allocator_type get_allocator() const { return allocator(); }
+  allocator_type get_allocator() const { return storage_.GetAllocator(); }
 
   // ---------------------------------------------------------------------------
   // InlinedVector Member Mutators
@@ -454,7 +455,7 @@
   // Overload of `InlinedVector::operator=()` to replace the contents of the
   // inlined vector with the contents of `other`.
   InlinedVector& operator=(const InlinedVector& other) {
-    if (ABSL_PREDICT_FALSE(this == &other)) return *this;
+    if (ABSL_PREDICT_FALSE(this == std::addressof(other))) return *this;
 
     // Optimized to avoid reallocation.
     // Prefer reassignment to copy construction for elements.
@@ -475,15 +476,16 @@
   // NOTE: As a result of calling this overload, `other` may be empty or it's
   // contents may be left in a moved-from state.
   InlinedVector& operator=(InlinedVector&& other) {
-    if (ABSL_PREDICT_FALSE(this == &other)) return *this;
+    if (ABSL_PREDICT_FALSE(this == std::addressof(other))) return *this;
 
-    if (other.allocated()) {
+    if (other.storage_.GetIsAllocated()) {
       clear();
-      tag().set_allocated_size(other.size());
-      init_allocation(other.allocation());
-      other.tag() = Tag();
+      storage_.SetAllocatedSize(other.size());
+      storage_.SetAllocatedData(other.storage_.GetAllocatedData());
+      storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity());
+      other.storage_.SetInlinedSize(0);
     } else {
-      if (allocated()) clear();
+      if (storage_.GetIsAllocated()) clear();
       // Both are inlined now.
       if (size() < other.size()) {
         auto mid = std::make_move_iterator(other.begin() + size());
@@ -494,7 +496,7 @@
                                  std::make_move_iterator(other.end()), begin());
         Destroy(new_end, end());
       }
-      tag().set_inline_size(other.size());
+      storage_.SetInlinedSize(other.size());
     }
     return *this;
   }
@@ -511,12 +513,14 @@
     // Grow
     reserve(n);
     std::fill_n(begin(), size(), v);
-    if (allocated()) {
-      UninitializedFill(allocated_space() + size(), allocated_space() + n, v);
-      tag().set_allocated_size(n);
+    if (storage_.GetIsAllocated()) {
+      UninitializedFill(storage_.GetAllocatedData() + size(),
+                        storage_.GetAllocatedData() + n, v);
+      storage_.SetAllocatedSize(n);
     } else {
-      UninitializedFill(inlined_space() + size(), inlined_space() + n, v);
-      tag().set_inline_size(n);
+      UninitializedFill(storage_.GetInlinedData() + size(),
+                        storage_.GetInlinedData() + n, v);
+      storage_.SetInlinedSize(n);
     }
   }
 
@@ -564,12 +568,14 @@
     assert(capacity() >= n);
 
     // Fill new space with elements constructed in-place.
-    if (allocated()) {
-      UninitializedFill(allocated_space() + s, allocated_space() + n);
-      tag().set_allocated_size(n);
+    if (storage_.GetIsAllocated()) {
+      UninitializedFill(storage_.GetAllocatedData() + s,
+                        storage_.GetAllocatedData() + n);
+      storage_.SetAllocatedSize(n);
     } else {
-      UninitializedFill(inlined_space() + s, inlined_space() + n);
-      tag().set_inline_size(n);
+      UninitializedFill(storage_.GetInlinedData() + s,
+                        storage_.GetInlinedData() + n);
+      storage_.SetInlinedSize(n);
     }
   }
 
@@ -586,12 +592,14 @@
     assert(capacity() >= n);
 
     // Fill new space with copies of `v`.
-    if (allocated()) {
-      UninitializedFill(allocated_space() + s, allocated_space() + n, v);
-      tag().set_allocated_size(n);
+    if (storage_.GetIsAllocated()) {
+      UninitializedFill(storage_.GetAllocatedData() + s,
+                        storage_.GetAllocatedData() + n, v);
+      storage_.SetAllocatedSize(n);
     } else {
-      UninitializedFill(inlined_space() + s, inlined_space() + n, v);
-      tag().set_inline_size(n);
+      UninitializedFill(storage_.GetInlinedData() + s,
+                        storage_.GetInlinedData() + n, v);
+      storage_.SetInlinedSize(n);
     }
   }
 
@@ -688,12 +696,12 @@
       return GrowAndEmplaceBack(std::forward<Args>(args)...);
     }
     pointer space;
-    if (allocated()) {
-      tag().set_allocated_size(s + 1);
-      space = allocated_space();
+    if (storage_.GetIsAllocated()) {
+      storage_.SetAllocatedSize(s + 1);
+      space = storage_.GetAllocatedData();
     } else {
-      tag().set_inline_size(s + 1);
-      space = inlined_space();
+      storage_.SetInlinedSize(s + 1);
+      space = storage_.GetInlinedData();
     }
     return Construct(space + s, std::forward<Args>(args)...);
   }
@@ -716,12 +724,13 @@
   void pop_back() noexcept {
     assert(!empty());
     size_type s = size();
-    if (allocated()) {
-      Destroy(allocated_space() + s - 1, allocated_space() + s);
-      tag().set_allocated_size(s - 1);
+    if (storage_.GetIsAllocated()) {
+      Destroy(storage_.GetAllocatedData() + s - 1,
+              storage_.GetAllocatedData() + s);
+      storage_.SetAllocatedSize(s - 1);
     } else {
-      Destroy(inlined_space() + s - 1, inlined_space() + s);
-      tag().set_inline_size(s - 1);
+      Destroy(storage_.GetInlinedData() + s - 1, storage_.GetInlinedData() + s);
+      storage_.SetInlinedSize(s - 1);
     }
   }
 
@@ -757,12 +766,12 @@
     ptrdiff_t erase_gap = std::distance(range_start, range_end);
     if (erase_gap > 0) {
       pointer space;
-      if (allocated()) {
-        space = allocated_space();
-        tag().set_allocated_size(s - erase_gap);
+      if (storage_.GetIsAllocated()) {
+        space = storage_.GetAllocatedData();
+        storage_.SetAllocatedSize(s - erase_gap);
       } else {
-        space = inlined_space();
-        tag().set_inline_size(s - erase_gap);
+        space = storage_.GetInlinedData();
+        storage_.SetInlinedSize(s - erase_gap);
       }
       std::move(range_end, space + s, range_start);
       Destroy(space + s - erase_gap, space + s);
@@ -776,13 +785,15 @@
   // deallocates the heap allocation if the inlined vector was allocated.
   void clear() noexcept {
     size_type s = size();
-    if (allocated()) {
-      Destroy(allocated_space(), allocated_space() + s);
-      allocation().Dealloc(allocator());
+    if (storage_.GetIsAllocated()) {
+      Destroy(storage_.GetAllocatedData(), storage_.GetAllocatedData() + s);
+      AllocatorTraits::deallocate(storage_.GetAllocator(),
+                                  storage_.GetAllocatedData(),
+                                  storage_.GetAllocatedCapacity());
     } else if (s != 0) {  // do nothing for empty vectors
-      Destroy(inlined_space(), inlined_space() + s);
+      Destroy(storage_.GetInlinedData(), storage_.GetInlinedData() + s);
     }
-    tag() = Tag();
+    storage_.SetInlinedSize(0);
   }
 
   // `InlinedVector::reserve()`
@@ -814,7 +825,8 @@
   // smaller heap allocation.
   void shrink_to_fit() {
     const auto s = size();
-    if (ABSL_PREDICT_FALSE(!allocated() || s == capacity())) return;
+    if (ABSL_PREDICT_FALSE(!storage_.GetIsAllocated() || s == capacity()))
+      return;
 
     if (s <= N) {
       // Move the elements to the inlined storage.
@@ -829,86 +841,48 @@
     // Reallocate storage and move elements.
     // We can't simply use the same approach as above, because `assign()` would
     // call into `reserve()` internally and reserve larger capacity than we need
-    Allocation new_allocation(allocator(), s);
-    UninitializedCopy(std::make_move_iterator(allocated_space()),
-                      std::make_move_iterator(allocated_space() + s),
-                      new_allocation.buffer());
-    ResetAllocation(new_allocation, s);
+    pointer new_data = AllocatorTraits::allocate(storage_.GetAllocator(), s);
+    UninitializedCopy(std::make_move_iterator(storage_.GetAllocatedData()),
+                      std::make_move_iterator(storage_.GetAllocatedData() + s),
+                      new_data);
+    ResetAllocation(new_data, s, s);
   }
 
   // `InlinedVector::swap()`
   //
   // Swaps the contents of this inlined vector with the contents of `other`.
   void swap(InlinedVector& other) {
-    if (ABSL_PREDICT_FALSE(this == &other)) return;
+    if (ABSL_PREDICT_FALSE(this == std::addressof(other))) return;
 
     SwapImpl(other);
   }
 
  private:
   template <typename H, typename TheT, size_t TheN, typename TheA>
-  friend auto AbslHashValue(H h, const InlinedVector<TheT, TheN, TheA>& v) -> H;
+  friend H AbslHashValue(H h, const absl::InlinedVector<TheT, TheN, TheA>& a);
 
-  const Tag& tag() const { return storage_.allocator_and_tag_.tag(); }
-
-  Tag& tag() { return storage_.allocator_and_tag_.tag(); }
-
-  Allocation& allocation() {
-    return reinterpret_cast<Allocation&>(
-        storage_.rep_.allocation_storage.allocation);
-  }
-
-  const Allocation& allocation() const {
-    return reinterpret_cast<const Allocation&>(
-        storage_.rep_.allocation_storage.allocation);
-  }
-
-  void init_allocation(const Allocation& allocation) {
-    new (&storage_.rep_.allocation_storage.allocation) Allocation(allocation);
-  }
-
-  // TODO(absl-team): investigate whether the reinterpret_cast is appropriate.
-  pointer inlined_space() {
-    return reinterpret_cast<pointer>(
-        std::addressof(storage_.rep_.inlined_storage.inlined[0]));
-  }
-
-  const_pointer inlined_space() const {
-    return reinterpret_cast<const_pointer>(
-        std::addressof(storage_.rep_.inlined_storage.inlined[0]));
-  }
-
-  pointer allocated_space() { return allocation().buffer(); }
-
-  const_pointer allocated_space() const { return allocation().buffer(); }
-
-  const allocator_type& allocator() const {
-    return storage_.allocator_and_tag_.allocator();
-  }
-
-  allocator_type& allocator() {
-    return storage_.allocator_and_tag_.allocator();
-  }
-
-  bool allocated() const { return tag().allocated(); }
-
-  void ResetAllocation(Allocation new_allocation, size_type new_size) {
-    if (allocated()) {
-      Destroy(allocated_space(), allocated_space() + size());
-      assert(begin() == allocated_space());
-      allocation().Dealloc(allocator());
-      allocation() = new_allocation;
+  void ResetAllocation(pointer new_data, size_type new_capacity,
+                       size_type new_size) {
+    if (storage_.GetIsAllocated()) {
+      Destroy(storage_.GetAllocatedData(),
+              storage_.GetAllocatedData() + size());
+      assert(begin() == storage_.GetAllocatedData());
+      AllocatorTraits::deallocate(storage_.GetAllocator(),
+                                  storage_.GetAllocatedData(),
+                                  storage_.GetAllocatedCapacity());
     } else {
-      Destroy(inlined_space(), inlined_space() + size());
-      init_allocation(new_allocation);  // bug: only init once
+      Destroy(storage_.GetInlinedData(), storage_.GetInlinedData() + size());
     }
-    tag().set_allocated_size(new_size);
+
+    storage_.SetAllocatedData(new_data);
+    storage_.SetAllocatedCapacity(new_capacity);
+    storage_.SetAllocatedSize(new_size);
   }
 
   template <typename... Args>
   reference Construct(pointer p, Args&&... args) {
     std::allocator_traits<allocator_type>::construct(
-        allocator(), p, std::forward<Args>(args)...);
+        storage_.GetAllocator(), p, std::forward<Args>(args)...);
     return *p;
   }
 
@@ -925,7 +899,8 @@
   // Destroy [`from`, `to`) in place.
   void Destroy(pointer from, pointer to) {
     for (pointer cur = from; cur != to; ++cur) {
-      std::allocator_traits<allocator_type>::destroy(allocator(), cur);
+      std::allocator_traits<allocator_type>::destroy(storage_.GetAllocator(),
+                                                     cur);
     }
 #if !defined(NDEBUG)
     // Overwrite unused memory with `0xab` so we can catch uninitialized usage.
@@ -945,7 +920,7 @@
     const size_type s = size();
     assert(s <= capacity());
 
-    size_type target = (std::max)(N, s + delta);
+    size_type target = (std::max)(static_cast<size_type>(N), s + delta);
 
     // Compute new capacity by repeatedly doubling current capacity
     // TODO(psrc): Check and avoid overflow?
@@ -954,13 +929,13 @@
       new_capacity <<= 1;
     }
 
-    Allocation new_allocation(allocator(), new_capacity);
+    pointer new_data =
+        AllocatorTraits::allocate(storage_.GetAllocator(), new_capacity);
 
     UninitializedCopy(std::make_move_iterator(data()),
-                      std::make_move_iterator(data() + s),
-                      new_allocation.buffer());
+                      std::make_move_iterator(data() + s), new_data);
 
-    ResetAllocation(new_allocation, s);
+    ResetAllocation(new_data, new_capacity, s);
   }
 
   // Shift all elements from `position` to `end()` by `n` places to the right.
@@ -986,15 +961,15 @@
       }
       // Move everyone into the new allocation, leaving a gap of `n` for the
       // requested shift.
-      Allocation new_allocation(allocator(), new_capacity);
+      pointer new_data =
+          AllocatorTraits::allocate(storage_.GetAllocator(), new_capacity);
       size_type index = position - begin();
       UninitializedCopy(std::make_move_iterator(data()),
-                        std::make_move_iterator(data() + index),
-                        new_allocation.buffer());
+                        std::make_move_iterator(data() + index), new_data);
       UninitializedCopy(std::make_move_iterator(data() + index),
                         std::make_move_iterator(data() + s),
-                        new_allocation.buffer() + index + n);
-      ResetAllocation(new_allocation, s);
+                        new_data + index + n);
+      ResetAllocation(new_data, new_capacity, s);
 
       // New allocation means our iterator is invalid, so we'll recalculate.
       // Since the entire gap is in new space, there's no used space to reuse.
@@ -1025,7 +1000,7 @@
       start_used = pos;
       start_raw = pos + new_elements_in_used_space;
     }
-    tag().add_size(n);
+    storage_.AddSize(n);
     return std::make_pair(start_used, start_raw);
   }
 
@@ -1034,46 +1009,55 @@
     assert(size() == capacity());
     const size_type s = size();
 
-    Allocation new_allocation(allocator(), 2 * capacity());
+    size_type new_capacity = 2 * capacity();
+    pointer new_data =
+        AllocatorTraits::allocate(storage_.GetAllocator(), new_capacity);
 
     reference new_element =
-        Construct(new_allocation.buffer() + s, std::forward<Args>(args)...);
+        Construct(new_data + s, std::forward<Args>(args)...);
     UninitializedCopy(std::make_move_iterator(data()),
-                      std::make_move_iterator(data() + s),
-                      new_allocation.buffer());
+                      std::make_move_iterator(data() + s), new_data);
 
-    ResetAllocation(new_allocation, s + 1);
+    ResetAllocation(new_data, new_capacity, s + 1);
 
     return new_element;
   }
 
   void InitAssign(size_type n) {
-    if (n > N) {
-      Allocation new_allocation(allocator(), n);
-      init_allocation(new_allocation);
-      UninitializedFill(allocated_space(), allocated_space() + n);
-      tag().set_allocated_size(n);
+    if (n > static_cast<size_type>(N)) {
+      pointer new_data = AllocatorTraits::allocate(storage_.GetAllocator(), n);
+      storage_.SetAllocatedData(new_data);
+      storage_.SetAllocatedCapacity(n);
+      UninitializedFill(storage_.GetAllocatedData(),
+                        storage_.GetAllocatedData() + n);
+      storage_.SetAllocatedSize(n);
     } else {
-      UninitializedFill(inlined_space(), inlined_space() + n);
-      tag().set_inline_size(n);
+      UninitializedFill(storage_.GetInlinedData(),
+                        storage_.GetInlinedData() + n);
+      storage_.SetInlinedSize(n);
     }
   }
 
   void InitAssign(size_type n, const_reference v) {
-    if (n > N) {
-      Allocation new_allocation(allocator(), n);
-      init_allocation(new_allocation);
-      UninitializedFill(allocated_space(), allocated_space() + n, v);
-      tag().set_allocated_size(n);
+    if (n > static_cast<size_type>(N)) {
+      pointer new_data = AllocatorTraits::allocate(storage_.GetAllocator(), n);
+      storage_.SetAllocatedData(new_data);
+      storage_.SetAllocatedCapacity(n);
+      UninitializedFill(storage_.GetAllocatedData(),
+                        storage_.GetAllocatedData() + n, v);
+      storage_.SetAllocatedSize(n);
     } else {
-      UninitializedFill(inlined_space(), inlined_space() + n, v);
-      tag().set_inline_size(n);
+      UninitializedFill(storage_.GetInlinedData(),
+                        storage_.GetInlinedData() + n, v);
+      storage_.SetInlinedSize(n);
     }
   }
 
   template <typename ForwardIt>
   void AssignForwardRange(ForwardIt first, ForwardIt last) {
-    static_assert(IsAtLeastForwardIterator<ForwardIt>::value, "");
+    static_assert(absl::inlined_vector_internal::IsAtLeastForwardIterator<
+                      ForwardIt>::value,
+                  "");
 
     auto length = std::distance(first, last);
 
@@ -1086,27 +1070,29 @@
     reserve(length);
     iterator out = begin();
     for (; out != end(); ++first, ++out) *out = *first;
-    if (allocated()) {
+    if (storage_.GetIsAllocated()) {
       UninitializedCopy(first, last, out);
-      tag().set_allocated_size(length);
+      storage_.SetAllocatedSize(length);
     } else {
       UninitializedCopy(first, last, out);
-      tag().set_inline_size(length);
+      storage_.SetInlinedSize(length);
     }
   }
 
   template <typename ForwardIt>
   void AppendForwardRange(ForwardIt first, ForwardIt last) {
-    static_assert(IsAtLeastForwardIterator<ForwardIt>::value, "");
+    static_assert(absl::inlined_vector_internal::IsAtLeastForwardIterator<
+                      ForwardIt>::value,
+                  "");
 
     auto length = std::distance(first, last);
     reserve(size() + length);
-    if (allocated()) {
-      UninitializedCopy(first, last, allocated_space() + size());
-      tag().set_allocated_size(size() + length);
+    if (storage_.GetIsAllocated()) {
+      UninitializedCopy(first, last, storage_.GetAllocatedData() + size());
+      storage_.SetAllocatedSize(size() + length);
     } else {
-      UninitializedCopy(first, last, inlined_space() + size());
-      tag().set_inline_size(size() + length);
+      UninitializedCopy(first, last, storage_.GetInlinedData() + size());
+      storage_.SetInlinedSize(size() + length);
     }
   }
 
@@ -1126,7 +1112,9 @@
   template <typename ForwardIt>
   iterator InsertWithForwardRange(const_iterator position, ForwardIt first,
                                   ForwardIt last) {
-    static_assert(IsAtLeastForwardIterator<ForwardIt>::value, "");
+    static_assert(absl::inlined_vector_internal::IsAtLeastForwardIterator<
+                      ForwardIt>::value,
+                  "");
     assert(position >= begin() && position <= end());
 
     if (ABSL_PREDICT_FALSE(first == last))
@@ -1142,19 +1130,24 @@
   }
 
   void SwapImpl(InlinedVector& other) {
-    using std::swap;  // Augment ADL with `std::swap`.
+    using std::swap;
 
-    if (allocated() && other.allocated()) {
+    bool is_allocated = storage_.GetIsAllocated();
+    bool other_is_allocated = other.storage_.GetIsAllocated();
+
+    if (is_allocated && other_is_allocated) {
       // Both out of line, so just swap the tag, allocation, and allocator.
-      swap(tag(), other.tag());
-      swap(allocation(), other.allocation());
-      swap(allocator(), other.allocator());
+      storage_.SwapSizeAndIsAllocated(std::addressof(other.storage_));
+      storage_.SwapAllocatedSizeAndCapacity(std::addressof(other.storage_));
+      swap(storage_.GetAllocator(), other.storage_.GetAllocator());
+
       return;
     }
-    if (!allocated() && !other.allocated()) {
+
+    if (!is_allocated && !other_is_allocated) {
       // Both inlined: swap up to smaller size, then move remaining elements.
       InlinedVector* a = this;
-      InlinedVector* b = &other;
+      InlinedVector* b = std::addressof(other);
       if (size() < other.size()) {
         swap(a, b);
       }
@@ -1163,18 +1156,21 @@
       const size_type b_size = b->size();
       assert(a_size >= b_size);
       // `a` is larger. Swap the elements up to the smaller array size.
-      std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size,
-                       b->inlined_space());
+      std::swap_ranges(a->storage_.GetInlinedData(),
+                       a->storage_.GetInlinedData() + b_size,
+                       b->storage_.GetInlinedData());
 
       // Move the remaining elements:
       //   [`b_size`, `a_size`) from `a` -> [`b_size`, `a_size`) from `b`
-      b->UninitializedCopy(a->inlined_space() + b_size,
-                           a->inlined_space() + a_size,
-                           b->inlined_space() + b_size);
-      a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size);
+      b->UninitializedCopy(a->storage_.GetInlinedData() + b_size,
+                           a->storage_.GetInlinedData() + a_size,
+                           b->storage_.GetInlinedData() + b_size);
+      a->Destroy(a->storage_.GetInlinedData() + b_size,
+                 a->storage_.GetInlinedData() + a_size);
 
-      swap(a->tag(), b->tag());
-      swap(a->allocator(), b->allocator());
+      storage_.SwapSizeAndIsAllocated(std::addressof(other.storage_));
+      swap(storage_.GetAllocator(), other.storage_.GetAllocator());
+
       assert(b->size() == a_size);
       assert(a->size() == b_size);
       return;
@@ -1186,32 +1182,37 @@
     // pointer/capacity into the originally inlined vector and swap
     // the tags.
     InlinedVector* a = this;
-    InlinedVector* b = &other;
-    if (a->allocated()) {
+    InlinedVector* b = std::addressof(other);
+    if (a->storage_.GetIsAllocated()) {
       swap(a, b);
     }
-    assert(!a->allocated());
-    assert(b->allocated());
+
+    assert(!a->storage_.GetIsAllocated());
+    assert(b->storage_.GetIsAllocated());
+
     const size_type a_size = a->size();
     const size_type b_size = b->size();
     // In an optimized build, `b_size` would be unused.
     static_cast<void>(b_size);
 
-    // Made Local copies of `size()`, don't need `tag()` accurate anymore
-    swap(a->tag(), b->tag());
+    // Made Local copies of `size()`, these can now be swapped
+    a->storage_.SwapSizeAndIsAllocated(std::addressof(b->storage_));
 
-    // Copy `b_allocation` out before `b`'s union gets clobbered by
-    // `inline_space`
-    Allocation b_allocation = b->allocation();
+    // Copy out before `b`'s union gets clobbered by `inline_space`
+    pointer b_data = b->storage_.GetAllocatedData();
+    size_type b_capacity = b->storage_.GetAllocatedCapacity();
 
-    b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size,
-                         b->inlined_space());
-    a->Destroy(a->inlined_space(), a->inlined_space() + a_size);
+    b->UninitializedCopy(a->storage_.GetInlinedData(),
+                         a->storage_.GetInlinedData() + a_size,
+                         b->storage_.GetInlinedData());
+    a->Destroy(a->storage_.GetInlinedData(),
+               a->storage_.GetInlinedData() + a_size);
 
-    a->allocation() = b_allocation;
+    a->storage_.SetAllocatedData(b_data);
+    a->storage_.SetAllocatedCapacity(b_capacity);
 
-    if (a->allocator() != b->allocator()) {
-      swap(a->allocator(), b->allocator());
+    if (a->storage_.GetAllocator() != b->storage_.GetAllocator()) {
+      swap(a->storage_.GetAllocator(), b->storage_.GetAllocator());
     }
 
     assert(b->size() == a_size);
@@ -1230,8 +1231,8 @@
 // Swaps the contents of two inlined vectors. This convenience function
 // simply calls `InlinedVector::swap()`.
 template <typename T, size_t N, typename A>
-auto swap(InlinedVector<T, N, A>& a,
-          InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) -> void {
+void swap(absl::InlinedVector<T, N, A>& a,
+          absl::InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) {
   a.swap(b);
 }
 
@@ -1239,17 +1240,21 @@
 //
 // Tests the equivalency of the contents of two inlined vectors.
 template <typename T, size_t N, typename A>
-auto operator==(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
-  return absl::equal(a.begin(), a.end(), b.begin(), b.end());
+bool operator==(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
+  auto a_data = a.data();
+  auto a_size = a.size();
+  auto b_data = b.data();
+  auto b_size = b.size();
+  return absl::equal(a_data, a_data + a_size, b_data, b_data + b_size);
 }
 
 // `operator!=()`
 //
 // Tests the inequality of the contents of two inlined vectors.
 template <typename T, size_t N, typename A>
-auto operator!=(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
+bool operator!=(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
   return !(a == b);
 }
 
@@ -1258,9 +1263,14 @@
 // Tests whether the contents of one inlined vector are less than the contents
 // of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator<(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b)
-    -> bool {
-  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
+bool operator<(const absl::InlinedVector<T, N, A>& a,
+               const absl::InlinedVector<T, N, A>& b) {
+  auto a_data = a.data();
+  auto a_size = a.size();
+  auto b_data = b.data();
+  auto b_size = b.size();
+  return std::lexicographical_compare(a_data, a_data + a_size, b_data,
+                                      b_data + b_size);
 }
 
 // `operator>()`
@@ -1268,8 +1278,8 @@
 // Tests whether the contents of one inlined vector are greater than the
 // contents of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator>(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b)
-    -> bool {
+bool operator>(const absl::InlinedVector<T, N, A>& a,
+               const absl::InlinedVector<T, N, A>& b) {
   return b < a;
 }
 
@@ -1278,8 +1288,8 @@
 // Tests whether the contents of one inlined vector are less than or equal to
 // the contents of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator<=(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
+bool operator<=(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
   return !(b < a);
 }
 
@@ -1288,27 +1298,23 @@
 // Tests whether the contents of one inlined vector are greater than or equal to
 // the contents of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator>=(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
+bool operator>=(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
   return !(a < b);
 }
 
-// AbslHashValue()
+// `AbslHashValue()`
 //
-// Provides `absl::Hash` support for inlined vectors. You do not normally call
-// this function directly.
+// Provides `absl::Hash` support for `absl::InlinedVector`. You do not normally
+// call this function directly.
 template <typename H, typename TheT, size_t TheN, typename TheA>
-auto AbslHashValue(H h, const InlinedVector<TheT, TheN, TheA>& v) -> H {
-  auto p = v.data();
-  auto n = v.size();
-  return H::combine(H::combine_contiguous(std::move(h), p, n), n);
+H AbslHashValue(H h, const absl::InlinedVector<TheT, TheN, TheA>& a) {
+  auto a_data = a.data();
+  auto a_size = a.size();
+  return H::combine(H::combine_contiguous(std::move(h), a_data, a_size),
+                    a_size);
 }
-}  // namespace absl
 
-// -----------------------------------------------------------------------------
-// Implementation of InlinedVector
-//
-// Do not depend on any below implementation details!
-// -----------------------------------------------------------------------------
+}  // namespace absl
 
 #endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h
index b9bd91a..bb3471f 100644
--- a/absl/container/internal/compressed_tuple.h
+++ b/absl/container/internal/compressed_tuple.h
@@ -38,13 +38,13 @@
 
 #include "absl/utility/utility.h"
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__NVCC__)
 // We need to mark these classes with this declspec to ensure that
 // CompressedTuple happens.
 #define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases)
-#else  // _MSC_VER
+#else
 #define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
-#endif  // _MSC_VER
+#endif
 
 namespace absl {
 namespace container_internal {
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h
index 24059d9..b8b4f4c 100644
--- a/absl/container/internal/inlined_vector.h
+++ b/absl/container/internal/inlined_vector.h
@@ -18,12 +18,19 @@
 #include <cstddef>
 #include <iterator>
 #include <memory>
+#include <utility>
 
+#include "absl/container/internal/compressed_tuple.h"
 #include "absl/meta/type_traits.h"
 
 namespace absl {
 namespace inlined_vector_internal {
 
+template <typename Iterator>
+using IsAtLeastForwardIterator = std::is_convertible<
+    typename std::iterator_traits<Iterator>::iterator_category,
+    std::forward_iterator_tag>;
+
 template <typename InlinedVector>
 class Storage;
 
@@ -44,80 +51,93 @@
   using const_iterator = const_pointer;
   using reverse_iterator = std::reverse_iterator<iterator>;
   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+  using AllocatorTraits = std::allocator_traits<allocator_type>;
 
-  explicit Storage(const allocator_type& a) : allocator_and_tag_(a) {}
+  explicit Storage(const allocator_type& alloc)
+      : metadata_(alloc, /* empty and inlined */ 0) {}
 
-  // TODO(johnsoncj): Make the below types and members private after migration
+  size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; }
 
-  // Holds whether the vector is allocated or not in the lowest bit and the size
-  // in the high bits:
-  //   `size_ = (size << 1) | is_allocated;`
-  class Tag {
-    size_type size_;
+  bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; }
 
-   public:
-    Tag() : size_(0) {}
-    size_type size() const { return size_ / 2; }
-    void add_size(size_type n) { size_ += n * 2; }
-    void set_inline_size(size_type n) { size_ = n * 2; }
-    void set_allocated_size(size_type n) { size_ = (n * 2) + 1; }
-    bool allocated() const { return size_ % 2; }
+  pointer GetInlinedData() {
+    return reinterpret_cast<pointer>(
+        std::addressof(data_.inlined.inlined_data[0]));
+  }
+
+  const_pointer GetInlinedData() const {
+    return reinterpret_cast<const_pointer>(
+        std::addressof(data_.inlined.inlined_data[0]));
+  }
+
+  pointer GetAllocatedData() { return data_.allocated.allocated_data; }
+
+  const_pointer GetAllocatedData() const {
+    return data_.allocated.allocated_data;
+  }
+
+  size_type GetAllocatedCapacity() const {
+    return data_.allocated.allocated_capacity;
+  }
+
+  allocator_type& GetAllocator() { return metadata_.template get<0>(); }
+
+  const allocator_type& GetAllocator() const {
+    return metadata_.template get<0>();
+  }
+
+  void SetAllocatedSize(size_type size) {
+    GetSizeAndIsAllocated() = (size << 1) | static_cast<size_type>(1);
+  }
+
+  void SetInlinedSize(size_type size) { GetSizeAndIsAllocated() = size << 1; }
+
+  void AddSize(size_type count) { GetSizeAndIsAllocated() += count << 1; }
+
+  void SetAllocatedData(pointer data) { data_.allocated.allocated_data = data; }
+
+  void SetAllocatedCapacity(size_type capacity) {
+    data_.allocated.allocated_capacity = capacity;
+  }
+
+  void SwapSizeAndIsAllocated(Storage* other) {
+    using std::swap;
+    swap(GetSizeAndIsAllocated(), other->GetSizeAndIsAllocated());
+  }
+
+  void SwapAllocatedSizeAndCapacity(Storage* other) {
+    using std::swap;
+    swap(data_.allocated, other->data_.allocated);
+  }
+
+ private:
+  size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); }
+
+  const size_type& GetSizeAndIsAllocated() const {
+    return metadata_.template get<1>();
+  }
+
+  using Metadata =
+      container_internal::CompressedTuple<allocator_type, size_type>;
+
+  struct Allocated {
+    pointer allocated_data;
+    size_type allocated_capacity;
   };
 
-  // Derives from `allocator_type` to use the empty base class optimization.
-  // If the `allocator_type` is stateless, we can store our instance for free.
-  class AllocatorAndTag : private allocator_type {
-    Tag tag_;
-
-   public:
-    explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {}
-    Tag& tag() { return tag_; }
-    const Tag& tag() const { return tag_; }
-    allocator_type& allocator() { return *this; }
-    const allocator_type& allocator() const { return *this; }
-  };
-
-  class Allocation {
-    size_type capacity_;
-    pointer buffer_;
-
-   public:
-    Allocation(allocator_type& a, size_type capacity)
-        : capacity_(capacity), buffer_(Create(a, capacity)) {}
-    void Dealloc(allocator_type& a) {
-      std::allocator_traits<allocator_type>::deallocate(a, buffer_, capacity_);
-    }
-    size_type capacity() const { return capacity_; }
-    const_pointer buffer() const { return buffer_; }
-    pointer buffer() { return buffer_; }
-    static pointer Create(allocator_type& a, size_type n) {
-      return std::allocator_traits<allocator_type>::allocate(a, n);
-    }
-  };
-
-  // Stores either the inlined or allocated representation
-  union Rep {
-    using ValueTypeBuffer =
+  struct Inlined {
+    using InlinedDataElement =
         absl::aligned_storage_t<sizeof(value_type), alignof(value_type)>;
-    using AllocationBuffer =
-        absl::aligned_storage_t<sizeof(Allocation), alignof(Allocation)>;
-
-    // Structs wrap the buffers to perform indirection that solves a bizarre
-    // compilation error on Visual Studio (all known versions).
-    struct InlinedRep {
-      ValueTypeBuffer inlined[N];
-    };
-
-    struct AllocatedRep {
-      AllocationBuffer allocation;
-    };
-
-    InlinedRep inlined_storage;
-    AllocatedRep allocation_storage;
+    InlinedDataElement inlined_data[N];
   };
 
-  AllocatorAndTag allocator_and_tag_;
-  Rep rep_;
+  union Data {
+    Allocated allocated;
+    Inlined inlined;
+  };
+
+  Metadata metadata_;
+  Data data_;
 };
 
 }  // namespace inlined_vector_internal
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 85e3334..8ac0dda 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1437,7 +1437,18 @@
 
   void initialize_slots() {
     assert(capacity_);
-    if (slots_ == nullptr) {
+    // Folks with custom allocators often make unwarranted assumptions about the
+    // behavior of their classes vis-a-vis trivial destructability and what
+    // calls they will or wont make.  Avoid sampling for people with custom
+    // allocators to get us out of this mess.  This is not a hard guarantee but
+    // a workaround while we plan the exact guarantee we want to provide.
+    //
+    // People are often sloppy with the exact type of their allocator (sometimes
+    // it has an extra const or is missing the pair, but rebinds made it work
+    // anyway).  To avoid the ambiguity, we work off SlotAlloc which we have
+    // bound more carefully.
+    if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value &&
+        slots_ == nullptr) {
       infoz_ = Sample();
     }
 
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 02fd0bf..ed4ca8c 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -343,7 +343,25 @@
     : raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
                    std::equal_to<int64_t>, std::allocator<int64_t>> {
   using Base = typename IntTable::raw_hash_set;
-  IntTable() {}
+  using Base::Base;
+};
+
+template <typename T>
+struct CustomAlloc : std::allocator<T> {
+  CustomAlloc() {}
+
+  template <typename U>
+  CustomAlloc(const CustomAlloc<U>& other) {}
+
+  template<class U> struct rebind {
+    using other = CustomAlloc<U>;
+  };
+};
+
+struct CustomAllocIntTable
+    : raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
+                   std::equal_to<int64_t>, CustomAlloc<int64_t>> {
+  using Base = typename CustomAllocIntTable::raw_hash_set;
   using Base::Base;
 };
 
@@ -414,10 +432,11 @@
   t.prefetch(2);
 
   // Do not run in debug mode, when prefetch is not implemented, or when
-  // sanitizers are enabled.
-#if defined(NDEBUG) && defined(__GNUC__) && !defined(ADDRESS_SANITIZER) && \
-    !defined(MEMORY_SANITIZER) && !defined(THREAD_SANITIZER) &&            \
-    !defined(UNDEFINED_BEHAVIOR_SANITIZER)
+  // sanitizers are enabled, or on WebAssembly.
+#if defined(NDEBUG) && defined(__GNUC__) && defined(__x86_64__) &&          \
+    !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) &&            \
+    !defined(THREAD_SANITIZER) && !defined(UNDEFINED_BEHAVIOR_SANITIZER) && \
+    !defined(__EMSCRIPTEN__)
   const auto now = [] { return absl::base_internal::CycleClock::Now(); };
 
   // Make size enough to not fit in L2 cache (16.7 Mb)
@@ -1062,7 +1081,7 @@
 
 ExpectedStats XorSeedExpectedStats() {
   constexpr bool kRandomizesInserts =
-#if NDEBUG
+#ifdef NDEBUG
       false;
 #else   // NDEBUG
       true;
@@ -1156,7 +1175,7 @@
 
 ExpectedStats LinearTransformExpectedStats() {
   constexpr bool kRandomizesInserts =
-#if NDEBUG
+#ifdef NDEBUG
       false;
 #else   // NDEBUG
       true;
@@ -1346,37 +1365,31 @@
 
 TEST(Table, CopyConstruct) {
   IntTable t;
-  t.max_load_factor(.321f);
   t.emplace(0);
   EXPECT_EQ(1, t.size());
   {
     IntTable u(t);
     EXPECT_EQ(1, u.size());
-    EXPECT_EQ(t.max_load_factor(), u.max_load_factor());
     EXPECT_THAT(*u.find(0), 0);
   }
   {
     IntTable u{t};
     EXPECT_EQ(1, u.size());
-    EXPECT_EQ(t.max_load_factor(), u.max_load_factor());
     EXPECT_THAT(*u.find(0), 0);
   }
   {
     IntTable u = t;
     EXPECT_EQ(1, u.size());
-    EXPECT_EQ(t.max_load_factor(), u.max_load_factor());
     EXPECT_THAT(*u.find(0), 0);
   }
 }
 
 TEST(Table, CopyConstructWithAlloc) {
   StringTable t;
-  t.max_load_factor(.321f);
   t.emplace("a", "b");
   EXPECT_EQ(1, t.size());
   StringTable u(t, Alloc<std::pair<std::string, std::string>>());
   EXPECT_EQ(1, u.size());
-  EXPECT_EQ(t.max_load_factor(), u.max_load_factor());
   EXPECT_THAT(*u.find("a"), Pair("a", "b"));
 }
 
@@ -1394,88 +1407,68 @@
 TEST(Table, MoveConstruct) {
   {
     StringTable t;
-    t.max_load_factor(.321f);
-    const float lf = t.max_load_factor();
     t.emplace("a", "b");
     EXPECT_EQ(1, t.size());
 
     StringTable u(std::move(t));
     EXPECT_EQ(1, u.size());
-    EXPECT_EQ(lf, u.max_load_factor());
     EXPECT_THAT(*u.find("a"), Pair("a", "b"));
   }
   {
     StringTable t;
-    t.max_load_factor(.321f);
-    const float lf = t.max_load_factor();
     t.emplace("a", "b");
     EXPECT_EQ(1, t.size());
 
     StringTable u{std::move(t)};
     EXPECT_EQ(1, u.size());
-    EXPECT_EQ(lf, u.max_load_factor());
     EXPECT_THAT(*u.find("a"), Pair("a", "b"));
   }
   {
     StringTable t;
-    t.max_load_factor(.321f);
-    const float lf = t.max_load_factor();
     t.emplace("a", "b");
     EXPECT_EQ(1, t.size());
 
     StringTable u = std::move(t);
     EXPECT_EQ(1, u.size());
-    EXPECT_EQ(lf, u.max_load_factor());
     EXPECT_THAT(*u.find("a"), Pair("a", "b"));
   }
 }
 
 TEST(Table, MoveConstructWithAlloc) {
   StringTable t;
-  t.max_load_factor(.321f);
-  const float lf = t.max_load_factor();
   t.emplace("a", "b");
   EXPECT_EQ(1, t.size());
   StringTable u(std::move(t), Alloc<std::pair<std::string, std::string>>());
   EXPECT_EQ(1, u.size());
-  EXPECT_EQ(lf, u.max_load_factor());
   EXPECT_THAT(*u.find("a"), Pair("a", "b"));
 }
 
 TEST(Table, CopyAssign) {
   StringTable t;
-  t.max_load_factor(.321f);
   t.emplace("a", "b");
   EXPECT_EQ(1, t.size());
   StringTable u;
   u = t;
   EXPECT_EQ(1, u.size());
-  EXPECT_EQ(t.max_load_factor(), u.max_load_factor());
   EXPECT_THAT(*u.find("a"), Pair("a", "b"));
 }
 
 TEST(Table, CopySelfAssign) {
   StringTable t;
-  t.max_load_factor(.321f);
-  const float lf = t.max_load_factor();
   t.emplace("a", "b");
   EXPECT_EQ(1, t.size());
   t = *&t;
   EXPECT_EQ(1, t.size());
-  EXPECT_EQ(lf, t.max_load_factor());
   EXPECT_THAT(*t.find("a"), Pair("a", "b"));
 }
 
 TEST(Table, MoveAssign) {
   StringTable t;
-  t.max_load_factor(.321f);
-  const float lf = t.max_load_factor();
   t.emplace("a", "b");
   EXPECT_EQ(1, t.size());
   StringTable u;
   u = std::move(t);
   EXPECT_EQ(1, u.size());
-  EXPECT_EQ(lf, u.max_load_factor());
   EXPECT_THAT(*u.find("a"), Pair("a", "b"));
 }
 
@@ -1785,7 +1778,7 @@
 
     std::vector<IntTable> tables;
     bool found_difference = false;
-    for (int i = 0; !found_difference && i < 500; ++i) {
+    for (int i = 0; !found_difference && i < 5000; ++i) {
       tables.push_back(MakeSimpleTable(size));
       found_difference = OrderOfIteration(tables.back()) != reference;
     }
@@ -1799,7 +1792,7 @@
 
 TEST(Table, IterationOrderChangesOnRehash) {
   std::vector<IntTable> garbage;
-  for (int i = 0; i < 500; ++i) {
+  for (int i = 0; i < 5000; ++i) {
     auto t = MakeSimpleTable(20);
     const auto reference = OrderOfIteration(t);
     // Force rehash to the same size.
@@ -1869,6 +1862,27 @@
               0.01, 0.005);
 }
 
+TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
+  // Enable the feature even if the prod default is off.
+  SetHashtablezEnabled(true);
+  SetHashtablezSampleParameter(100);
+
+  auto& sampler = HashtablezSampler::Global();
+  size_t start_size = 0;
+  start_size += sampler.Iterate([&](const HashtablezInfo&) { ++start_size; });
+
+  std::vector<CustomAllocIntTable> tables;
+  for (int i = 0; i < 1000000; ++i) {
+    tables.emplace_back();
+    tables.back().insert(1);
+  }
+  size_t end_size = 0;
+  end_size += sampler.Iterate([&](const HashtablezInfo&) { ++end_size; });
+
+  EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
+              0.00, 0.001);
+}
+
 #ifdef ADDRESS_SANITIZER
 TEST(Sanitizer, PoisoningUnused) {
   IntTable t;
diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake
index 5084958..eaef30b 100644
--- a/absl/copts/AbseilConfigureCopts.cmake
+++ b/absl/copts/AbseilConfigureCopts.cmake
@@ -3,23 +3,25 @@
 
 set(ABSL_LSAN_LINKOPTS "")
 set(ABSL_HAVE_LSAN OFF)
+set(ABSL_DEFAULT_LINKOPTS "")
 
-if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
   set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}")
   set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}")
   set(ABSL_EXCEPTIONS_FLAG "${ABSL_GCC_EXCEPTIONS_FLAGS}")
 elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
   # MATCHES so we get both Clang and AppleClang
-  if (MSVC)
+  if(MSVC)
     # clang-cl is half MSVC, half LLVM
     set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}")
     set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}")
     set(ABSL_EXCEPTIONS_FLAG "${ABSL_CLANG_CL_EXCEPTIONS_FLAGS}")
+    set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
   else()
     set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}")
     set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}")
     set(ABSL_EXCEPTIONS_FLAG "${ABSL_LLVM_EXCEPTIONS_FLAGS}")
-    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
       # AppleClang doesn't have lsan
       # https://developer.apple.com/documentation/code_diagnostics
       if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.5)
@@ -32,6 +34,7 @@
   set(ABSL_DEFAULT_COPTS "${ABSL_MSVC_FLAGS}")
   set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}")
   set(ABSL_EXCEPTIONS_FLAG "${ABSL_MSVC_EXCEPTIONS_FLAGS}")
+  set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
 else()
   message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}.  Building with no default flags")
   set(ABSL_DEFAULT_COPTS "")
diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake
index 9031bfa..27e6f5a 100644
--- a/absl/copts/GENERATED_AbseilCopts.cmake
+++ b/absl/copts/GENERATED_AbseilCopts.cmake
@@ -37,7 +37,6 @@
     "-Wno-shorten-64-to-32"
     "-Wno-switch-enum"
     "-Wno-thread-safety-negative"
-    "-Wno-undef"
     "-Wno-unknown-warning-option"
     "-Wno-unreachable-code"
     "-Wno-unused-macros"
@@ -62,6 +61,7 @@
 
 list(APPEND ABSL_CLANG_CL_TEST_FLAGS
     "-Wno-c99-extensions"
+    "-Wno-deprecated-declarations"
     "-Wno-missing-noreturn"
     "-Wno-missing-prototypes"
     "-Wno-missing-variable-declarations"
@@ -76,6 +76,7 @@
     "-Wno-unused-template"
     "-Wno-used-but-marked-unused"
     "-Wno-zero-as-null-pointer-constant"
+    "-Wno-gnu-include-next"
     "-Wno-gnu-zero-variadic-macro-arguments"
 )
 
@@ -102,6 +103,7 @@
 
 list(APPEND ABSL_GCC_TEST_FLAGS
     "-Wno-conversion-null"
+    "-Wno-deprecated-declarations"
     "-Wno-missing-declarations"
     "-Wno-sign-compare"
     "-Wno-unused-function"
@@ -143,7 +145,6 @@
     "-Wno-shorten-64-to-32"
     "-Wno-switch-enum"
     "-Wno-thread-safety-negative"
-    "-Wno-undef"
     "-Wno-unknown-warning-option"
     "-Wno-unreachable-code"
     "-Wno-unused-macros"
@@ -163,6 +164,7 @@
 
 list(APPEND ABSL_LLVM_TEST_FLAGS
     "-Wno-c99-extensions"
+    "-Wno-deprecated-declarations"
     "-Wno-missing-noreturn"
     "-Wno-missing-prototypes"
     "-Wno-missing-variable-declarations"
@@ -177,6 +179,7 @@
     "-Wno-unused-template"
     "-Wno-used-but-marked-unused"
     "-Wno-zero-as-null-pointer-constant"
+    "-Wno-gnu-include-next"
     "-Wno-gnu-zero-variadic-macro-arguments"
 )
 
@@ -201,8 +204,14 @@
     "/wd4800"
 )
 
+list(APPEND ABSL_MSVC_LINKOPTS
+    "-ignore:4221"
+)
+
 list(APPEND ABSL_MSVC_TEST_FLAGS
     "/wd4018"
     "/wd4101"
     "/wd4503"
+    "/wd4996"
+    "/DNOMINMAX"
 )
diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl
index e05a58e..0feb0f4 100644
--- a/absl/copts/GENERATED_copts.bzl
+++ b/absl/copts/GENERATED_copts.bzl
@@ -38,7 +38,6 @@
     "-Wno-shorten-64-to-32",
     "-Wno-switch-enum",
     "-Wno-thread-safety-negative",
-    "-Wno-undef",
     "-Wno-unknown-warning-option",
     "-Wno-unreachable-code",
     "-Wno-unused-macros",
@@ -63,6 +62,7 @@
 
 ABSL_CLANG_CL_TEST_FLAGS = [
     "-Wno-c99-extensions",
+    "-Wno-deprecated-declarations",
     "-Wno-missing-noreturn",
     "-Wno-missing-prototypes",
     "-Wno-missing-variable-declarations",
@@ -77,6 +77,7 @@
     "-Wno-unused-template",
     "-Wno-used-but-marked-unused",
     "-Wno-zero-as-null-pointer-constant",
+    "-Wno-gnu-include-next",
     "-Wno-gnu-zero-variadic-macro-arguments",
 ]
 
@@ -103,6 +104,7 @@
 
 ABSL_GCC_TEST_FLAGS = [
     "-Wno-conversion-null",
+    "-Wno-deprecated-declarations",
     "-Wno-missing-declarations",
     "-Wno-sign-compare",
     "-Wno-unused-function",
@@ -144,7 +146,6 @@
     "-Wno-shorten-64-to-32",
     "-Wno-switch-enum",
     "-Wno-thread-safety-negative",
-    "-Wno-undef",
     "-Wno-unknown-warning-option",
     "-Wno-unreachable-code",
     "-Wno-unused-macros",
@@ -164,6 +165,7 @@
 
 ABSL_LLVM_TEST_FLAGS = [
     "-Wno-c99-extensions",
+    "-Wno-deprecated-declarations",
     "-Wno-missing-noreturn",
     "-Wno-missing-prototypes",
     "-Wno-missing-variable-declarations",
@@ -178,6 +180,7 @@
     "-Wno-unused-template",
     "-Wno-used-but-marked-unused",
     "-Wno-zero-as-null-pointer-constant",
+    "-Wno-gnu-include-next",
     "-Wno-gnu-zero-variadic-macro-arguments",
 ]
 
@@ -202,8 +205,14 @@
     "/wd4800",
 ]
 
+ABSL_MSVC_LINKOPTS = [
+    "-ignore:4221",
+]
+
 ABSL_MSVC_TEST_FLAGS = [
     "/wd4018",
     "/wd4101",
     "/wd4503",
+    "/wd4996",
+    "/DNOMINMAX",
 ]
diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl
index 1655add..0015931 100644
--- a/absl/copts/configure_copts.bzl
+++ b/absl/copts/configure_copts.bzl
@@ -14,6 +14,7 @@
     "ABSL_LLVM_TEST_FLAGS",
     "ABSL_MSVC_EXCEPTIONS_FLAGS",
     "ABSL_MSVC_FLAGS",
+    "ABSL_MSVC_LINKOPTS",
     "ABSL_MSVC_TEST_FLAGS",
 )
 
@@ -40,3 +41,8 @@
 ABSL_EXCEPTIONS_FLAG_LINKOPTS = select({
     "//conditions:default": [],
 })
+
+ABSL_DEFAULT_LINKOPTS = select({
+    "//absl:windows": ABSL_MSVC_LINKOPTS,
+    "//conditions:default": [],
+})
diff --git a/absl/copts/copts.py b/absl/copts/copts.py
index 3c9d429..154c0ce 100644
--- a/absl/copts/copts.py
+++ b/absl/copts/copts.py
@@ -65,7 +65,6 @@
     "-Wno-shorten-64-to-32",
     "-Wno-switch-enum",
     "-Wno-thread-safety-negative",
-    "-Wno-undef",
     "-Wno-unknown-warning-option",
     "-Wno-unreachable-code",
     # Causes warnings on include guards
@@ -89,6 +88,7 @@
 
 LLVM_TEST_DISABLE_WARNINGS_FLAGS = [
     "-Wno-c99-extensions",
+    "-Wno-deprecated-declarations",
     "-Wno-missing-noreturn",
     "-Wno-missing-prototypes",
     "-Wno-missing-variable-declarations",
@@ -103,12 +103,16 @@
     "-Wno-unused-template",
     "-Wno-used-but-marked-unused",
     "-Wno-zero-as-null-pointer-constant",
+    # For a libc++ bug fixed in r357267
+    "-Wno-gnu-include-next",
     # gtest depends on this GNU extension being offered.
     "-Wno-gnu-zero-variadic-macro-arguments",
 ]
 
 MSVC_STYLE_EXCEPTIONS_FLAGS = [
-    "/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc"
+    "/U_HAS_EXCEPTIONS",
+    "/D_HAS_EXCEPTIONS=1",
+    "/EHsc"
 ]
 
 MSVC_DEFINES = [
@@ -146,6 +150,7 @@
     ],
     "ABSL_GCC_TEST_FLAGS": [
         "-Wno-conversion-null",
+        "-Wno-deprecated-declarations",
         "-Wno-missing-declarations",
         "-Wno-sign-compare",
         "-Wno-unused-function",
@@ -153,26 +158,41 @@
         "-Wno-unused-private-field",
     ],
     "ABSL_GCC_EXCEPTIONS_FLAGS": ["-fexceptions"],
-    "ABSL_LLVM_FLAGS": LLVM_BIG_WARNING_FLAGS + LLVM_DISABLE_WARNINGS_FLAGS,
-    "ABSL_LLVM_TEST_FLAGS": LLVM_TEST_DISABLE_WARNINGS_FLAGS,
+    "ABSL_LLVM_FLAGS":
+        LLVM_BIG_WARNING_FLAGS + LLVM_DISABLE_WARNINGS_FLAGS,
+    "ABSL_LLVM_TEST_FLAGS":
+        LLVM_TEST_DISABLE_WARNINGS_FLAGS,
     "ABSL_LLVM_EXCEPTIONS_FLAGS": ["-fexceptions"],
-    "ABSL_CLANG_CL_FLAGS": (MSVC_BIG_WARNING_FLAGS +
-                            LLVM_DISABLE_WARNINGS_FLAGS + MSVC_DEFINES),
-    "ABSL_CLANG_CL_TEST_FLAGS": LLVM_TEST_DISABLE_WARNINGS_FLAGS,
-    "ABSL_CLANG_CL_EXCEPTIONS_FLAGS": MSVC_STYLE_EXCEPTIONS_FLAGS,
-    "ABSL_MSVC_FLAGS": MSVC_BIG_WARNING_FLAGS + MSVC_DEFINES + [
-        "/wd4005",  # macro-redefinition
-        "/wd4068",  # unknown pragma
-        "/wd4180",  # qualifier applied to function type has no meaning; ignored
-        "/wd4244",  # conversion from 'type1' to 'type2', possible loss of data
-        "/wd4267",  # conversion from 'size_t' to 'type', possible loss of data
-        # forcing value to bool 'true' or 'false' (performance warning)
-        "/wd4800",
-    ],
+    "ABSL_CLANG_CL_FLAGS": (
+        MSVC_BIG_WARNING_FLAGS + LLVM_DISABLE_WARNINGS_FLAGS + MSVC_DEFINES),
+    "ABSL_CLANG_CL_TEST_FLAGS":
+        LLVM_TEST_DISABLE_WARNINGS_FLAGS,
+    "ABSL_CLANG_CL_EXCEPTIONS_FLAGS":
+        MSVC_STYLE_EXCEPTIONS_FLAGS,
+    "ABSL_MSVC_FLAGS":
+        MSVC_BIG_WARNING_FLAGS + MSVC_DEFINES + [
+            "/wd4005",  # macro-redefinition
+            "/wd4068",  # unknown pragma
+            # qualifier applied to function type has no meaning; ignored
+            "/wd4180",
+            # conversion from 'type1' to 'type2', possible loss of data
+            "/wd4244",
+            # conversion from 'size_t' to 'type', possible loss of data
+            "/wd4267",
+            # forcing value to bool 'true' or 'false' (performance warning)
+            "/wd4800",
+        ],
     "ABSL_MSVC_TEST_FLAGS": [
         "/wd4018",  # signed/unsigned mismatch
         "/wd4101",  # unreferenced local variable
         "/wd4503",  # decorated name length exceeded, name was truncated
+        "/wd4996",  # use of deprecated symbol
+        "/DNOMINMAX",  # disable the min() and max() macros from <windows.h>
     ],
-    "ABSL_MSVC_EXCEPTIONS_FLAGS": MSVC_STYLE_EXCEPTIONS_FLAGS,
+    "ABSL_MSVC_EXCEPTIONS_FLAGS":
+        MSVC_STYLE_EXCEPTIONS_FLAGS,
+    "ABSL_MSVC_LINKOPTS": [
+        # Object file doesn't export any previously undefined symbols
+        "-ignore:4221",
+    ],
 }
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index c9184f9..0854314 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -33,6 +34,7 @@
     ],
     hdrs = ["stacktrace.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":debugging_internal",
         "//absl/base",
@@ -53,6 +55,7 @@
         "symbolize.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":debugging_internal",
         ":demangle_internal",
@@ -66,6 +69,7 @@
     name = "symbolize_test",
     srcs = ["symbolize_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":stack_consumption",
         ":symbolize",
@@ -85,6 +89,7 @@
         "internal/examine_stack.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
         ":stacktrace",
@@ -99,6 +104,7 @@
     srcs = ["failure_signal_handler.cc"],
     hdrs = ["failure_signal_handler.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":examine_stack",
         ":stacktrace",
@@ -115,7 +121,7 @@
     linkopts = select({
         "//absl:windows": [],
         "//conditions:default": ["-pthread"],
-    }),
+    }) + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":failure_signal_handler",
         ":stacktrace",
@@ -147,6 +153,7 @@
         "internal/vdso_support.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base",
         "//absl/base:core_headers",
@@ -169,6 +176,7 @@
     name = "demangle_test",
     srcs = ["internal/demangle_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":demangle_internal",
         ":stack_consumption",
@@ -183,6 +191,7 @@
     name = "leak_check",
     srcs = ["leak_check.cc"],
     hdrs = ["leak_check.h"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = ["//absl/base:core_headers"],
 )
 
@@ -192,6 +201,7 @@
 cc_library(
     name = "leak_check_disable",
     srcs = ["leak_check_disable.cc"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     linkstatic = 1,
     alwayslink = 1,
 )
@@ -212,6 +222,7 @@
         "//absl:llvm_compiler": ["-DLEAK_SANITIZER"],
         "//conditions:default": [],
     }),
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
 )
 
@@ -221,6 +232,7 @@
     srcs = ["leak_check.cc"],
     hdrs = ["leak_check.h"],
     copts = ["-ULEAK_SANITIZER"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
 )
 
@@ -231,7 +243,7 @@
         "//absl:llvm_compiler": ["-DABSL_EXPECT_LEAK_SANITIZER"],
         "//conditions:default": [],
     }),
-    linkopts = ABSL_LSAN_LINKOPTS,
+    linkopts = ABSL_LSAN_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":leak_check_api_enabled_for_testing",
         "//absl/base",
@@ -243,6 +255,7 @@
     name = "leak_check_no_lsan_test",
     srcs = ["leak_check_test.cc"],
     copts = ["-UABSL_EXPECT_LEAK_SANITIZER"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":leak_check_api_disabled_for_testing",
         "//absl/base",  # for raw_logging
@@ -257,7 +270,7 @@
 cc_test(
     name = "disabled_leak_check_test",
     srcs = ["leak_check_fail_test.cc"],
-    linkopts = ABSL_LSAN_LINKOPTS,
+    linkopts = ABSL_LSAN_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":leak_check_api_enabled_for_testing",
         ":leak_check_disable",
@@ -272,6 +285,7 @@
     srcs = ["internal/stack_consumption.cc"],
     hdrs = ["internal/stack_consumption.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
         "//absl/base",
@@ -283,6 +297,7 @@
     name = "stack_consumption_test",
     srcs = ["internal/stack_consumption_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":stack_consumption",
         "//absl/base",
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt
index dccd4a5..d813fed 100644
--- a/absl/debugging/CMakeLists.txt
+++ b/absl/debugging/CMakeLists.txt
@@ -43,6 +43,8 @@
     "symbolize_win32.inc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
+  LINKOPTS
+    ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::debugging_internal
     absl::demangle_internal
@@ -196,6 +198,8 @@
     leak_check_disable
   SRCS
     "leak_check_disable.cc"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   PUBLIC
 )
 
@@ -207,6 +211,7 @@
   SRCS
     "leak_check.cc"
   COPTS
+    ${ABSL_DEFAULT_COPTS}
     $<$<BOOL:${ABSL_HAVE_LSAN}>:-DLEAK_SANITIZER>
   TESTONLY
 )
@@ -219,6 +224,7 @@
   SRCS
     "leak_check.cc"
   COPTS
+    ${ABSL_DEFAULT_COPTS}
     "-ULEAK_SANITIZER"
   TESTONLY
 )
@@ -229,6 +235,7 @@
   SRCS
     "leak_check_test.cc"
   COPTS
+    ${ABSL_DEFAULT_COPTS}
     "$<$<BOOL:${ABSL_HAVE_LSAN}>:-DABSL_EXPECT_LEAK_SANITIZER>"
   LINKOPTS
     "${ABSL_LSAN_LINKOPTS}"
@@ -244,6 +251,7 @@
   SRCS
     "leak_check_test.cc"
   COPTS
+    ${ABSL_TEST_COPTS}
     "-UABSL_EXPECT_LEAK_SANITIZER"
   DEPS
     absl::leak_check_api_disabled_for_testing
@@ -256,6 +264,8 @@
     disabled_leak_check_test
   SRCS
     "leak_check_fail_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   LINKOPTS
     "${ABSL_LSAN_LINKOPTS}"
   DEPS
@@ -298,6 +308,8 @@
 absl_cc_library(
   NAME
     debugging
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::stacktrace
     absl::leak_check
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 883b92d..a68ce32 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -81,8 +81,9 @@
 // Tests that verify that Demangle footprint is within some limit.
 // They are not to be run under sanitizers as the sanitizers increase
 // stack consumption by about 4x.
-#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
-    !ADDRESS_SANITIZER && !MEMORY_SANITIZER && !THREAD_SANITIZER
+#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) &&   \
+    !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
+    !defined(THREAD_SANITIZER)
 
 static const char *g_mangled;
 static char g_demangle_buffer[4096];
diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc
index 05fc297..5ac7ff5 100644
--- a/absl/debugging/symbolize_elf.inc
+++ b/absl/debugging/symbolize_elf.inc
@@ -305,7 +305,7 @@
                                            char *tmp_buf, int tmp_buf_size);
 
   enum {
-    SYMBOL_BUF_SIZE = 2048,
+    SYMBOL_BUF_SIZE = 3072,
     TMP_BUF_SIZE = 1024,
     SYMBOL_CACHE_LINES = 128,
   };
diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc
index 17ea618..7ed3bd3 100644
--- a/absl/debugging/symbolize_win32.inc
+++ b/absl/debugging/symbolize_win32.inc
@@ -16,7 +16,13 @@
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx
 
 #include <windows.h>
+
+// MSVC header DbgHelp.h has a warning for an ignored typedef.
+#pragma warning(push)
+#pragma warning(disable:4091)
 #include <DbgHelp.h>
+#pragma warning(pop)
+
 #pragma comment(lib, "DbgHelp")
 
 #include <algorithm>
diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel
index 69860d9..e1e6eae 100644
--- a/absl/hash/BUILD.bazel
+++ b/absl/hash/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -32,11 +33,12 @@
     ],
     hdrs = ["hash.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
-        ":city",
         "//absl/base:core_headers",
         "//absl/base:endian",
         "//absl/container:fixed_array",
+        "//absl/hash:city",
         "//absl/meta:type_traits",
         "//absl/numeric:int128",
         "//absl/strings",
@@ -50,6 +52,7 @@
     name = "hash_testing",
     testonly = 1,
     hdrs = ["hash_testing.h"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":spy_hash_state",
         "//absl/meta:type_traits",
@@ -63,6 +66,7 @@
     name = "hash_test",
     srcs = ["hash_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hash",
         ":hash_testing",
@@ -80,6 +84,7 @@
     testonly = 1,
     hdrs = ["internal/spy_hash_state.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
         ":hash",
@@ -95,6 +100,7 @@
         "internal/city.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:config",
         "//absl/base:core_headers",
@@ -106,6 +112,7 @@
     name = "city_test",
     srcs = ["internal/city_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":city",
         "@com_google_googletest//:gtest_main",
diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt
index 4cafc13..febc551 100644
--- a/absl/hash/CMakeLists.txt
+++ b/absl/hash/CMakeLists.txt
@@ -43,6 +43,8 @@
     hash_testing
   HDRS
     "hash_testing.h"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::spy_hash_state
     absl::meta
@@ -56,7 +58,9 @@
   NAME
     hash_test
   SRCS
-   "hash_test.cc"
+    "hash_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::hash
     absl::hash_testing
diff --git a/absl/hash/hash.h b/absl/hash/hash.h
index c0ede35..339b685 100644
--- a/absl/hash/hash.h
+++ b/absl/hash/hash.h
@@ -36,6 +36,10 @@
 // framework by simply combining its state with the state of known, hashable
 // types. Hashing of that combined state is separately done by `absl::Hash`.
 //
+// One should assume that a hash algorithm is chosen randomly at the start of
+// each process.  E.g., absl::Hash<int>()(9) in one process and
+// absl::Hash<int>()(9) in another process are likely to differ.
+//
 // Example:
 //
 //   // Suppose we have a class `Circle` for which we want to add hashing
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index af95938..92c64ad 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -425,10 +425,10 @@
 }
 
 template <typename T, typename = void>
-struct IsHashCallble : std::false_type {};
+struct IsHashCallable : std::false_type {};
 
 template <typename T>
-struct IsHashCallble<T, absl::void_t<decltype(std::declval<absl::Hash<T>>()(
+struct IsHashCallable<T, absl::void_t<decltype(std::declval<absl::Hash<T>>()(
                             std::declval<const T&>()))>> : std::true_type {};
 
 template <typename T, typename = void>
@@ -445,7 +445,7 @@
   EXPECT_TRUE(std::is_move_constructible<absl::Hash<int>>::value);
   EXPECT_TRUE(absl::is_copy_assignable<absl::Hash<int>>::value);
   EXPECT_TRUE(absl::is_move_assignable<absl::Hash<int>>::value);
-  EXPECT_TRUE(IsHashCallble<int>::value);
+  EXPECT_TRUE(IsHashCallable<int>::value);
   EXPECT_TRUE(IsAggregateInitializable<absl::Hash<int>>::value);
 }
 
@@ -458,7 +458,7 @@
   EXPECT_FALSE(std::is_move_constructible<absl::Hash<X>>::value);
   EXPECT_FALSE(absl::is_copy_assignable<absl::Hash<X>>::value);
   EXPECT_FALSE(absl::is_move_assignable<absl::Hash<X>>::value);
-  EXPECT_FALSE(IsHashCallble<X>::value);
+  EXPECT_FALSE(IsHashCallable<X>::value);
   EXPECT_FALSE(IsAggregateInitializable<absl::Hash<X>>::value);
 }
 #endif  // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 9ab9890..1866517 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -615,7 +615,7 @@
 
  public:
   // Probe each implementation in order.
-  // disjunction provides short circuting wrt instantiation.
+  // disjunction provides short circuiting wrt instantiation.
   template <typename T>
   using Apply = absl::disjunction<         //
       Probe<UniquelyRepresentedProbe, T>,  //
diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel
index 7c6366f..f815ef9 100644
--- a/absl/memory/BUILD.bazel
+++ b/absl/memory/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
     "ABSL_EXCEPTIONS_FLAG",
     "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
@@ -30,6 +31,7 @@
     name = "memory",
     hdrs = ["memory.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:core_headers",
         "//absl/meta:type_traits",
@@ -40,6 +42,7 @@
     name = "memory_test",
     srcs = ["memory_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":memory",
         "//absl/base",
@@ -54,7 +57,7 @@
         "memory_exception_safety_test.cc",
     ],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":memory",
         "//absl/base:exception_safety_testing",
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc
index 8905433..c47820e 100644
--- a/absl/memory/memory_test.cc
+++ b/absl/memory/memory_test.cc
@@ -620,7 +620,7 @@
 }
 
 TEST(AllocatorNoThrowTest, DefaultAllocator) {
-#if ABSL_ALLOCATOR_NOTHROW
+#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
   EXPECT_TRUE(absl::default_allocator_is_nothrow::value);
 #else
   EXPECT_FALSE(absl::default_allocator_is_nothrow::value);
@@ -628,7 +628,7 @@
 }
 
 TEST(AllocatorNoThrowTest, StdAllocator) {
-#if ABSL_ALLOCATOR_NOTHROW
+#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
   EXPECT_TRUE(absl::allocator_is_nothrow<std::allocator<int>>::value);
 #else
   EXPECT_FALSE(absl::allocator_is_nothrow<std::allocator<int>>::value);
diff --git a/absl/meta/BUILD.bazel b/absl/meta/BUILD.bazel
index 1c39fa9..e004b50 100644
--- a/absl/meta/BUILD.bazel
+++ b/absl/meta/BUILD.bazel
@@ -1,6 +1,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -12,6 +13,7 @@
     name = "type_traits",
     hdrs = ["type_traits.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:config",
     ],
@@ -21,9 +23,9 @@
     name = "type_traits_test",
     srcs = ["type_traits_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":type_traits",
-        "//absl/base:core_headers",
         "@com_google_googletest//:gtest_main",
     ],
 )
diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt
index 74d4a54..672ead2 100644
--- a/absl/meta/CMakeLists.txt
+++ b/absl/meta/CMakeLists.txt
@@ -35,8 +35,6 @@
     ${ABSL_TEST_COPTS}
   DEPS
     absl::type_traits
-    absl::base
-    absl::core_headers
     gmock_main
 )
 
@@ -44,6 +42,8 @@
 absl_cc_library(
   NAME
     meta
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::type_traits
   PUBLIC
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index fbdc921..c08e375 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -43,8 +43,39 @@
 
 namespace absl {
 
+// Defined and documented later on in this file.
+template <typename T>
+struct is_trivially_move_assignable;
+
 namespace type_traits_internal {
 
+// Silence MSVC warnings about the destructor being defined as deleted.
+#if defined(_MSC_VER) && !defined(__GNUC__)
+#pragma warning(push)
+#pragma warning(disable : 4624)
+#endif  // defined(_MSC_VER) && !defined(__GNUC__)
+
+template <class T>
+union SingleMemberUnion {
+  T t;
+};
+
+// Restore the state of the destructor warning that was silenced above.
+#if defined(_MSC_VER) && !defined(__GNUC__)
+#pragma warning(pop)
+#endif  // defined(_MSC_VER) && !defined(__GNUC__)
+
+template <class T>
+struct IsTriviallyMoveAssignableReference : std::false_type {};
+
+template <class T>
+struct IsTriviallyMoveAssignableReference<T&>
+    : absl::is_trivially_move_assignable<T>::type {};
+
+template <class T>
+struct IsTriviallyMoveAssignableReference<T&&>
+    : absl::is_trivially_move_assignable<T>::type {};
+
 template <typename... Ts>
 struct VoidTImpl {
   using type = void;
@@ -275,6 +306,40 @@
 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 };
 
+// is_trivially_move_constructible()
+//
+// Determines whether the passed type `T` is trivially move constructible.
+//
+// This metafunction is designed to be a drop-in replacement for the C++11
+// `std::is_trivially_move_constructible()` metafunction for platforms that have
+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
+// fully support C++11, we check whether this yields the same result as the std
+// implementation.
+//
+// NOTE: `T obj(declval<T>());` needs to be well-formed and not call any
+// nontrivial operation.  Nontrivially destructible types will cause the
+// expression to be nontrivial.
+template <typename T>
+struct is_trivially_move_constructible
+    : std::conditional<
+          std::is_object<T>::value && !std::is_array<T>::value,
+          std::is_move_constructible<
+              type_traits_internal::SingleMemberUnion<T>>,
+          std::is_reference<T>>::type::type {
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+ private:
+  static constexpr bool compliant =
+      std::is_trivially_move_constructible<T>::value ==
+      is_trivially_move_constructible::value;
+  static_assert(compliant || std::is_trivially_move_constructible<T>::value,
+                "Not compliant with std::is_trivially_move_constructible; "
+                "Standard: false, Implementation: true");
+  static_assert(compliant || !std::is_trivially_move_constructible<T>::value,
+                "Not compliant with std::is_trivially_move_constructible; "
+                "Standard: true, Implementation: false");
+#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+};
+
 // is_trivially_copy_constructible()
 //
 // Determines whether the passed type `T` is trivially copy constructible.
@@ -290,9 +355,11 @@
 // expression to be nontrivial.
 template <typename T>
 struct is_trivially_copy_constructible
-    : std::integral_constant<bool, __has_trivial_copy(T) &&
-                                   std::is_copy_constructible<T>::value &&
-                                   is_trivially_destructible<T>::value> {
+    : std::conditional<
+          std::is_object<T>::value && !std::is_array<T>::value,
+          std::is_copy_constructible<
+              type_traits_internal::SingleMemberUnion<T>>,
+          std::is_lvalue_reference<T>>::type::type {
 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
  private:
   static constexpr bool compliant =
@@ -307,6 +374,42 @@
 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 };
 
+// is_trivially_move_assignable()
+//
+// Determines whether the passed type `T` is trivially move assignable.
+//
+// This metafunction is designed to be a drop-in replacement for the C++11
+// `std::is_trivially_move_assignable()` metafunction for platforms that have
+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
+// fully support C++11, we check whether this yields the same result as the std
+// implementation.
+//
+// NOTE: `is_assignable<T, U>::value` is `true` if the expression
+// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
+// operand. `is_trivially_assignable<T, U>` requires the assignment to call no
+// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
+// `is_trivially_assignable<T&, T>`.
+template <typename T>
+struct is_trivially_move_assignable
+    : std::conditional<
+          std::is_object<T>::value && !std::is_array<T>::value,
+          std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
+          type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
+          type {
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
+ private:
+  static constexpr bool compliant =
+      std::is_trivially_move_assignable<T>::value ==
+      is_trivially_move_assignable::value;
+  static_assert(compliant || std::is_trivially_move_assignable<T>::value,
+                "Not compliant with std::is_trivially_move_assignable; "
+                "Standard: false, Implementation: true");
+  static_assert(compliant || !std::is_trivially_move_assignable<T>::value,
+                "Not compliant with std::is_trivially_move_assignable; "
+                "Standard: true, Implementation: false");
+#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
+};
+
 // is_trivially_copy_assignable()
 //
 // Determines whether the passed type `T` is trivially copy assignable.
@@ -341,6 +444,49 @@
 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 };
 
+namespace type_traits_internal {
+// is_trivially_copyable()
+//
+// Determines whether the passed type `T` is trivially copyable.
+//
+// This metafunction is designed to be a drop-in replacement for the C++11
+// `std::is_trivially_copyable()` metafunction for platforms that have
+// incomplete C++11 support (such as libstdc++ 4.x). We use the C++17 definition
+// of TriviallyCopyable.
+//
+// NOTE: `is_trivially_copyable<T>::value` is `true` if all of T's copy/move
+// constructors/assignment operators are trivial or deleted, T has at least
+// one non-deleted copy/move constructor/assignment operator, and T is trivially
+// destructible. Arrays of trivially copyable types are trivially copyable.
+//
+// We expose this metafunction only for internal use within absl.
+template <typename T>
+class is_trivially_copyable_impl {
+  using ExtentsRemoved = typename std::remove_all_extents<T>::type;
+  static constexpr bool kIsCopyOrMoveConstructible =
+      std::is_copy_constructible<ExtentsRemoved>::value ||
+      std::is_move_constructible<ExtentsRemoved>::value;
+  static constexpr bool kIsCopyOrMoveAssignable =
+      absl::is_copy_assignable<ExtentsRemoved>::value ||
+      absl::is_move_assignable<ExtentsRemoved>::value;
+
+ public:
+  static constexpr bool kValue =
+      (__has_trivial_copy(ExtentsRemoved) || !kIsCopyOrMoveConstructible) &&
+      (__has_trivial_assign(ExtentsRemoved) || !kIsCopyOrMoveAssignable) &&
+      (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) &&
+      is_trivially_destructible<ExtentsRemoved>::value &&
+      // We need to check for this explicitly because otherwise we'll say
+      // references are trivial copyable when compiled by MSVC.
+      !std::is_reference<ExtentsRemoved>::value;
+};
+
+template <typename T>
+struct is_trivially_copyable
+    : std::integral_constant<
+          bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {};
+}  // namespace type_traits_internal
+
 // -----------------------------------------------------------------------------
 // C++14 "_t" trait aliases
 // -----------------------------------------------------------------------------
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 912336e..82b1be5 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -214,6 +214,29 @@
   int n_;
 };
 
+class TrivialMoveCtor {
+ public:
+  explicit TrivialMoveCtor(int n) : n_(n) {}
+  TrivialMoveCtor(TrivialMoveCtor&&) = default;
+  TrivialMoveCtor& operator=(const TrivialMoveCtor& t) {
+    n_ = t.n_;
+    return *this;
+  }
+
+ private:
+  int n_;
+};
+
+class NontrivialMoveCtor {
+ public:
+  explicit NontrivialMoveCtor(int n) : n_(n) {}
+  NontrivialMoveCtor(NontrivialMoveCtor&& t) noexcept : n_(t.n_) {}
+  NontrivialMoveCtor& operator=(const NontrivialMoveCtor&) = default;
+
+ private:
+  int n_;
+};
+
 class TrivialCopyCtor {
  public:
   explicit TrivialCopyCtor(int n) : n_(n) {}
@@ -247,6 +270,29 @@
   int n_;
 };
 
+class TrivialMoveAssign {
+ public:
+  explicit TrivialMoveAssign(int n) : n_(n) {}
+  TrivialMoveAssign(const TrivialMoveAssign& t) : n_(t.n_) {}
+  TrivialMoveAssign& operator=(TrivialMoveAssign&&) = default;
+  ~TrivialMoveAssign() {}  // can have nontrivial destructor
+ private:
+  int n_;
+};
+
+class NontrivialMoveAssign {
+ public:
+  explicit NontrivialMoveAssign(int n) : n_(n) {}
+  NontrivialMoveAssign(const NontrivialMoveAssign&) = default;
+  NontrivialMoveAssign& operator=(NontrivialMoveAssign&& t) noexcept {
+    n_ = t.n_;
+    return *this;
+  }
+
+ private:
+  int n_;
+};
+
 class TrivialCopyAssign {
  public:
   explicit TrivialCopyAssign(int n) : n_(n) {}
@@ -280,10 +326,20 @@
   int n_;
 };
 
-struct NonCopyable {
-  NonCopyable() = default;
-  NonCopyable(const NonCopyable&) = delete;
-  NonCopyable& operator=(const NonCopyable&) = delete;
+struct MovableNonCopyable {
+  MovableNonCopyable() = default;
+  MovableNonCopyable(const MovableNonCopyable&) = delete;
+  MovableNonCopyable(MovableNonCopyable&&) = default;
+  MovableNonCopyable& operator=(const MovableNonCopyable&) = delete;
+  MovableNonCopyable& operator=(MovableNonCopyable&&) = default;
+};
+
+struct NonCopyableOrMovable {
+  NonCopyableOrMovable() = default;
+  NonCopyableOrMovable(const NonCopyableOrMovable&) = delete;
+  NonCopyableOrMovable(NonCopyableOrMovable&&) = delete;
+  NonCopyableOrMovable& operator=(const NonCopyableOrMovable&) = delete;
+  NonCopyableOrMovable& operator=(NonCopyableOrMovable&&) = delete;
 };
 
 class Base {
@@ -474,6 +530,79 @@
 #endif
 }
 
+TEST(TypeTraitsTest, TestTrivialMoveCtor) {
+  // Verify that arithmetic types and pointers have trivial move
+  // constructors.
+  EXPECT_TRUE(absl::is_trivially_move_constructible<bool>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<char>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned char>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<signed char>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<wchar_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<int>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned int>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<int16_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<uint16_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<int64_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<uint64_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<float>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<double>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<long double>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<std::string*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<const std::string*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<const Trivial*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<std::string**>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial**>::value);
+
+  // Reference types
+  EXPECT_TRUE(absl::is_trivially_move_constructible<int&>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<int&&>::value);
+
+  // types with compiler generated move ctors
+  EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial>::value);
+  EXPECT_TRUE(absl::is_trivially_move_constructible<TrivialMoveCtor>::value);
+
+  // Verify that types without them (i.e. nontrivial or deleted) are not.
+  EXPECT_FALSE(
+      absl::is_trivially_move_constructible<NontrivialCopyCtor>::value);
+  EXPECT_FALSE(absl::is_trivially_move_constructible<DeletedCopyCtor>::value);
+  EXPECT_FALSE(
+      absl::is_trivially_move_constructible<NonCopyableOrMovable>::value);
+
+#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
+  // type with nontrivial destructor are nontrivial move construbtible
+  EXPECT_FALSE(
+      absl::is_trivially_move_constructible<NontrivialDestructor>::value);
+#endif
+
+  // types with vtables
+  EXPECT_FALSE(absl::is_trivially_move_constructible<Base>::value);
+
+  // Verify that simple_pair of such types is trivially move constructible
+  EXPECT_TRUE(
+      (absl::is_trivially_move_constructible<simple_pair<int, char*>>::value));
+  EXPECT_TRUE((
+      absl::is_trivially_move_constructible<simple_pair<int, Trivial>>::value));
+  EXPECT_TRUE((absl::is_trivially_move_constructible<
+               simple_pair<int, TrivialMoveCtor>>::value));
+
+  // Verify that types without trivial move constructors are
+  // correctly marked as such.
+  EXPECT_FALSE(absl::is_trivially_move_constructible<std::string>::value);
+  EXPECT_FALSE(absl::is_trivially_move_constructible<std::vector<int>>::value);
+
+  // Verify that simple_pairs of types without trivial move constructors
+  // are not marked as trivial.
+  EXPECT_FALSE((absl::is_trivially_move_constructible<
+                simple_pair<int, std::string>>::value));
+  EXPECT_FALSE((absl::is_trivially_move_constructible<
+                simple_pair<std::string, int>>::value));
+
+  // Verify that arrays are not
+  using int10 = int[10];
+  EXPECT_FALSE(absl::is_trivially_move_constructible<int10>::value);
+}
+
 TEST(TypeTraitsTest, TestTrivialCopyCtor) {
   // Verify that arithmetic types and pointers have trivial copy
   // constructors.
@@ -498,6 +627,10 @@
   EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value);
   EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value);
 
+  // Reference types
+  EXPECT_TRUE(absl::is_trivially_copy_constructible<int&>::value);
+  EXPECT_FALSE(absl::is_trivially_copy_constructible<int&&>::value);
+
   // types with compiler generated copy ctors
   EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value);
   EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value);
@@ -507,7 +640,9 @@
       absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value);
   EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value);
   EXPECT_FALSE(
-      absl::is_trivially_copy_constructible<NonCopyable>::value);
+      absl::is_trivially_copy_constructible<MovableNonCopyable>::value);
+  EXPECT_FALSE(
+      absl::is_trivially_copy_constructible<NonCopyableOrMovable>::value);
 
 #ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
   // type with nontrivial destructor are nontrivial copy construbtible
@@ -543,6 +678,74 @@
   EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value);
 }
 
+TEST(TypeTraitsTest, TestTrivialMoveAssign) {
+  // Verify that arithmetic types and pointers have trivial move
+  // assignment operators.
+  EXPECT_TRUE(absl::is_trivially_move_assignable<bool>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<char>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned char>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<signed char>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<wchar_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<int>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned int>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<int16_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<uint16_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<int64_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<uint64_t>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<float>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<double>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<long double>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<std::string*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<const std::string*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<const Trivial*>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<std::string**>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial**>::value);
+
+  // const qualified types are not assignable
+  EXPECT_FALSE(absl::is_trivially_move_assignable<const int>::value);
+
+  // types with compiler generated move assignment
+  EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<TrivialMoveAssign>::value);
+
+  // Verify that types without them (i.e. nontrivial or deleted) are not.
+  EXPECT_FALSE(absl::is_trivially_move_assignable<NontrivialCopyAssign>::value);
+  EXPECT_FALSE(absl::is_trivially_move_assignable<DeletedCopyAssign>::value);
+  EXPECT_FALSE(absl::is_trivially_move_assignable<NonCopyableOrMovable>::value);
+
+  // types with vtables
+  EXPECT_FALSE(absl::is_trivially_move_assignable<Base>::value);
+
+  // Verify that simple_pair is trivially assignable
+  EXPECT_TRUE(
+      (absl::is_trivially_move_assignable<simple_pair<int, char*>>::value));
+  EXPECT_TRUE(
+      (absl::is_trivially_move_assignable<simple_pair<int, Trivial>>::value));
+  EXPECT_TRUE((absl::is_trivially_move_assignable<
+               simple_pair<int, TrivialMoveAssign>>::value));
+
+  // Verify that types not trivially move assignable are
+  // correctly marked as such.
+  EXPECT_FALSE(absl::is_trivially_move_assignable<std::string>::value);
+  EXPECT_FALSE(absl::is_trivially_move_assignable<std::vector<int>>::value);
+
+  // Verify that simple_pairs of types not trivially move assignable
+  // are not marked as trivial.
+  EXPECT_FALSE((absl::is_trivially_move_assignable<
+                simple_pair<int, std::string>>::value));
+  EXPECT_FALSE((absl::is_trivially_move_assignable<
+                simple_pair<std::string, int>>::value));
+
+  // Verify that arrays are not trivially move assignable
+  using int10 = int[10];
+  EXPECT_FALSE(absl::is_trivially_move_assignable<int10>::value);
+
+  // Verify that references are handled correctly
+  EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&&>::value);
+  EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&>::value);
+}
+
 TEST(TypeTraitsTest, TestTrivialCopyAssign) {
   // Verify that arithmetic types and pointers have trivial copy
   // assignment operators.
@@ -577,7 +780,8 @@
   // Verify that types without them (i.e. nontrivial or deleted) are not.
   EXPECT_FALSE(absl::is_trivially_copy_assignable<NontrivialCopyAssign>::value);
   EXPECT_FALSE(absl::is_trivially_copy_assignable<DeletedCopyAssign>::value);
-  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyable>::value);
+  EXPECT_FALSE(absl::is_trivially_copy_assignable<MovableNonCopyable>::value);
+  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyableOrMovable>::value);
 
   // types with vtables
   EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value);
@@ -611,6 +815,116 @@
   EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&>::value);
 }
 
+TEST(TypeTraitsTest, TestTriviallyCopyable) {
+  // Verify that arithmetic types and pointers are trivially copyable.
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<bool>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<char>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<unsigned char>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<signed char>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<wchar_t>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<int>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<unsigned int>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<int16_t>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<uint16_t>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<int64_t>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<uint64_t>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<float>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<double>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<long double>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<std::string*>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial*>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
+              const std::string*>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<const Trivial*>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<std::string**>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial**>::value);
+
+  // const qualified types are not assignable but are constructible
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<const int>::value);
+
+  // Trivial copy constructor/assignment and destructor.
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial>::value);
+  // Trivial copy assignment, but non-trivial copy constructor/destructor.
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               TrivialCopyAssign>::value);
+  // Trivial copy constructor, but non-trivial assignment.
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               TrivialCopyCtor>::value);
+
+  // Types with a non-trivial copy constructor/assignment
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               NontrivialCopyCtor>::value);
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               NontrivialCopyAssign>::value);
+
+  // Types without copy constructor/assignment, but with move
+  // MSVC disagrees with other compilers about this:
+  // EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
+  //             MovableNonCopyable>::value);
+
+  // Types without copy/move constructor/assignment
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               NonCopyableOrMovable>::value);
+
+  // No copy assign, but has trivial copy constructor.
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
+              DeletedCopyAssign>::value);
+
+  // types with vtables
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<Base>::value);
+
+  // Verify that simple_pair is trivially copyable if members are
+  EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable<
+               simple_pair<int, char*>>::value));
+  EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable<
+               simple_pair<int, Trivial>>::value));
+
+  // Verify that types not trivially copyable are
+  // correctly marked as such.
+  EXPECT_FALSE(
+      absl::type_traits_internal::is_trivially_copyable<std::string>::value);
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               std::vector<int>>::value);
+
+  // Verify that simple_pairs of types not trivially copyable
+  // are not marked as trivial.
+  EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
+                simple_pair<int, std::string>>::value));
+  EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
+                simple_pair<std::string, int>>::value));
+  EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
+                simple_pair<int, TrivialCopyAssign>>::value));
+
+  // Verify that arrays of trivially copyable types are trivially copyable
+  using int10 = int[10];
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<int10>::value);
+  using int10x10 = int[10][10];
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<int10x10>::value);
+
+  // Verify that references are handled correctly
+  EXPECT_FALSE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial&&>::value);
+  EXPECT_FALSE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial&>::value);
+}
+
 #define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...)          \
   EXPECT_TRUE((std::is_same<typename std::trait_name<__VA_ARGS__>::type, \
                             absl::trait_name##_t<__VA_ARGS__>>::value))
diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel
index 7cd7ee1..d9b561d 100644
--- a/absl/numeric/BUILD.bazel
+++ b/absl/numeric/BUILD.bazel
@@ -15,6 +15,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -31,6 +32,7 @@
     ],
     hdrs = ["int128.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:config",
         "//absl/base:core_headers",
@@ -45,6 +47,7 @@
         "int128_test.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":int128",
         "//absl/base",
@@ -59,6 +62,7 @@
     name = "int128_benchmark",
     srcs = ["int128_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["benchmark"],
     deps = [
         ":int128",
diff --git a/absl/numeric/CMakeLists.txt b/absl/numeric/CMakeLists.txt
index d26141c..242889f 100644
--- a/absl/numeric/CMakeLists.txt
+++ b/absl/numeric/CMakeLists.txt
@@ -52,6 +52,8 @@
 absl_cc_library(
   NAME
     numeric
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::int128
   PUBLIC
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 9640ff4..2b19473 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -16,9 +16,9 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
-    "ABSL_TEST_COPTS",
     "ABSL_EXCEPTIONS_FLAG",
     "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
+    "ABSL_TEST_COPTS",
 )
 
 package(
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt
index d3393a3..8515ec2 100644
--- a/absl/strings/CMakeLists.txt
+++ b/absl/strings/CMakeLists.txt
@@ -501,6 +501,8 @@
     "internal/pow10_helper.h"
   SRCS
     "internal/pow10_helper.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
   TESTONLY
 )
 
diff --git a/absl/strings/charconv.h b/absl/strings/charconv.h
index 59f74bf..3f5891b 100644
--- a/absl/strings/charconv.h
+++ b/absl/strings/charconv.h
@@ -49,9 +49,9 @@
 // this only supports the `double` and `float` types.
 //
 // This interface incorporates the proposed resolutions for library issues
-// DR 3800 and DR 3801.  If these are adopted with different wording,
+// DR 3080 and DR 3081.  If these are adopted with different wording,
 // Abseil's behavior will change to match the standard.  (The behavior most
-// likely to change is for DR 3801, which says what `value` will be set to in
+// likely to change is for DR 3081, which says what `value` will be set to in
 // the case of overflow and underflow.  Code that wants to avoid possible
 // breaking changes in this area should not depend on `value` when the returned
 // from_chars_result indicates a range error.)
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc
index bc8307e..0d336e3 100644
--- a/absl/strings/escaping.cc
+++ b/absl/strings/escaping.cc
@@ -1055,10 +1055,10 @@
 }
 
 // ----------------------------------------------------------------------
-// ptrdiff_t Base64Unescape() - base64 decoder
-// ptrdiff_t Base64Escape() - base64 encoder
-// ptrdiff_t WebSafeBase64Unescape() - Google's variation of base64 decoder
-// ptrdiff_t WebSafeBase64Escape() - Google's variation of base64 encoder
+// Base64Unescape() - base64 decoder
+// Base64Escape() - base64 encoder
+// WebSafeBase64Unescape() - Google's variation of base64 decoder
+// WebSafeBase64Escape() - Google's variation of base64 encoder
 //
 // Check out
 // http://tools.ietf.org/html/rfc2045 for formal description, but what we
@@ -1096,6 +1096,20 @@
                        src.size(), dest, false, kWebSafeBase64Chars);
 }
 
+std::string Base64Escape(absl::string_view src) {
+  std::string dest;
+  Base64EscapeInternal(reinterpret_cast<const unsigned char*>(src.data()),
+                       src.size(), &dest, true, kBase64Chars);
+  return dest;
+}
+
+std::string WebSafeBase64Escape(absl::string_view src) {
+  std::string dest;
+  Base64EscapeInternal(reinterpret_cast<const unsigned char*>(src.data()),
+                       src.size(), &dest, false, kWebSafeBase64Chars);
+  return dest;
+}
+
 std::string HexStringToBytes(absl::string_view from) {
   std::string result;
   const auto num = from.size() / 2;
diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h
index fd9be78..198b934 100644
--- a/absl/strings/escaping.h
+++ b/absl/strings/escaping.h
@@ -132,16 +132,18 @@
 
 // Base64Escape()
 //
-// Encodes a `src` string into a `dest` buffer using base64 encoding, with
-// padding characters. This function conforms with RFC 4648 section 4 (base64).
+// Encodes a `src` string into a base64-encoded string, with padding characters.
+// This function conforms with RFC 4648 section 4 (base64).
 void Base64Escape(absl::string_view src, std::string* dest);
+std::string Base64Escape(absl::string_view src);
 
 // WebSafeBase64Escape()
 //
-// Encodes a `src` string into a `dest` buffer using '-' instead of '+' and
-// '_' instead of '/', and without padding. This function conforms with RFC 4648
-// section 5 (base64url).
+// Encodes a `src` string into a base64-like string, using '-' instead of '+'
+// and '_' instead of '/', and without padding. This function conforms with RFC
+// 4648 section 5 (base64url).
 void WebSafeBase64Escape(absl::string_view src, std::string* dest);
+std::string WebSafeBase64Escape(absl::string_view src);
 
 // HexStringToBytes()
 //
diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc
index d433b4c..6a633cd 100644
--- a/absl/strings/escaping_test.cc
+++ b/absl/strings/escaping_test.cc
@@ -556,6 +556,7 @@
     StringType encoded("this junk should be ignored");
     absl::Base64Escape(tc.plaintext, &encoded);
     EXPECT_EQ(encoded, tc.cyphertext);
+    EXPECT_EQ(absl::Base64Escape(tc.plaintext), tc.cyphertext);
 
     StringType decoded("this junk should be ignored");
     EXPECT_TRUE(absl::Base64Unescape(encoded, &decoded));
@@ -574,6 +575,7 @@
     encoded = "this junk should be ignored";
     absl::WebSafeBase64Escape(tc.plaintext, &encoded);
     EXPECT_EQ(encoded, websafe);
+    EXPECT_EQ(absl::WebSafeBase64Escape(tc.plaintext), websafe);
 
     // Let's try the std::string version of the decoder
     decoded = "this junk should be ignored";
@@ -586,6 +588,7 @@
     StringType buffer;
     absl::WebSafeBase64Escape(tc.plaintext, &buffer);
     EXPECT_EQ(tc.cyphertext, buffer);
+    EXPECT_EQ(absl::WebSafeBase64Escape(tc.plaintext), tc.cyphertext);
   }
 
   // Verify the behavior when decoding bad data
diff --git a/absl/strings/internal/str_format/bind_test.cc b/absl/strings/internal/str_format/bind_test.cc
index ba6470e..2574801 100644
--- a/absl/strings/internal/str_format/bind_test.cc
+++ b/absl/strings/internal/str_format/bind_test.cc
@@ -9,16 +9,11 @@
 namespace str_format_internal {
 namespace {
 
-template <typename T, size_t N>
-size_t ArraySize(T (&)[N]) {
-  return N;
-}
-
 class FormatBindTest : public ::testing::Test {
  public:
   bool Extract(const char *s, UnboundConversion *props, int *next) const {
-    absl::string_view src = s;
-    return ConsumeUnboundConversion(&src, props, next) && src.empty();
+    return ConsumeUnboundConversion(s, s + strlen(s), props, next) ==
+           s + strlen(s);
   }
 };
 
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index 99cc0af..3b4d4b0 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -1,6 +1,7 @@
 #include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <cctype>
 #include <cmath>
 #include <string>
 
@@ -32,7 +33,9 @@
 std::string LengthModFor(unsigned long long) { return "ll"; }  // NOLINT
 
 std::string EscCharImpl(int v) {
-  if (isprint(v)) return std::string(1, static_cast<char>(v));
+  if (std::isprint(static_cast<unsigned char>(v))) {
+    return std::string(1, static_cast<char>(v));
+  }
   char buf[64];
   int n = snprintf(buf, sizeof(buf), "\\%#.2x",
                    static_cast<unsigned>(v & 0xff));
@@ -155,7 +158,7 @@
 }
 
 TEST_F(FormatConvertTest, Pointer) {
-#if _MSC_VER
+#ifdef _MSC_VER
   // MSVC's printf implementation prints pointers differently. We can't easily
   // compare our implementation to theirs.
   return;
@@ -390,7 +393,7 @@
 }
 
 TEST_F(FormatConvertTest, Float) {
-#if _MSC_VER
+#ifdef _MSC_VER
   // MSVC has a different rounding policy than us so we can't test our
   // implementation against the native one there.
   return;
diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc
index 10487f2..9ef5615 100644
--- a/absl/strings/internal/str_format/parser.cc
+++ b/absl/strings/internal/str_format/parser.cc
@@ -15,6 +15,44 @@
 
 namespace absl {
 namespace str_format_internal {
+
+using CC = ConversionChar::Id;
+using LM = LengthMod::Id;
+ABSL_CONST_INIT const ConvTag kTags[256] = {
+    {},    {},    {},    {},    {},    {},    {},    {},     // 00-07
+    {},    {},    {},    {},    {},    {},    {},    {},     // 08-0f
+    {},    {},    {},    {},    {},    {},    {},    {},     // 10-17
+    {},    {},    {},    {},    {},    {},    {},    {},     // 18-1f
+    {},    {},    {},    {},    {},    {},    {},    {},     // 20-27
+    {},    {},    {},    {},    {},    {},    {},    {},     // 28-2f
+    {},    {},    {},    {},    {},    {},    {},    {},     // 30-37
+    {},    {},    {},    {},    {},    {},    {},    {},     // 38-3f
+    {},    CC::A, {},    CC::C, {},    CC::E, CC::F, CC::G,  // @ABCDEFG
+    {},    {},    {},    {},    LM::L, {},    {},    {},     // HIJKLMNO
+    {},    {},    {},    CC::S, {},    {},    {},    {},     // PQRSTUVW
+    CC::X, {},    {},    {},    {},    {},    {},    {},     // XYZ[\]^_
+    {},    CC::a, {},    CC::c, CC::d, CC::e, CC::f, CC::g,  // `abcdefg
+    LM::h, CC::i, LM::j, {},    LM::l, {},    CC::n, CC::o,  // hijklmno
+    CC::p, LM::q, {},    CC::s, LM::t, CC::u, {},    {},     // pqrstuvw
+    CC::x, {},    LM::z, {},    {},    {},    {},    {},     // xyz{|}!
+    {},    {},    {},    {},    {},    {},    {},    {},     // 80-87
+    {},    {},    {},    {},    {},    {},    {},    {},     // 88-8f
+    {},    {},    {},    {},    {},    {},    {},    {},     // 90-97
+    {},    {},    {},    {},    {},    {},    {},    {},     // 98-9f
+    {},    {},    {},    {},    {},    {},    {},    {},     // a0-a7
+    {},    {},    {},    {},    {},    {},    {},    {},     // a8-af
+    {},    {},    {},    {},    {},    {},    {},    {},     // b0-b7
+    {},    {},    {},    {},    {},    {},    {},    {},     // b8-bf
+    {},    {},    {},    {},    {},    {},    {},    {},     // c0-c7
+    {},    {},    {},    {},    {},    {},    {},    {},     // c8-cf
+    {},    {},    {},    {},    {},    {},    {},    {},     // d0-d7
+    {},    {},    {},    {},    {},    {},    {},    {},     // d8-df
+    {},    {},    {},    {},    {},    {},    {},    {},     // e0-e7
+    {},    {},    {},    {},    {},    {},    {},    {},     // e8-ef
+    {},    {},    {},    {},    {},    {},    {},    {},     // f0-f7
+    {},    {},    {},    {},    {},    {},    {},    {},     // f8-ff
+};
+
 namespace {
 
 bool CheckFastPathSetting(const UnboundConversion& conv) {
@@ -36,60 +74,17 @@
   return should_be_basic == conv.flags.basic;
 }
 
-// Keep a single table for all the conversion chars and length modifiers.
-// We invert the length modifiers to make them negative so that we can easily
-// test for them.
-// Everything else is `none`, which is a negative constant.
-using CC = ConversionChar::Id;
-using LM = LengthMod::Id;
-static constexpr std::int8_t none = -128;
-static constexpr std::int8_t kIds[] = {
-    none,   none,   none,   none,  none,   none,  none,  none,   // 00-07
-    none,   none,   none,   none,  none,   none,  none,  none,   // 08-0f
-    none,   none,   none,   none,  none,   none,  none,  none,   // 10-17
-    none,   none,   none,   none,  none,   none,  none,  none,   // 18-1f
-    none,   none,   none,   none,  none,   none,  none,  none,   // 20-27
-    none,   none,   none,   none,  none,   none,  none,  none,   // 28-2f
-    none,   none,   none,   none,  none,   none,  none,  none,   // 30-37
-    none,   none,   none,   none,  none,   none,  none,  none,   // 38-3f
-    none,   CC::A,  none,   CC::C, none,   CC::E, CC::F, CC::G,  // @ABCDEFG
-    none,   none,   none,   none,  ~LM::L, none,  none,  none,   // HIJKLMNO
-    none,   none,   none,   CC::S, none,   none,  none,  none,   // PQRSTUVW
-    CC::X,  none,   none,   none,  none,   none,  none,  none,   // XYZ[\]^_
-    none,   CC::a,  none,   CC::c, CC::d,  CC::e, CC::f, CC::g,  // `abcdefg
-    ~LM::h, CC::i,  ~LM::j, none,  ~LM::l, none,  CC::n, CC::o,  // hijklmno
-    CC::p,  ~LM::q, none,   CC::s, ~LM::t, CC::u, none,  none,   // pqrstuvw
-    CC::x,  none,   ~LM::z, none,  none,   none,  none,  none,   // xyz{|}~!
-    none,   none,   none,   none,  none,   none,  none,  none,   // 80-87
-    none,   none,   none,   none,  none,   none,  none,  none,   // 88-8f
-    none,   none,   none,   none,  none,   none,  none,  none,   // 90-97
-    none,   none,   none,   none,  none,   none,  none,  none,   // 98-9f
-    none,   none,   none,   none,  none,   none,  none,  none,   // a0-a7
-    none,   none,   none,   none,  none,   none,  none,  none,   // a8-af
-    none,   none,   none,   none,  none,   none,  none,  none,   // b0-b7
-    none,   none,   none,   none,  none,   none,  none,  none,   // b8-bf
-    none,   none,   none,   none,  none,   none,  none,  none,   // c0-c7
-    none,   none,   none,   none,  none,   none,  none,  none,   // c8-cf
-    none,   none,   none,   none,  none,   none,  none,  none,   // d0-d7
-    none,   none,   none,   none,  none,   none,  none,  none,   // d8-df
-    none,   none,   none,   none,  none,   none,  none,  none,   // e0-e7
-    none,   none,   none,   none,  none,   none,  none,  none,   // e8-ef
-    none,   none,   none,   none,  none,   none,  none,  none,   // f0-f7
-    none,   none,   none,   none,  none,   none,  none,  none,   // f8-ff
-};
-
 template <bool is_positional>
-bool ConsumeConversion(string_view *src, UnboundConversion *conv,
-                       int *next_arg) {
-  const char *pos = src->data();
-  const char *const end = pos + src->size();
+const char *ConsumeConversion(const char *pos, const char *const end,
+                              UnboundConversion *conv, int *next_arg) {
+  const char* const original_pos = pos;
   char c;
   // Read the next char into `c` and update `pos`. Returns false if there are
   // no more chars to read.
-#define ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR()        \
-  do {                                                \
-    if (ABSL_PREDICT_FALSE(pos == end)) return false; \
-    c = *pos++;                                       \
+#define ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR()          \
+  do {                                                  \
+    if (ABSL_PREDICT_FALSE(pos == end)) return nullptr; \
+    c = *pos++;                                         \
   } while (0)
 
   const auto parse_digits = [&] {
@@ -111,10 +106,10 @@
 
   if (is_positional) {
     ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
-    if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return false;
+    if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr;
     conv->arg_position = parse_digits();
     assert(conv->arg_position > 0);
-    if (ABSL_PREDICT_FALSE(c != '$')) return false;
+    if (ABSL_PREDICT_FALSE(c != '$')) return nullptr;
   }
 
   ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
@@ -129,10 +124,9 @@
     conv->flags.basic = false;
 
     for (; c <= '0';) {
-      // FIXME: We might be able to speed this up reusing the kIds lookup table
-      // from above.
-      // It might require changing Flags to be a plain integer where we can |= a
-      // value.
+      // FIXME: We might be able to speed this up reusing the lookup table from
+      // above. It might require changing Flags to be a plain integer where we
+      // can |= a value.
       switch (c) {
         case '-':
           conv->flags.left = true;
@@ -160,20 +154,20 @@
       if (c >= '0') {
         int maybe_width = parse_digits();
         if (!is_positional && c == '$') {
-          if (ABSL_PREDICT_FALSE(*next_arg != 0)) return false;
+          if (ABSL_PREDICT_FALSE(*next_arg != 0)) return nullptr;
           // Positional conversion.
           *next_arg = -1;
           conv->flags = Flags();
           conv->flags.basic = true;
-          return ConsumeConversion<true>(src, conv, next_arg);
+          return ConsumeConversion<true>(original_pos, end, conv, next_arg);
         }
         conv->width.set_value(maybe_width);
       } else if (c == '*') {
         ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
         if (is_positional) {
-          if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return false;
+          if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr;
           conv->width.set_from_arg(parse_digits());
-          if (ABSL_PREDICT_FALSE(c != '$')) return false;
+          if (ABSL_PREDICT_FALSE(c != '$')) return nullptr;
           ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
         } else {
           conv->width.set_from_arg(++*next_arg);
@@ -188,9 +182,9 @@
       } else if (c == '*') {
         ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
         if (is_positional) {
-          if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return false;
+          if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr;
           conv->precision.set_from_arg(parse_digits());
-          if (c != '$') return false;
+          if (c != '$') return nullptr;
           ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
         } else {
           conv->precision.set_from_arg(++*next_arg);
@@ -201,14 +195,14 @@
     }
   }
 
-  std::int8_t id = kIds[static_cast<unsigned char>(c)];
+  auto tag = GetTagForChar(c);
 
-  if (id < 0) {
-    if (ABSL_PREDICT_FALSE(id == none)) return false;
+  if (ABSL_PREDICT_FALSE(!tag.is_conv())) {
+    if (ABSL_PREDICT_FALSE(!tag.is_length())) return nullptr;
 
     // It is a length modifier.
     using str_format_internal::LengthMod;
-    LengthMod length_mod = LengthMod::FromId(static_cast<LM>(~id));
+    LengthMod length_mod = tag.as_length();
     ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
     if (c == 'h' && length_mod.id() == LengthMod::h) {
       conv->length_mod = LengthMod::FromId(LengthMod::hh);
@@ -219,25 +213,24 @@
     } else {
       conv->length_mod = length_mod;
     }
-    id = kIds[static_cast<unsigned char>(c)];
-    if (ABSL_PREDICT_FALSE(id < 0)) return false;
+    tag = GetTagForChar(c);
+    if (ABSL_PREDICT_FALSE(!tag.is_conv())) return nullptr;
   }
 
   assert(CheckFastPathSetting(*conv));
   (void)(&CheckFastPathSetting);
 
-  conv->conv = ConversionChar::FromId(static_cast<CC>(id));
+  conv->conv = tag.as_conv();
   if (!is_positional) conv->arg_position = ++*next_arg;
-  *src = string_view(pos, end - pos);
-  return true;
+  return pos;
 }
 
 }  // namespace
 
-bool ConsumeUnboundConversion(string_view *src, UnboundConversion *conv,
-                              int *next_arg) {
-  if (*next_arg < 0) return ConsumeConversion<true>(src, conv, next_arg);
-  return ConsumeConversion<false>(src, conv, next_arg);
+const char *ConsumeUnboundConversion(const char *p, const char *end,
+                                     UnboundConversion *conv, int *next_arg) {
+  if (*next_arg < 0) return ConsumeConversion<true>(p, end, conv, next_arg);
+  return ConsumeConversion<false>(p, end, conv, next_arg);
 }
 
 struct ParsedFormatBase::ParsedFormatConsumer {
diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h
index 1022f06..b7614a0 100644
--- a/absl/strings/internal/str_format/parser.h
+++ b/absl/strings/internal/str_format/parser.h
@@ -63,17 +63,45 @@
   ConversionChar conv;
 };
 
-// Consume conversion spec prefix (not including '%') of '*src' if valid.
+// Consume conversion spec prefix (not including '%') of [p, end) if valid.
 // Examples of valid specs would be e.g.: "s", "d", "-12.6f".
-// If valid, the front of src is advanced such that src becomes the
-// part following the conversion spec, and the spec part is broken down and
-// returned in 'conv'.
-// If invalid, returns false and leaves 'src' unmodified.
-// For example:
-//   Given "d9", returns "d", and leaves src="9",
-//   Given "!", returns "" and leaves src="!".
-bool ConsumeUnboundConversion(string_view* src, UnboundConversion* conv,
-                              int* next_arg);
+// If valid, it returns the first character following the conversion spec,
+// and the spec part is broken down and returned in 'conv'.
+// If invalid, returns nullptr.
+const char* ConsumeUnboundConversion(const char* p, const char* end,
+                                     UnboundConversion* conv, int* next_arg);
+
+// Helper tag class for the table below.
+// It allows fast `char -> ConversionChar/LengthMod` checking and conversions.
+class ConvTag {
+ public:
+  constexpr ConvTag(ConversionChar::Id id) : tag_(id) {}  // NOLINT
+  // We invert the length modifiers to make them negative so that we can easily
+  // test for them.
+  constexpr ConvTag(LengthMod::Id id) : tag_(~id) {}  // NOLINT
+  // Everything else is -128, which is negative to make is_conv() simpler.
+  constexpr ConvTag() : tag_(-128) {}
+
+  bool is_conv() const { return tag_ >= 0; }
+  bool is_length() const { return tag_ < 0 && tag_ != -128; }
+  ConversionChar as_conv() const {
+    assert(is_conv());
+    return ConversionChar::FromId(static_cast<ConversionChar::Id>(tag_));
+  }
+  LengthMod as_length() const {
+    assert(is_length());
+    return LengthMod::FromId(static_cast<LengthMod::Id>(~tag_));
+  }
+
+ private:
+  std::int8_t tag_;
+};
+
+extern const ConvTag kTags[256];
+// Keep a single table for all the conversion chars and length modifiers.
+inline ConvTag GetTagForChar(char c) {
+  return kTags[static_cast<unsigned char>(c)];
+}
 
 // Parse the format string provided in 'src' and pass the identified items into
 // 'consumer'.
@@ -88,51 +116,53 @@
 template <typename Consumer>
 bool ParseFormatString(string_view src, Consumer consumer) {
   int next_arg = 0;
-  while (!src.empty()) {
-    const char* percent =
-        static_cast<const char*>(memchr(src.data(), '%', src.size()));
+  const char* p = src.data();
+  const char* const end = p + src.size();
+  while (p != end) {
+    const char* percent = static_cast<const char*>(memchr(p, '%', end - p));
     if (!percent) {
       // We found the last substring.
-      return consumer.Append(src);
+      return consumer.Append(string_view(p, end - p));
     }
     // We found a percent, so push the text run then process the percent.
-    size_t percent_loc = percent - src.data();
-    if (!consumer.Append(string_view(src.data(), percent_loc))) return false;
-    if (percent + 1 >= src.data() + src.size()) return false;
-
-    UnboundConversion conv;
-
-    switch (percent[1]) {
-      case '%':
-        if (!consumer.Append("%")) return false;
-        src.remove_prefix(percent_loc + 2);
-        continue;
-
-#define PARSER_CASE(ch)                                     \
-  case #ch[0]:                                              \
-    src.remove_prefix(percent_loc + 2);                     \
-    conv.conv = ConversionChar::FromId(ConversionChar::ch); \
-    conv.arg_position = ++next_arg;                         \
-    break;
-        ABSL_CONVERSION_CHARS_EXPAND_(PARSER_CASE, );
-#undef PARSER_CASE
-
-      default:
-        src.remove_prefix(percent_loc + 1);
-        if (!ConsumeUnboundConversion(&src, &conv, &next_arg)) return false;
-        break;
-    }
-    if (next_arg == 0) {
-      // This indicates an error in the format std::string.
-      // The only way to get next_arg == 0 is to have a positional argument
-      // first which sets next_arg to -1 and then a non-positional argument
-      // which does ++next_arg.
-      // Checking here seems to be the cheapeast place to do it.
+    if (ABSL_PREDICT_FALSE(!consumer.Append(string_view(p, percent - p)))) {
       return false;
     }
-    if (!consumer.ConvertOne(
-            conv, string_view(percent + 1, src.data() - (percent + 1)))) {
-      return false;
+    if (ABSL_PREDICT_FALSE(percent + 1 >= end)) return false;
+
+    auto tag = GetTagForChar(percent[1]);
+    if (tag.is_conv()) {
+      if (ABSL_PREDICT_FALSE(next_arg < 0)) {
+        // This indicates an error in the format std::string.
+        // The only way to get `next_arg < 0` here is to have a positional
+        // argument first which sets next_arg to -1 and then a non-positional
+        // argument.
+        return false;
+      }
+      p = percent + 2;
+
+      // Keep this case separate from the one below.
+      // ConvertOne is more efficient when the compiler can see that the `basic`
+      // flag is set.
+      UnboundConversion conv;
+      conv.conv = tag.as_conv();
+      conv.arg_position = ++next_arg;
+      if (ABSL_PREDICT_FALSE(
+              !consumer.ConvertOne(conv, string_view(percent + 1, 1)))) {
+        return false;
+      }
+    } else if (percent[1] != '%') {
+      UnboundConversion conv;
+      p = ConsumeUnboundConversion(percent + 1, end, &conv, &next_arg);
+      if (ABSL_PREDICT_FALSE(p == nullptr)) return false;
+      if (ABSL_PREDICT_FALSE(!consumer.ConvertOne(
+          conv, string_view(percent + 1, p - (percent + 1))))) {
+        return false;
+      }
+    } else {
+      if (ABSL_PREDICT_FALSE(!consumer.Append("%"))) return false;
+      p = percent + 2;
+      continue;
     }
   }
   return true;
diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc
index ff70575..6d35609 100644
--- a/absl/strings/internal/str_format/parser_test.cc
+++ b/absl/strings/internal/str_format/parser_test.cc
@@ -1,6 +1,8 @@
 #include "absl/strings/internal/str_format/parser.h"
 
 #include <string.h>
+
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "absl/base/macros.h"
 
@@ -9,6 +11,8 @@
 
 namespace {
 
+using testing::Pair;
+
 TEST(LengthModTest, Names) {
   struct Expectation {
     int line;
@@ -63,20 +67,21 @@
 
 class ConsumeUnboundConversionTest : public ::testing::Test {
  public:
-  typedef UnboundConversion Props;
-  string_view Consume(string_view* src) {
+  std::pair<string_view, string_view> Consume(string_view src) {
     int next = 0;
-    const char* prev_begin = src->data();
     o = UnboundConversion();  // refresh
-    ConsumeUnboundConversion(src, &o, &next);
-    return {prev_begin, static_cast<size_t>(src->data() - prev_begin)};
+    const char* p = ConsumeUnboundConversion(
+        src.data(), src.data() + src.size(), &o, &next);
+    if (!p) return {{}, src};
+    return {string_view(src.data(), p - src.data()),
+            string_view(p, src.data() + src.size() - p)};
   }
 
   bool Run(const char *fmt, bool force_positional = false) {
-    string_view src = fmt;
     int next = force_positional ? -1 : 0;
     o = UnboundConversion();  // refresh
-    return ConsumeUnboundConversion(&src, &o, &next) && src.empty();
+    return ConsumeUnboundConversion(fmt, fmt + strlen(fmt), &o, &next) ==
+           fmt + strlen(fmt);
   }
   UnboundConversion o;
 };
@@ -104,11 +109,7 @@
   };
   for (const auto& e : kExpect) {
     SCOPED_TRACE(e.line);
-    string_view src = e.src;
-    EXPECT_EQ(e.src, src);
-    string_view out = Consume(&src);
-    EXPECT_EQ(e.out, out);
-    EXPECT_EQ(e.src_post, src);
+    EXPECT_THAT(Consume(e.src), Pair(e.out, e.src_post));
   }
 }
 
diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc
index 558c339..38d1486 100644
--- a/absl/strings/numbers.cc
+++ b/absl/strings/numbers.cc
@@ -54,7 +54,7 @@
     // not all non-whitespace characters consumed
     return false;
   }
-  // from_chars() with DR 3801's current wording will return max() on
+  // from_chars() with DR 3081's current wording will return max() on
   // overflow.  SimpleAtof returns infinity instead.
   if (result.ec == std::errc::result_out_of_range) {
     if (*out > 1.0) {
@@ -80,7 +80,7 @@
     // not all non-whitespace characters consumed
     return false;
   }
-  // from_chars() with DR 3801's current wording will return max() on
+  // from_chars() with DR 3081's current wording will return max() on
   // overflow.  SimpleAtod returns infinity instead.
   if (result.ec == std::errc::result_out_of_range) {
     if (*out > 1.0) {
diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc
index 4b8e7d6..02f27bc 100644
--- a/absl/strings/str_split_test.cc
+++ b/absl/strings/str_split_test.cc
@@ -71,8 +71,8 @@
 // namespaces just like callers will need to use.
 TEST(Split, APIExamples) {
   {
-    // Passes std::string delimiter. Assumes the default of Literal.
-    std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
+    // Passes std::string delimiter. Assumes the default of ByString.
+    std::vector<std::string> v = absl::StrSplit("a,b,c", ",");  // NOLINT
     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
 
     // Equivalent to...
@@ -97,17 +97,6 @@
   }
 
   {
-    // Same as above, but using std::string
-    std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
-    EXPECT_THAT(v, ElementsAre("a", "b", "c"));
-
-    // Equivalent to...
-    using absl::ByChar;
-    v = absl::StrSplit("a,b,c", ByChar(','));
-    EXPECT_THAT(v, ElementsAre("a", "b", "c"));
-  }
-
-  {
     // Uses the Literal std::string "=>" as the delimiter.
     const std::vector<std::string> v = absl::StrSplit("a=>b=>c", "=>");
     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
@@ -797,7 +786,7 @@
 }
 
 //
-// Tests for Literal
+// Tests for ByString
 //
 
 // Tests using any delimiter that represents a single comma.
@@ -817,7 +806,7 @@
   EXPECT_FALSE(IsFoundAt(";", d, -1));
 }
 
-TEST(Delimiter, Literal) {
+TEST(Delimiter, ByString) {
   using absl::ByString;
   TestComma(ByString(","));
 
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index 5e69847..67da9d4 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -34,6 +35,7 @@
         "internal/graphcycles.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -72,7 +74,7 @@
     linkopts = select({
         "//absl:windows": [],
         "//conditions:default": ["-pthread"],
-    }),
+    }) + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":graphcycles_internal",
         "//absl/base",
@@ -92,9 +94,7 @@
     size = "small",
     srcs = ["barrier_test.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = [
-        "no_test_wasm",
-    ],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":synchronization",
         "//absl/time",
@@ -107,9 +107,7 @@
     size = "small",
     srcs = ["blocking_counter_test.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = [
-        "no_test_wasm",
-    ],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":synchronization",
         "//absl/time",
@@ -122,6 +120,7 @@
     size = "medium",
     srcs = ["internal/graphcycles_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":graphcycles_internal",
         "//absl/base",
@@ -134,6 +133,7 @@
     name = "graphcycles_benchmark",
     srcs = ["internal/graphcycles_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = [
         "benchmark",
     ],
@@ -148,6 +148,7 @@
     name = "thread_pool",
     testonly = 1,
     hdrs = ["internal/thread_pool.h"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:__subpackages__",
     ],
@@ -162,6 +163,7 @@
     size = "large",
     srcs = ["mutex_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     shard_count = 25,
     deps = [
         ":synchronization",
@@ -179,6 +181,7 @@
     testonly = 1,
     srcs = ["mutex_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl/synchronization:__pkg__",
     ],
@@ -195,6 +198,7 @@
     name = "mutex_benchmark",
     testonly = 1,
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
         ":mutex_benchmark_common",
@@ -206,6 +210,7 @@
     size = "small",
     srcs = ["notification_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":synchronization",
         "//absl/time",
@@ -218,6 +223,7 @@
     testonly = 1,
     srcs = ["internal/per_thread_sem_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":synchronization",
         "//absl/base",
@@ -232,7 +238,7 @@
     name = "per_thread_sem_test",
     size = "medium",
     copts = ABSL_TEST_COPTS,
-    tags = ["no_test_wasm"],
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":per_thread_sem_test_common",
         ":synchronization",
@@ -249,6 +255,7 @@
         "lifetime_test.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["no_test_ios_x86_64"],
     deps = [
         ":synchronization",
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index 68473b7..6fdbcb2 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -64,6 +64,7 @@
     absl::stacktrace
     absl::symbolize
     absl::time
+    Threads::Threads
   PUBLIC
 )
 
@@ -112,6 +113,8 @@
     thread_pool
   HDRS
     "internal/thread_pool.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::synchronization
     absl::core_headers
@@ -191,5 +194,4 @@
     absl::synchronization
     absl::base
     absl::core_headers
-    Threads::Threads
 )
diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc
index 74b0965..f17ea56 100644
--- a/absl/synchronization/internal/waiter.cc
+++ b/absl/synchronization/internal/waiter.cc
@@ -40,6 +40,8 @@
 #include <atomic>
 #include <cassert>
 #include <cstdint>
+#include <new>
+#include <type_traits>
 
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/thread_identity.h"
@@ -328,6 +330,43 @@
 
 #elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_WIN32
 
+class Waiter::WinHelper {
+ public:
+  static SRWLOCK *GetLock(Waiter *w) {
+    return reinterpret_cast<SRWLOCK *>(&w->mu_storage_);
+  }
+
+  static CONDITION_VARIABLE *GetCond(Waiter *w) {
+    return reinterpret_cast<CONDITION_VARIABLE *>(&w->cv_storage_);
+  }
+
+  static_assert(sizeof(SRWLOCK) == sizeof(Waiter::SRWLockStorage),
+                "SRWLockStorage does not have the same size as SRWLOCK");
+  static_assert(
+      alignof(SRWLOCK) == alignof(Waiter::SRWLockStorage),
+      "SRWLockStorage does not have the same alignment as SRWLOCK");
+
+  static_assert(sizeof(CONDITION_VARIABLE) ==
+                    sizeof(Waiter::ConditionVariableStorage),
+                "ABSL_CONDITION_VARIABLE_STORAGE does not have the same size "
+                "as CONDITION_VARIABLE");
+  static_assert(alignof(CONDITION_VARIABLE) ==
+                    alignof(Waiter::ConditionVariableStorage),
+                "ConditionVariableStorage does not have the same "
+                "alignment as CONDITION_VARIABLE");
+
+  // The SRWLOCK and CONDITION_VARIABLE types must be trivially constuctible
+  // and destructible because we never call their constructors or destructors.
+  static_assert(std::is_trivially_constructible<SRWLOCK>::value,
+                "The SRWLOCK type must be trivially constructible");
+  static_assert(std::is_trivially_constructible<CONDITION_VARIABLE>::value,
+                "The CONDITION_VARIABLE type must be trivially constructible");
+  static_assert(std::is_trivially_destructible<SRWLOCK>::value,
+                "The SRWLOCK type must be trivially destructible");
+  static_assert(std::is_trivially_destructible<CONDITION_VARIABLE>::value,
+                "The CONDITION_VARIABLE type must be trivially destructible");
+};
+
 class LockHolder {
  public:
   explicit LockHolder(SRWLOCK* mu) : mu_(mu) {
@@ -346,14 +385,19 @@
 };
 
 void Waiter::Init() {
-  InitializeSRWLock(&mu_);
-  InitializeConditionVariable(&cv_);
+  auto *mu = ::new (static_cast<void *>(&mu_storage_)) SRWLOCK;
+  auto *cv = ::new (static_cast<void *>(&cv_storage_)) CONDITION_VARIABLE;
+  InitializeSRWLock(mu);
+  InitializeConditionVariable(cv);
   waiter_count_.store(0, std::memory_order_relaxed);
   wakeup_count_.store(0, std::memory_order_relaxed);
 }
 
 bool Waiter::Wait(KernelTimeout t) {
-  LockHolder h(&mu_);
+  SRWLOCK *mu = WinHelper::GetLock(this);
+  CONDITION_VARIABLE *cv = WinHelper::GetCond(this);
+
+  LockHolder h(mu);
   waiter_count_.fetch_add(1, std::memory_order_relaxed);
 
   // Loop until we find a wakeup to consume or timeout.
@@ -371,8 +415,7 @@
     }
 
     // No wakeups available, time to wait.
-    if (!SleepConditionVariableSRW(
-            &cv_, &mu_, t.InMillisecondsFromNow(), 0)) {
+    if (!SleepConditionVariableSRW(cv, mu, t.InMillisecondsFromNow(), 0)) {
       // GetLastError() returns a Win32 DWORD, but we assign to
       // unsigned long to simplify the ABSL_RAW_LOG case below.  The uniform
       // initialization guarantees this is not a narrowing conversion.
@@ -399,11 +442,11 @@
     return;
   }
   // Potentially a waker. Take the lock and check again.
-  LockHolder h(&mu_);
+  LockHolder h(WinHelper::GetLock(this));
   if (waiter_count_.load(std::memory_order_relaxed) == 0) {
     return;
   }
-  WakeConditionVariable(&cv_);
+  WakeConditionVariable(WinHelper::GetCond(this));
 }
 
 #else
diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h
index 66b4beb..a3e3124 100644
--- a/absl/synchronization/internal/waiter.h
+++ b/absl/synchronization/internal/waiter.h
@@ -18,9 +18,7 @@
 
 #include "absl/base/config.h"
 
-#ifdef _WIN32
-#include <windows.h>
-#else
+#ifndef _WIN32
 #include <pthread.h>
 #endif
 
@@ -123,8 +121,20 @@
   // primivitives.  We are using SRWLOCK and CONDITION_VARIABLE
   // because they don't require a destructor to release system
   // resources.
-  SRWLOCK mu_;
-  CONDITION_VARIABLE cv_;
+  //
+  // However, we can't include Windows.h in our headers, so we use aligned
+  // storage buffers to define the storage.
+  using SRWLockStorage =
+      typename std::aligned_storage<sizeof(void*), alignof(void*)>::type;
+  using ConditionVariableStorage =
+      typename std::aligned_storage<sizeof(void*), alignof(void*)>::type;
+
+  // WinHelper - Used to define utilities for accessing the lock and
+  // condition variable storage once the types are complete.
+  class WinHelper;
+
+  SRWLockStorage mu_storage_;
+  ConditionVariableStorage cv_storage_;
   std::atomic<int> waiter_count_;
   std::atomic<int> wakeup_count_;
 
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel
index a94be65..55e83a8 100644
--- a/absl/time/BUILD.bazel
+++ b/absl/time/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -41,6 +42,7 @@
         "time.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base",
         "//absl/base:core_headers",
@@ -60,6 +62,7 @@
     ],
     hdrs = ["internal/test_util.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl/time:__pkg__",
     ],
@@ -82,6 +85,7 @@
         "time_zone_test.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":test_util",
         ":time",
@@ -103,6 +107,7 @@
         "time_benchmark.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = [
         "benchmark",
     ],
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel
index 903499b..b05c234 100644
--- a/absl/time/internal/cctz/BUILD.bazel
+++ b/absl/time/internal/cctz/BUILD.bazel
@@ -16,6 +16,20 @@
 
 licenses(["notice"])  # Apache License
 
+config_setting(
+    name = "osx",
+    constraint_values = [
+        "@bazel_tools//platforms:osx",
+    ],
+)
+
+config_setting(
+    name = "ios",
+    constraint_values = [
+        "@bazel_tools//platforms:ios",
+    ],
+)
+
 ### libraries
 
 cc_library(
@@ -62,6 +76,15 @@
         "include/cctz/time_zone.h",
         "include/cctz/zone_info_source.h",
     ],
+    linkopts = select({
+        ":osx": [
+            "-framework Foundation",
+        ],
+        ":ios": [
+            "-framework Foundation",
+        ],
+        "//conditions:default": [],
+    }),
     visibility = ["//visibility:public"],
     deps = [":civil_time"],
 )
@@ -87,7 +110,6 @@
         "no_test_android_arm",
         "no_test_android_arm64",
         "no_test_android_x86",
-        "no_test_wasm",
     ],
     deps = [
         ":civil_time",
@@ -106,7 +128,6 @@
         "no_test_android_arm",
         "no_test_android_arm64",
         "no_test_android_x86",
-        "no_test_wasm",
     ],
     deps = [
         ":civil_time",
diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
index a5923f1..bb191b3 100644
--- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h
+++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
@@ -21,7 +21,7 @@
 #include <type_traits>
 
 // Disable constexpr support unless we are in C++14 mode.
-#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
 #define CONSTEXPR_D constexpr  // data
 #define CONSTEXPR_F constexpr  // function
 #define CONSTEXPR_M constexpr  // member
diff --git a/absl/time/internal/cctz/src/civil_time_test.cc b/absl/time/internal/cctz/src/civil_time_test.cc
index e590ee3..dc7e5a1 100644
--- a/absl/time/internal/cctz/src/civil_time_test.cc
+++ b/absl/time/internal/cctz/src/civil_time_test.cc
@@ -37,7 +37,7 @@
 
 }  // namespace
 
-#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
 // Construction constexpr tests
 
 TEST(CivilTime, Normal) {
@@ -319,7 +319,7 @@
   constexpr int yd = get_yearday(cd);
   static_assert(yd == 28, "YearDay");
 }
-#endif  // __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#endif  // __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
 
 // The remaining tests do not use constexpr.
 
diff --git a/absl/time/internal/cctz/src/time_zone_lookup.cc b/absl/time/internal/cctz/src/time_zone_lookup.cc
index fd04e2d..3c53dd1 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup.cc
@@ -16,13 +16,14 @@
 
 #if defined(__ANDROID__)
 #include <sys/system_properties.h>
-#if __ANDROID_API__ >= 21
+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
 #include <dlfcn.h>
 #endif
 #endif
 
 #if defined(__APPLE__)
 #include <CoreFoundation/CFTimeZone.h>
+#include <vector>
 #endif
 
 #include <cstdlib>
@@ -36,7 +37,7 @@
 namespace time_internal {
 namespace cctz {
 
-#if defined(__ANDROID__) && __ANDROID_API__ >= 21
+#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
 namespace {
 // Android 'L' removes __system_property_get() from the NDK, however
 // it is still a hidden symbol in libc so we use dlsym() to access it.
@@ -121,25 +122,33 @@
 
 time_zone local_time_zone() {
   const char* zone = ":localtime";
+#if defined(__ANDROID__)
+  char sysprop[PROP_VALUE_MAX];
+  if (__system_property_get("persist.sys.timezone", sysprop) > 0) {
+    zone = sysprop;
+  }
+#endif
+#if defined(__APPLE__)
+  std::vector<char> buffer;
+  CFTimeZoneRef tz_default = CFTimeZoneCopyDefault();
+  if (CFStringRef tz_name = CFTimeZoneGetName(tz_default)) {
+    CFStringEncoding encoding = kCFStringEncodingUTF8;
+    CFIndex length = CFStringGetLength(tz_name);
+    buffer.resize(CFStringGetMaximumSizeForEncoding(length, encoding) + 1);
+    if (CFStringGetCString(tz_name, &buffer[0], buffer.size(), encoding)) {
+      zone = &buffer[0];
+    }
+  }
+  CFRelease(tz_default);
+#endif
 
   // Allow ${TZ} to override to default zone.
   char* tz_env = nullptr;
 #if defined(_MSC_VER)
   _dupenv_s(&tz_env, nullptr, "TZ");
-#elif defined(__APPLE__)
-  CFTimeZoneRef system_time_zone = CFTimeZoneCopyDefault();
-  CFStringRef tz_name = CFTimeZoneGetName(system_time_zone);
-  tz_env = strdup(CFStringGetCStringPtr(tz_name, CFStringGetSystemEncoding()));
-  CFRelease(system_time_zone);
 #else
   tz_env = std::getenv("TZ");
 #endif
-#if defined(__ANDROID__)
-  char sysprop[PROP_VALUE_MAX];
-  if (tz_env == nullptr)
-    if (__system_property_get("persist.sys.timezone", sysprop) > 0)
-      tz_env = sysprop;
-#endif
   if (tz_env) zone = tz_env;
 
   // We only support the "[:]<zone-name>" form.
@@ -163,8 +172,6 @@
 #if defined(_MSC_VER)
   free(localtime_env);
   free(tz_env);
-#elif defined(__APPLE__)
-  free(tz_env);
 #endif
 
   time_zone tz;
diff --git a/absl/time/internal/cctz/src/tzfile.h b/absl/time/internal/cctz/src/tzfile.h
index 4485ba5..ef3feff 100644
--- a/absl/time/internal/cctz/src/tzfile.h
+++ b/absl/time/internal/cctz/src/tzfile.h
@@ -33,6 +33,9 @@
 #define TZDEFRULES	"posixrules"
 #endif /* !defined TZDEFRULES */
 
+
+/* See Internet RFC 8536 for more details about the following format.  */
+
 /*
 ** Each file begins with. . .
 */
diff --git a/absl/time/internal/cctz/testdata/version b/absl/time/internal/cctz/testdata/version
index 63f5800..149d790 100644
--- a/absl/time/internal/cctz/testdata/version
+++ b/absl/time/internal/cctz/testdata/version
@@ -1 +1 @@
-2018i
+2019a
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla
index 85a7e16..1e94be3 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza
index cf54deb..32b4ed6 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron
index 09c876a..0ed8b0d 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem
index 2d14c99..93e9f19 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv
index 2d14c99..93e9f19 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT
index a88c4b6..5583f5b 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Israel b/absl/time/internal/cctz/testdata/zoneinfo/Israel
index 2d14c99..93e9f19 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Israel
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Israel
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/UCT b/absl/time/internal/cctz/testdata/zoneinfo/UCT
index a88c4b6..5583f5b 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/UCT
+++ b/absl/time/internal/cctz/testdata/zoneinfo/UCT
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab b/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab
index 4e4a5c3..a4ff61a 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab
+++ b/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab
@@ -9,7 +9,7 @@
 # All text uses UTF-8 encoding.  The columns of the table are as follows:
 #
 # 1.  ISO 3166-1 alpha-2 country code, current as of
-#     ISO 3166-1 N905 (2016-11-15).  See: Updates on ISO 3166-1
+#     ISO 3166-1 N976 (2018-11-06).  See: Updates on ISO 3166-1
 #     https://isotc.iso.org/livelink/livelink/Open/16944257
 # 2.  The usual English name for the coded region,
 #     chosen so that alphabetic sorting of subsets produces helpful lists.
@@ -166,7 +166,7 @@
 MF	St Martin (French)
 MG	Madagascar
 MH	Marshall Islands
-MK	Macedonia
+MK	North Macedonia
 ML	Mali
 MM	Myanmar (Burma)
 MN	Mongolia
@@ -235,7 +235,7 @@
 SV	El Salvador
 SX	St Maarten (Dutch)
 SY	Syria
-SZ	Swaziland
+SZ	Eswatini (Swaziland)
 TC	Turks & Caicos Is
 TD	Chad
 TF	French Southern & Antarctic Lands
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 74148d5..4d791f4 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -28,7 +28,7 @@
 
 namespace {
 
-#if GTEST_USES_SIMPLE_RE
+#if defined(GTEST_USES_SIMPLE_RE) && GTEST_USES_SIMPLE_RE
 const char kZoneAbbrRE[] = ".*";  // just punt
 #else
 const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?";
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index 7da0003..a254871 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -17,6 +17,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
     "ABSL_EXCEPTIONS_FLAG",
     "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
@@ -30,6 +31,7 @@
     name = "any",
     hdrs = ["any.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":bad_any_cast",
         "//absl/base:config",
@@ -43,6 +45,7 @@
     name = "bad_any_cast",
     hdrs = ["bad_any_cast.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":bad_any_cast_impl",
         "//absl/base:config",
@@ -56,7 +59,7 @@
         "bad_any_cast.h",
     ],
     copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
         "//absl/base",
@@ -71,7 +74,7 @@
         "any_test.cc",
     ],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":any",
         "//absl/base",
@@ -89,6 +92,7 @@
         "any_test.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":any",
         "//absl/base",
@@ -103,7 +107,7 @@
     name = "any_exception_safety_test",
     srcs = ["any_exception_safety_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":any",
         "//absl/base:exception_safety_testing",
@@ -113,8 +117,14 @@
 
 cc_library(
     name = "span",
-    hdrs = ["span.h"],
+    srcs = [
+        "internal/span.h",
+    ],
+    hdrs = [
+        "span.h",
+    ],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/algorithm",
         "//absl/base:core_headers",
@@ -128,7 +138,7 @@
     size = "small",
     srcs = ["span_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":span",
         "//absl/base:config",
@@ -147,6 +157,7 @@
     size = "small",
     srcs = ["span_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":span",
         "//absl/base:config",
@@ -162,11 +173,13 @@
 
 cc_library(
     name = "optional",
-    srcs = ["optional.cc"],
+    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/memory",
@@ -180,7 +193,7 @@
     srcs = ["bad_optional_access.cc"],
     hdrs = ["bad_optional_access.h"],
     copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base",
         "//absl/base:config",
@@ -192,7 +205,7 @@
     srcs = ["bad_variant_access.cc"],
     hdrs = ["bad_variant_access.h"],
     copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base",
         "//absl/base:config",
@@ -206,7 +219,7 @@
         "optional_test.cc",
     ],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":optional",
         "//absl/base",
@@ -223,7 +236,7 @@
         "optional_exception_safety_test.cc",
     ],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":optional",
         "//absl/base:exception_safety_testing",
@@ -236,6 +249,7 @@
     srcs = ["internal/variant.h"],
     hdrs = ["variant.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":bad_variant_access",
         "//absl/base:base_internal",
@@ -251,7 +265,7 @@
     size = "small",
     srcs = ["variant_test.cc"],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":variant",
         "//absl/base:config",
@@ -269,6 +283,7 @@
         "variant_benchmark.cc",
     ],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     tags = ["benchmark"],
     deps = [
         ":variant",
@@ -284,7 +299,7 @@
         "variant_exception_safety_test.cc",
     ],
     copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
-    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+    linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":variant",
         "//absl/base:config",
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt
index 8afde46..9da94eb 100644
--- a/absl/types/CMakeLists.txt
+++ b/absl/types/CMakeLists.txt
@@ -114,6 +114,8 @@
     span
   HDRS
     "span.h"
+  SRCS
+    "internal/span.h"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
@@ -173,11 +175,12 @@
   HDRS
     "optional.h"
   SRCS
-    "optional.cc"
+    "internal/optional.h"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::bad_optional_access
+    absl::base_internal
     absl::config
     absl::core_headers
     absl::memory
@@ -297,7 +300,8 @@
 )
 
 # TODO(cohenjon,zhangxy) Figure out why this test is failing on gcc 4.8
-if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
+else()
 absl_cc_test(
   NAME
     variant_exception_safety_test
diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc
index a6351bf..8710472 100644
--- a/absl/types/any_test.cc
+++ b/absl/types/any_test.cc
@@ -154,6 +154,14 @@
   EXPECT_EQ(5, v.value);
 }
 
+TEST(AnyTest, InPlaceConstructionVariableTemplate) {
+  const CopyOnly copy_only{};
+  absl::any o(absl::in_place_type<IntMoveOnlyCopyOnly>, 5, MoveOnly(),
+              copy_only);
+  auto& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
+  EXPECT_EQ(5, v.value);
+}
+
 TEST(AnyTest, InPlaceConstructionWithCV) {
   const CopyOnly copy_only{};
   absl::any o(absl::in_place_type_t<const volatile IntMoveOnlyCopyOnly>(), 5,
@@ -162,12 +170,26 @@
   EXPECT_EQ(5, v.value);
 }
 
+TEST(AnyTest, InPlaceConstructionWithCVVariableTemplate) {
+  const CopyOnly copy_only{};
+  absl::any o(absl::in_place_type<const volatile IntMoveOnlyCopyOnly>, 5,
+              MoveOnly(), copy_only);
+  auto& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
+  EXPECT_EQ(5, v.value);
+}
+
 TEST(AnyTest, InPlaceConstructionWithFunction) {
   absl::any o(absl::in_place_type_t<FunctionType>(), FunctionToEmplace);
   FunctionType*& construction_result = absl::any_cast<FunctionType*&>(o);
   EXPECT_EQ(&FunctionToEmplace, construction_result);
 }
 
+TEST(AnyTest, InPlaceConstructionWithFunctionVariableTemplate) {
+  absl::any o(absl::in_place_type<FunctionType>, FunctionToEmplace);
+  auto& construction_result = absl::any_cast<FunctionType*&>(o);
+  EXPECT_EQ(&FunctionToEmplace, construction_result);
+}
+
 TEST(AnyTest, InPlaceConstructionWithArray) {
   ArrayType ar = {5, 42};
   absl::any o(absl::in_place_type_t<ArrayType>(), ar);
@@ -175,6 +197,13 @@
   EXPECT_EQ(&ar[0], construction_result);
 }
 
+TEST(AnyTest, InPlaceConstructionWithArrayVariableTemplate) {
+  ArrayType ar = {5, 42};
+  absl::any o(absl::in_place_type<ArrayType>, ar);
+  auto& construction_result = absl::any_cast<DecayedArray&>(o);
+  EXPECT_EQ(&ar[0], construction_result);
+}
+
 TEST(AnyTest, InPlaceConstructionIlist) {
   const CopyOnly copy_only{};
   absl::any o(absl::in_place_type_t<ListMoveOnlyCopyOnly>(), {1, 2, 3, 4},
@@ -184,6 +213,15 @@
   EXPECT_EQ(expected_values, v.values);
 }
 
+TEST(AnyTest, InPlaceConstructionIlistVariableTemplate) {
+  const CopyOnly copy_only{};
+  absl::any o(absl::in_place_type<ListMoveOnlyCopyOnly>, {1, 2, 3, 4},
+              MoveOnly(), copy_only);
+  auto& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
+  std::vector<int> expected_values = {1, 2, 3, 4};
+  EXPECT_EQ(expected_values, v.values);
+}
+
 TEST(AnyTest, InPlaceConstructionIlistWithCV) {
   const CopyOnly copy_only{};
   absl::any o(absl::in_place_type_t<const volatile ListMoveOnlyCopyOnly>(),
@@ -193,11 +231,25 @@
   EXPECT_EQ(expected_values, v.values);
 }
 
+TEST(AnyTest, InPlaceConstructionIlistWithCVVariableTemplate) {
+  const CopyOnly copy_only{};
+  absl::any o(absl::in_place_type<const volatile ListMoveOnlyCopyOnly>,
+              {1, 2, 3, 4}, MoveOnly(), copy_only);
+  auto& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
+  std::vector<int> expected_values = {1, 2, 3, 4};
+  EXPECT_EQ(expected_values, v.values);
+}
+
 TEST(AnyTest, InPlaceNoArgs) {
   absl::any o(absl::in_place_type_t<int>{});
   EXPECT_EQ(0, absl::any_cast<int&>(o));
 }
 
+TEST(AnyTest, InPlaceNoArgsVariableTemplate) {
+  absl::any o(absl::in_place_type<int>);
+  EXPECT_EQ(0, absl::any_cast<int&>(o));
+}
+
 template <typename Enabler, typename T, typename... Args>
 struct CanEmplaceAnyImpl : std::false_type {};
 
@@ -501,7 +553,7 @@
   InstanceTracker tracker_raii;
 
   {
-    absl::any o(absl::in_place_type_t<CopyableOnlyInstance>{}, 123);
+    absl::any o(absl::in_place_type<CopyableOnlyInstance>, 123);
     CopyableOnlyInstance* f1 = absl::any_cast<CopyableOnlyInstance>(&o);
 
     absl::any o2(o);
@@ -622,7 +674,7 @@
   }
 
   {
-    absl::any a(absl::in_place_type_t<int>{});
+    absl::any a(absl::in_place_type<int>);
     ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&>(a));
     ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float&>(a));
     ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&&>(absl::any{}));
@@ -665,7 +717,7 @@
   }
 
   {
-    absl::any src(absl::in_place_type_t<BadCopyable>{});
+    absl::any src(absl::in_place_type<BadCopyable>);
     ABSL_ANY_TEST_EXPECT_BAD_COPY(absl::any{src});
   }
 
@@ -677,21 +729,21 @@
 
   {
     BadCopyable bad;
-    absl::any target(absl::in_place_type_t<BadCopyable>{});
+    absl::any target(absl::in_place_type<BadCopyable>);
     ABSL_ANY_TEST_EXPECT_BAD_COPY(target = bad);
     EXPECT_TRUE(target.has_value());
   }
 
   {
-    absl::any src(absl::in_place_type_t<BadCopyable>{});
+    absl::any src(absl::in_place_type<BadCopyable>);
     absl::any target;
     ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src);
     EXPECT_FALSE(target.has_value());
   }
 
   {
-    absl::any src(absl::in_place_type_t<BadCopyable>{});
-    absl::any target(absl::in_place_type_t<BadCopyable>{});
+    absl::any src(absl::in_place_type<BadCopyable>);
+    absl::any target(absl::in_place_type<BadCopyable>);
     ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src);
     EXPECT_TRUE(target.has_value());
   }
@@ -707,7 +759,7 @@
 
   {
     BadCopyable bad;
-    absl::any target(absl::in_place_type_t<int>{});
+    absl::any target(absl::in_place_type<int>);
     ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(bad));
 #if defined(ABSL_HAVE_STD_ANY) && defined(__GLIBCXX__)
     // libstdc++ std::any::emplace() implementation (as of 7.2) has a bug: if an
diff --git a/absl/types/internal/optional.h b/absl/types/internal/optional.h
new file mode 100644
index 0000000..8acbda2
--- /dev/null
+++ b/absl/types/internal/optional.h
@@ -0,0 +1,394 @@
+// 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/base/internal/inline_variable.h"
+#include "absl/memory/memory.h"
+#include "absl/meta/type_traits.h"
+#include "absl/utility/utility.h"
+
+// ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
+//
+// Inheriting constructors is supported in GCC 4.8+, Clang 3.3+ and MSVC 2015.
+// __cpp_inheriting_constructors is a predefined macro and a recommended way to
+// check for this language feature, but GCC doesn't support it until 5.0 and
+// Clang doesn't support it until 3.6.
+// Also, MSVC 2015 has a bug: it doesn't inherit the constexpr template
+// constructor. For example, the following code won't work on MSVC 2015 Update3:
+// struct Base {
+//   int t;
+//   template <typename T>
+//   constexpr Base(T t_) : t(t_) {}
+// };
+// struct Foo : Base {
+//   using Base::Base;
+// }
+// constexpr Foo foo(0);  // doesn't work on MSVC 2015
+#if defined(__clang__)
+#if __has_feature(cxx_inheriting_constructors)
+#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1
+#endif
+#elif (defined(__GNUC__) &&                                       \
+       (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 8)) || \
+    (__cpp_inheriting_constructors >= 200802) ||                  \
+    (defined(_MSC_VER) && _MSC_VER >= 1910)
+#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1
+#endif
+
+namespace absl {
+
+// 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 {
+    dummy_type dummy_;
+    T data_;
+  };
+
+  void destruct() noexcept {
+    if (engaged_) {
+      data_.~T();
+      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_(absl::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 {
+    dummy_type dummy_;
+    T data_;
+  };
+  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_(absl::forward<Args>(args)...) {}
+};
+
+template <typename T>
+class optional_data_base : public optional_data_dtor_base<T> {
+ protected:
+  using base = optional_data_dtor_base<T>;
+#ifdef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
+  using base::base;
+#else
+  optional_data_base() = default;
+
+  template <typename... Args>
+  constexpr explicit optional_data_base(in_place_t t, Args&&... args)
+      : base(t, absl::forward<Args>(args)...) {}
+#endif
+
+  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:
+#ifdef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
+  using optional_data_base<T>::optional_data_base;
+#else
+  optional_data() = default;
+
+  template <typename... Args>
+  constexpr explicit optional_data(in_place_t t, Args&&... args)
+      : optional_data_base<T>(t, absl::forward<Args>(args)...) {}
+#endif
+};
+
+template <typename T>
+class optional_data<T, false> : public optional_data_base<T> {
+ protected:
+#ifdef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
+  using optional_data_base<T>::optional_data_base;
+#else
+  template <typename... Args>
+  constexpr explicit optional_data(in_place_t t, Args&&... args)
+      : optional_data_base<T>(t, absl::forward<Args>(args)...) {}
+#endif
+
+  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
+}  // namespace absl
+
+#undef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
+
+#endif  // ABSL_TYPES_INTERNAL_OPTIONAL_H_
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h
new file mode 100644
index 0000000..d203aad
--- /dev/null
+++ b/absl/types/internal/span.h
@@ -0,0 +1,126 @@
+//
+// Copyright 2019 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_SPAN_H_
+#define ABSL_TYPES_INTERNAL_SPAN_H_
+
+#include <algorithm>
+#include <cstddef>
+#include <string>
+#include <type_traits>
+
+#include "absl/algorithm/algorithm.h"
+#include "absl/base/internal/throw_delegate.h"
+#include "absl/meta/type_traits.h"
+
+namespace absl {
+
+namespace span_internal {
+// A constexpr min function
+constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; }
+
+// Wrappers for access to container data pointers.
+template <typename C>
+constexpr auto GetDataImpl(C& c, char) noexcept  // NOLINT(runtime/references)
+    -> decltype(c.data()) {
+  return c.data();
+}
+
+// Before C++17, std::string::data returns a const char* in all cases.
+inline char* GetDataImpl(std::string& s,  // NOLINT(runtime/references)
+                         int) noexcept {
+  return &s[0];
+}
+
+template <typename C>
+constexpr auto GetData(C& c) noexcept  // NOLINT(runtime/references)
+    -> decltype(GetDataImpl(c, 0)) {
+  return GetDataImpl(c, 0);
+}
+
+// Detection idioms for size() and data().
+template <typename C>
+using HasSize =
+    std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;
+
+// We want to enable conversion from vector<T*> to Span<const T* const> but
+// disable conversion from vector<Derived> to Span<Base>. Here we use
+// the fact that U** is convertible to Q* const* if and only if Q is the same
+// type or a more cv-qualified version of U.  We also decay the result type of
+// data() to avoid problems with classes which have a member function data()
+// which returns a reference.
+template <typename T, typename C>
+using HasData =
+    std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
+                        T* const*>;
+
+// Extracts value type from a Container
+template <typename C>
+struct ElementType {
+  using type = typename absl::remove_reference_t<C>::value_type;
+};
+
+template <typename T, size_t N>
+struct ElementType<T (&)[N]> {
+  using type = T;
+};
+
+template <typename C>
+using ElementT = typename ElementType<C>::type;
+
+template <typename T>
+using EnableIfMutable =
+    typename std::enable_if<!std::is_const<T>::value, int>::type;
+
+template <template <typename> class SpanT, typename T>
+bool EqualImpl(SpanT<T> a, SpanT<T> b) {
+  static_assert(std::is_const<T>::value, "");
+  return absl::equal(a.begin(), a.end(), b.begin(), b.end());
+}
+
+template <template <typename> class SpanT, typename T>
+bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
+  // We can't use value_type since that is remove_cv_t<T>, so we go the long way
+  // around.
+  static_assert(std::is_const<T>::value, "");
+  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
+}
+
+// The `IsConvertible` classes here are needed because of the
+// `std::is_convertible` bug in libcxx when compiled with GCC. This build
+// configuration is used by Android NDK toolchain. Reference link:
+// https://bugs.llvm.org/show_bug.cgi?id=27538.
+template <typename From, typename To>
+struct IsConvertibleHelper {
+ private:
+  static std::true_type testval(To);
+  static std::false_type testval(...);
+
+ public:
+  using type = decltype(testval(std::declval<From>()));
+};
+
+template <typename From, typename To>
+struct IsConvertible : IsConvertibleHelper<From, To>::type {};
+
+// TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the
+// older version of libcxx is not supported.
+template <typename From, typename To>
+using EnableIfConvertibleTo =
+    typename std::enable_if<IsConvertible<From, To>::value>::type;
+}  // namespace span_internal
+}  // namespace absl
+
+#endif  // ABSL_TYPES_INTERNAL_SPAN_H_
diff --git a/absl/types/optional.h b/absl/types/optional.h
index f0ae9a1..5798331 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -35,8 +35,7 @@
 #ifndef ABSL_TYPES_OPTIONAL_H_
 #define ABSL_TYPES_OPTIONAL_H_
 
-#include "absl/base/config.h"
-#include "absl/memory/memory.h"
+#include "absl/base/config.h"   // TODO(calabrese) IWYU removal?
 #include "absl/utility/utility.h"
 
 #ifdef ABSL_HAVE_STD_OPTIONAL
@@ -56,44 +55,33 @@
 #include <cassert>
 #include <functional>
 #include <initializer_list>
-#include <new>
 #include <type_traits>
 #include <utility>
 
 #include "absl/base/attributes.h"
+#include "absl/base/internal/inline_variable.h"
 #include "absl/meta/type_traits.h"
 #include "absl/types/bad_optional_access.h"
-
-// ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
-//
-// Inheriting constructors is supported in GCC 4.8+, Clang 3.3+ and MSVC 2015.
-// __cpp_inheriting_constructors is a predefined macro and a recommended way to
-// check for this language feature, but GCC doesn't support it until 5.0 and
-// Clang doesn't support it until 3.6.
-// Also, MSVC 2015 has a bug: it doesn't inherit the constexpr template
-// constructor. For example, the following code won't work on MSVC 2015 Update3:
-// struct Base {
-//   int t;
-//   template <typename T>
-//   constexpr Base(T t_) : t(t_) {}
-// };
-// struct Foo : Base {
-//   using Base::Base;
-// }
-// constexpr Foo foo(0);  // doesn't work on MSVC 2015
-#if defined(__clang__)
-#if __has_feature(cxx_inheriting_constructors)
-#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1
-#endif
-#elif (defined(__GNUC__) &&                                       \
-       (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 8)) || \
-    (__cpp_inheriting_constructors >= 200802) ||                  \
-    (defined(_MSC_VER) && _MSC_VER >= 1910)
-#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1
-#endif
+#include "absl/types/internal/optional.h"
 
 namespace absl {
 
+// 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.
+ABSL_INTERNAL_INLINE_CONSTEXPR(nullopt_t, nullopt,
+                               nullopt_t(optional_internal::init_t()));
+
 // -----------------------------------------------------------------------------
 // absl::optional
 // -----------------------------------------------------------------------------
@@ -123,363 +111,7 @@
 //       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;
-
-// nullopt_t
 //
-// Class type for `absl::nullopt` used to indicate an `absl::optional<T>` type
-// that does not contain a value.
-struct nullopt_t {
-  struct init_t {};
-  static init_t init;
-
-  // It must not be default-constructible to avoid ambiguity for opt = {}.
-  // Note the non-const reference, which is to eliminate ambiguity for code
-  // like:
-  //
-  // struct S { int value; };
-  //
-  // void Test() {
-  //   optional<S> opt;
-  //   opt = {{}};
-  // }
-  explicit constexpr nullopt_t(init_t& /*unused*/) {}
-};
-
-// nullopt
-//
-// A tag constant of type `absl::nullopt_t` used to indicate an empty
-// `absl::optional` in certain functions, such as construction or assignment.
-extern const nullopt_t nullopt;
-
-namespace optional_internal {
-
-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 {
-    dummy_type dummy_;
-    T data_;
-  };
-
-  void destruct() noexcept {
-    if (engaged_) {
-      data_.~T();
-      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_(absl::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 {
-    dummy_type dummy_;
-    T data_;
-  };
-  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_(absl::forward<Args>(args)...) {}
-};
-
-template <typename T>
-class optional_data_base : public optional_data_dtor_base<T> {
- protected:
-  using base = optional_data_dtor_base<T>;
-#if ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
-  using base::base;
-#else
-  optional_data_base() = default;
-
-  template <typename... Args>
-  constexpr explicit optional_data_base(in_place_t t, Args&&... args)
-      : base(t, absl::forward<Args>(args)...) {}
-#endif
-
-  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:
-#if ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
-  using optional_data_base<T>::optional_data_base;
-#else
-  optional_data() = default;
-
-  template <typename... Args>
-  constexpr explicit optional_data(in_place_t t, Args&&... args)
-      : optional_data_base<T>(t, absl::forward<Args>(args)...) {}
-#endif
-};
-
-template <typename T>
-class optional_data<T, false> : public optional_data_base<T> {
- protected:
-#if ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
-  using optional_data_base<T>::optional_data_base;
-#else
-  template <typename... Args>
-  constexpr explicit optional_data(in_place_t t, Args&&... args)
-      : optional_data_base<T>(t, absl::forward<Args>(args)...) {}
-#endif
-
-  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::optional class definition
-// -----------------------------------------------------------------------------
-
 template <typename T>
 class optional : private optional_internal::optional_data<T>,
                  private optional_internal::optional_ctor_base<
@@ -1131,7 +763,6 @@
 
 }  // namespace std
 
-#undef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
 #undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS
 
 #endif  // ABSL_HAVE_STD_OPTIONAL
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
index 0665488..221c314 100644
--- a/absl/types/optional_test.cc
+++ b/absl/types/optional_test.cc
@@ -179,15 +179,7 @@
 TEST(optionalTest, nulloptConstructor) {
   absl::optional<int> empty(absl::nullopt);
   EXPECT_FALSE(empty);
-
-#ifdef ABSL_HAVE_STD_OPTIONAL
   constexpr absl::optional<int> cempty{absl::nullopt};
-#else
-  // Creating a temporary absl::nullopt_t object instead of using absl::nullopt
-  // because absl::nullopt cannot be constexpr and have external linkage at the
-  // same time.
-  constexpr absl::optional<int> cempty{absl::nullopt_t(absl::nullopt_t::init)};
-#endif
   static_assert(!cempty.has_value(), "");
   EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>,
                                              absl::nullopt_t>::value));
@@ -1636,7 +1628,6 @@
   EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
 }
 
-#if !defined(ABSL_HAVE_STD_OPTIONAL) && !defined(_LIBCPP_VERSION)
 struct NestedClassBug {
   struct Inner {
     bool dummy = false;
@@ -1659,6 +1650,5 @@
   o.emplace();
   EXPECT_TRUE(o.has_value());
 }
-#endif  // !defined(ABSL_HAVE_STD_OPTIONAL) && !defined(_LIBCPP_VERSION)
 
 }  // namespace
diff --git a/absl/types/span.h b/absl/types/span.h
index d7f48d9..b007fc1 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -60,115 +60,18 @@
 #include <cstddef>
 #include <initializer_list>
 #include <iterator>
-#include <string>
 #include <type_traits>
 #include <utility>
 
-#include "absl/algorithm/algorithm.h"
 #include "absl/base/internal/throw_delegate.h"
 #include "absl/base/macros.h"
 #include "absl/base/optimization.h"
-#include "absl/base/port.h"
+#include "absl/base/port.h"    // TODO(strel): remove this include
 #include "absl/meta/type_traits.h"
+#include "absl/types/internal/span.h"
 
 namespace absl {
 
-template <typename T>
-class Span;
-
-namespace span_internal {
-// A constexpr min function
-constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; }
-
-// Wrappers for access to container data pointers.
-template <typename C>
-constexpr auto GetDataImpl(C& c, char) noexcept  // NOLINT(runtime/references)
-    -> decltype(c.data()) {
-  return c.data();
-}
-
-// Before C++17, std::string::data returns a const char* in all cases.
-inline char* GetDataImpl(std::string& s,  // NOLINT(runtime/references)
-                         int) noexcept {
-  return &s[0];
-}
-
-template <typename C>
-constexpr auto GetData(C& c) noexcept  // NOLINT(runtime/references)
-    -> decltype(GetDataImpl(c, 0)) {
-  return GetDataImpl(c, 0);
-}
-
-// Detection idioms for size() and data().
-template <typename C>
-using HasSize =
-    std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;
-
-// We want to enable conversion from vector<T*> to Span<const T* const> but
-// disable conversion from vector<Derived> to Span<Base>. Here we use
-// the fact that U** is convertible to Q* const* if and only if Q is the same
-// type or a more cv-qualified version of U.  We also decay the result type of
-// data() to avoid problems with classes which have a member function data()
-// which returns a reference.
-template <typename T, typename C>
-using HasData =
-    std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
-                        T* const*>;
-
-// Extracts value type from a Container
-template <typename C>
-struct ElementType {
-  using type = typename absl::remove_reference_t<C>::value_type;
-};
-
-template <typename T, size_t N>
-struct ElementType<T (&)[N]> {
-  using type = T;
-};
-
-template <typename C>
-using ElementT = typename ElementType<C>::type;
-
-template <typename T>
-using EnableIfMutable =
-    typename std::enable_if<!std::is_const<T>::value, int>::type;
-
-template <typename T>
-bool EqualImpl(Span<T> a, Span<T> b) {
-  static_assert(std::is_const<T>::value, "");
-  return absl::equal(a.begin(), a.end(), b.begin(), b.end());
-}
-
-template <typename T>
-bool LessThanImpl(Span<T> a, Span<T> b) {
-  static_assert(std::is_const<T>::value, "");
-  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
-}
-
-// The `IsConvertible` classes here are needed because of the
-// `std::is_convertible` bug in libcxx when compiled with GCC. This build
-// configuration is used by Android NDK toolchain. Reference link:
-// https://bugs.llvm.org/show_bug.cgi?id=27538.
-template <typename From, typename To>
-struct IsConvertibleHelper {
- private:
-  static std::true_type testval(To);
-  static std::false_type testval(...);
-
- public:
-  using type = decltype(testval(std::declval<From>()));
-};
-
-template <typename From, typename To>
-struct IsConvertible : IsConvertibleHelper<From, To>::type {};
-
-// TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the
-// older version of libcxx is not supported.
-template <typename From, typename To>
-using EnableIfConvertibleToSpanConst =
-    typename std::enable_if<IsConvertible<From, Span<const To>>::value>::type;
-}  // namespace span_internal
-
 //------------------------------------------------------------------------------
 // Span
 //------------------------------------------------------------------------------
@@ -551,25 +454,27 @@
 // operator==
 template <typename T>
 bool operator==(Span<T> a, Span<T> b) {
-  return span_internal::EqualImpl<const T>(a, b);
+  return span_internal::EqualImpl<Span, const T>(a, b);
 }
 template <typename T>
 bool operator==(Span<const T> a, Span<T> b) {
-  return span_internal::EqualImpl<const T>(a, b);
+  return span_internal::EqualImpl<Span, const T>(a, b);
 }
 template <typename T>
 bool operator==(Span<T> a, Span<const T> b) {
-  return span_internal::EqualImpl<const T>(a, b);
+  return span_internal::EqualImpl<Span, const T>(a, b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator==(const U& a, Span<T> b) {
-  return span_internal::EqualImpl<const T>(a, b);
+  return span_internal::EqualImpl<Span, const T>(a, b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator==(Span<T> a, const U& b) {
-  return span_internal::EqualImpl<const T>(a, b);
+  return span_internal::EqualImpl<Span, const T>(a, b);
 }
 
 // operator!=
@@ -585,13 +490,15 @@
 bool operator!=(Span<T> a, Span<const T> b) {
   return !(a == b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator!=(const U& a, Span<T> b) {
   return !(a == b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator!=(Span<T> a, const U& b) {
   return !(a == b);
 }
@@ -599,25 +506,27 @@
 // operator<
 template <typename T>
 bool operator<(Span<T> a, Span<T> b) {
-  return span_internal::LessThanImpl<const T>(a, b);
+  return span_internal::LessThanImpl<Span, const T>(a, b);
 }
 template <typename T>
 bool operator<(Span<const T> a, Span<T> b) {
-  return span_internal::LessThanImpl<const T>(a, b);
+  return span_internal::LessThanImpl<Span, const T>(a, b);
 }
 template <typename T>
 bool operator<(Span<T> a, Span<const T> b) {
-  return span_internal::LessThanImpl<const T>(a, b);
+  return span_internal::LessThanImpl<Span, const T>(a, b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator<(const U& a, Span<T> b) {
-  return span_internal::LessThanImpl<const T>(a, b);
+  return span_internal::LessThanImpl<Span, const T>(a, b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator<(Span<T> a, const U& b) {
-  return span_internal::LessThanImpl<const T>(a, b);
+  return span_internal::LessThanImpl<Span, const T>(a, b);
 }
 
 // operator>
@@ -633,13 +542,15 @@
 bool operator>(Span<T> a, Span<const T> b) {
   return b < a;
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator>(const U& a, Span<T> b) {
   return b < a;
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator>(Span<T> a, const U& b) {
   return b < a;
 }
@@ -657,13 +568,15 @@
 bool operator<=(Span<T> a, Span<const T> b) {
   return !(b < a);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator<=(const U& a, Span<T> b) {
   return !(b < a);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator<=(Span<T> a, const U& b) {
   return !(b < a);
 }
@@ -681,13 +594,15 @@
 bool operator>=(Span<T> a, Span<const T> b) {
   return !(a < b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator>=(const U& a, Span<T> b) {
   return !(a < b);
 }
-template <typename T, typename U,
-          typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+    typename T, typename U,
+    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
 bool operator>=(Span<T> a, const U& b) {
   return !(a < b);
 }
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc
index ab40ed2..b9c9811 100644
--- a/absl/types/variant_test.cc
+++ b/absl/types/variant_test.cc
@@ -384,7 +384,7 @@
 TEST(VariantTest, TestMoveConstruct) {
   using V = variant<MoveOnly<class A>, MoveOnly<class B>, MoveOnly<class C>>;
 
-  V v(in_place_index_t<1>{}, 10);
+  V v(in_place_index<1>, 10);
   V v2 = absl::move(v);
   EXPECT_EQ(10, absl::get<1>(v2).value);
 }
@@ -483,6 +483,29 @@
   EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
 }
 
+TEST(VariantTest, InPlaceTypeVariableTemplate) {
+  using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
+
+  Var v1(in_place_type<int>, 7);
+  ASSERT_TRUE(absl::holds_alternative<int>(v1));
+  EXPECT_EQ(7, absl::get<int>(v1));
+
+  Var v2(in_place_type<std::string>, "ABC");
+  ASSERT_TRUE(absl::holds_alternative<std::string>(v2));
+  EXPECT_EQ("ABC", absl::get<std::string>(v2));
+
+  Var v3(in_place_type<std::string>, "ABC", 2);
+  ASSERT_TRUE(absl::holds_alternative<std::string>(v3));
+  EXPECT_EQ("AB", absl::get<std::string>(v3));
+
+  Var v4(in_place_type<NonCopyable>);
+  ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v4));
+
+  Var v5(in_place_type<std::vector<int>>, {1, 2, 3});
+  ASSERT_TRUE(absl::holds_alternative<std::vector<int>>(v5));
+  EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
+}
+
 TEST(VariantTest, InPlaceTypeInitializerList) {
   using Var =
       variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
@@ -492,6 +515,15 @@
   EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
 }
 
+TEST(VariantTest, InPlaceTypeInitializerListVariabletemplate) {
+  using Var =
+      variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
+
+  Var v1(in_place_type<MoveOnlyWithListConstructor>, {1, 2, 3, 4, 5}, 6);
+  ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
+  EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
+}
+
 TEST(VariantTest, InPlaceIndex) {
   using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
 
@@ -519,6 +551,33 @@
   EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
 }
 
+TEST(VariantTest, InPlaceIndexVariableTemplate) {
+  using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
+
+  Var v1(in_place_index<0>, 7);
+  ASSERT_TRUE(absl::holds_alternative<int>(v1));
+  EXPECT_EQ(7, absl::get<int>(v1));
+
+  Var v2(in_place_index<1>, "ABC");
+  ASSERT_TRUE(absl::holds_alternative<std::string>(v2));
+  EXPECT_EQ("ABC", absl::get<std::string>(v2));
+
+  Var v3(in_place_index<1>, "ABC", 2);
+  ASSERT_TRUE(absl::holds_alternative<std::string>(v3));
+  EXPECT_EQ("AB", absl::get<std::string>(v3));
+
+  Var v4(in_place_index<2>);
+  EXPECT_TRUE(absl::holds_alternative<NonCopyable>(v4));
+
+  // Verify that a variant with only non-copyables can still be constructed.
+  EXPECT_TRUE(absl::holds_alternative<NonCopyable>(
+      variant<NonCopyable>(in_place_index<0>)));
+
+  Var v5(in_place_index<3>, {1, 2, 3});
+  ASSERT_TRUE(absl::holds_alternative<std::vector<int>>(v5));
+  EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
+}
+
 TEST(VariantTest, InPlaceIndexInitializerList) {
   using Var =
       variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
@@ -528,6 +587,15 @@
   EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
 }
 
+TEST(VariantTest, InPlaceIndexInitializerListVariableTemplate) {
+  using Var =
+      variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
+
+  Var v1(in_place_index<3>, {1, 2, 3, 4, 5}, 6);
+  ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
+  EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
+}
+
 ////////////////////
 // [variant.dtor] //
 ////////////////////
@@ -576,7 +644,7 @@
   {
     using Variant = VariantFactory<IncrementInDtor>::Type;
 
-    Variant v(in_place_index_t<0>(), counter_adjuster);
+    Variant v(in_place_index<0>, counter_adjuster);
     EXPECT_EQ(0, counter);
 
     ToValuelessByException(v);
@@ -810,7 +878,7 @@
 TEST(VariantTest, TestEmplaceBasic) {
   using Variant = variant<int, char>;
 
-  Variant v(absl::in_place_index_t<0>{}, 0);
+  Variant v(absl::in_place_index<0>, 0);
 
   {
     char& emplace_result = v.emplace<char>();
@@ -837,7 +905,7 @@
   using Var =
       variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
 
-  Var v1(absl::in_place_index_t<0>{}, 555);
+  Var v1(absl::in_place_index<0>, 555);
   MoveOnlyWithListConstructor& emplace_result =
       v1.emplace<MoveOnlyWithListConstructor>({1, 2, 3, 4, 5}, 6);
   ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
@@ -848,7 +916,7 @@
 TEST(VariantTest, TestEmplaceIndex) {
   using Variant = variant<int, char>;
 
-  Variant v(absl::in_place_index_t<0>{}, 555);
+  Variant v(absl::in_place_index<0>, 555);
 
   {
     char& emplace_result = v.emplace<1>();
@@ -875,7 +943,7 @@
   using Var =
       variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
 
-  Var v1(absl::in_place_index_t<0>{}, 555);
+  Var v1(absl::in_place_index<0>, 555);
   MoveOnlyWithListConstructor& emplace_result =
       v1.emplace<3>({1, 2, 3, 4, 5}, 6);
   ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
@@ -924,7 +992,7 @@
 TEST(VariantTest, IndexValuelessByException) {
   using Var = variant<MoveCanThrow, std::string, double>;
 
-  Var v(absl::in_place_index_t<0>{});
+  Var v(absl::in_place_index<0>);
   EXPECT_EQ(0, v.index());
   ToValuelessByException(v);
   EXPECT_EQ(absl::variant_npos, v.index());
@@ -935,7 +1003,7 @@
 TEST(VariantTest, ValuelessByException) {
   using Var = variant<MoveCanThrow, std::string, double>;
 
-  Var v(absl::in_place_index_t<0>{});
+  Var v(absl::in_place_index<0>);
   EXPECT_FALSE(v.valueless_by_exception());
   ToValuelessByException(v);
   EXPECT_TRUE(v.valueless_by_exception());
@@ -966,7 +1034,7 @@
   using V = variant<MoveCanThrow, std::string, int>;
   int i = 33;
   std::string s = "abc";
-  V valueless(in_place_index_t<0>{});
+  V valueless(in_place_index<0>);
   ToValuelessByException(valueless);
   {
     // lhs and rhs holds different alternative
@@ -1127,7 +1195,7 @@
   using Var = variant<int, std::string, double, int>;
 
   {
-    Var v(absl::in_place_index_t<0>{}, 0);
+    Var v(absl::in_place_index<0>, 0);
 
     using LValueGetType = decltype(absl::get<0>(v));
     using RValueGetType = decltype(absl::get<0>(absl::move(v)));
@@ -1187,7 +1255,7 @@
   }
 
   {
-    Var v(absl::in_place_index_t<0>{}, 0);
+    Var v(absl::in_place_index<0>, 0);
     v.emplace<3>(1);
 
     using LValueGetType = decltype(absl::get<3>(v));
@@ -1334,7 +1402,7 @@
   using Var = variant<int, std::string, double, int>;
 
   {
-    Var v(absl::in_place_index_t<0>{}, 0);
+    Var v(absl::in_place_index<0>, 0);
     EXPECT_TRUE(noexcept(absl::get_if<0>(&v)));
 
     {
@@ -1492,7 +1560,7 @@
   }
 
   {
-    Var v(absl::in_place_index_t<0>{}, 0);
+    Var v(absl::in_place_index<0>, 0);
     v.emplace<3>(1);
     EXPECT_TRUE(noexcept(absl::get_if<3>(&v)));
 
@@ -1638,8 +1706,8 @@
 
 TEST(VariantTest, ValuelessOperatorEquals) {
   variant<MoveCanThrow, std::string> int_v(1), string_v("Hello"),
-      valueless(absl::in_place_index_t<0>{}),
-      other_valueless(absl::in_place_index_t<0>{});
+      valueless(absl::in_place_index<0>),
+      other_valueless(absl::in_place_index<0>);
   ToValuelessByException(valueless);
   ToValuelessByException(other_valueless);
 
@@ -1660,8 +1728,8 @@
 
 TEST(VariantTest, ValuelessOperatorRelational) {
   variant<MoveCanThrow, std::string> int_v(1), string_v("Hello"),
-      valueless(absl::in_place_index_t<0>{}),
-      other_valueless(absl::in_place_index_t<0>{});
+      valueless(absl::in_place_index<0>),
+      other_valueless(absl::in_place_index<0>);
   ToValuelessByException(valueless);
   ToValuelessByException(other_valueless);
 
@@ -2008,8 +2076,8 @@
 #if !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT))
   {
     // same value as different alternative
-    variant<int, int> v0(in_place_index_t<0>{}, 42);
-    variant<int, int> v1(in_place_index_t<1>{}, 42);
+    variant<int, int> v0(in_place_index<0>, 42);
+    variant<int, int> v1(in_place_index<1>, 42);
     std::hash<variant<int, int>> hash;
     EXPECT_NE(hash(v0), hash(v1));
   }
@@ -2605,7 +2673,7 @@
   };
   {
     using V = absl::variant<TrivialCopyNontrivialMove, int>;
-    V v1(absl::in_place_index_t<0>{});
+    V v1(absl::in_place_index<0>);
     // this should invoke the move ctor, rather than the trivial copy ctor.
     V v2(std::move(v1));
     EXPECT_TRUE(absl::get<0>(v2).called);
@@ -2613,7 +2681,7 @@
   {
     // this case failed to compile before our fix due to a GCC bug.
     using V = absl::variant<int, TrivialCopyNontrivialMove>;
-    V v1(absl::in_place_index_t<1>{});
+    V v1(absl::in_place_index<1>);
     // this should invoke the move ctor, rather than the trivial copy ctor.
     V v2(std::move(v1));
     EXPECT_TRUE(absl::get<1>(v2).called);
diff --git a/absl/utility/BUILD.bazel b/absl/utility/BUILD.bazel
index 5185ccd..d41317e 100644
--- a/absl/utility/BUILD.bazel
+++ b/absl/utility/BUILD.bazel
@@ -1,6 +1,7 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
+    "ABSL_DEFAULT_LINKOPTS",
     "ABSL_TEST_COPTS",
 )
 
@@ -12,6 +13,7 @@
     name = "utility",
     hdrs = ["utility.h"],
     copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:base_internal",
         "//absl/base:config",
@@ -23,6 +25,7 @@
     name = "utility_test",
     srcs = ["utility_test.cc"],
     copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":utility",
         "//absl/base:core_headers",
diff --git a/absl/utility/utility.h b/absl/utility/utility.h
index 853c1fb..7686db1 100644
--- a/absl/utility/utility.h
+++ b/absl/utility/utility.h
@@ -113,6 +113,20 @@
   using type = integer_sequence<T>;
 };
 
+template <typename T>
+struct InPlaceTypeTag {
+  explicit InPlaceTypeTag() = delete;
+  InPlaceTypeTag(const InPlaceTypeTag&) = delete;
+  InPlaceTypeTag& operator=(const InPlaceTypeTag&) = delete;
+};
+
+template <size_t I>
+struct InPlaceIndexTag {
+  explicit InPlaceIndexTag() = delete;
+  InPlaceIndexTag(const InPlaceIndexTag&) = delete;
+  InPlaceIndexTag& operator=(const InPlaceIndexTag&) = delete;
+};
+
 }  // namespace utility_internal
 
 // Compile-time sequences of integers
@@ -162,6 +176,7 @@
 #endif  // ABSL_HAVE_STD_OPTIONAL
 
 #if defined(ABSL_HAVE_STD_ANY) || defined(ABSL_HAVE_STD_VARIANT)
+using std::in_place_type;
 using std::in_place_type_t;
 #else
 
@@ -171,10 +186,14 @@
 // be specified, such as with `absl::any`, designed to be a drop-in replacement
 // for C++17's `std::in_place_type_t`.
 template <typename T>
-struct in_place_type_t {};
+using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
+
+template <typename T>
+void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
 #endif  // ABSL_HAVE_STD_ANY || ABSL_HAVE_STD_VARIANT
 
 #ifdef ABSL_HAVE_STD_VARIANT
+using std::in_place_index;
 using std::in_place_index_t;
 #else
 
@@ -184,7 +203,10 @@
 // be specified, such as with `absl::any`, designed to be a drop-in replacement
 // for C++17's `std::in_place_index_t`.
 template <size_t I>
-struct in_place_index_t {};
+using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
+
+template <size_t I>
+void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
 #endif  // ABSL_HAVE_STD_VARIANT
 
 // Constexpr move and forward
diff --git a/ci/cmake_install_test.sh b/ci/cmake_install_test.sh
index e54b783..7195d18 100755
--- a/ci/cmake_install_test.sh
+++ b/ci/cmake_install_test.sh
@@ -29,5 +29,5 @@
     -e CFLAGS="-Werror" \
     -e CXXFLAGS="-Werror" \
     gcr.io/google.com/absl-177019/linux_gcc-4.8:20190316 \
-    /bin/bash CMake/install_test_project/test.sh
+    /bin/bash CMake/install_test_project/test.sh $@
 
diff --git a/ci/linux_clang-latest_libcxx_bazel.sh b/ci/linux_clang-latest_libcxx_bazel.sh
index 741e48c..fe9d6aa 100755
--- a/ci/linux_clang-latest_libcxx_bazel.sh
+++ b/ci/linux_clang-latest_libcxx_bazel.sh
@@ -32,6 +32,20 @@
   COMPILATION_MODE="fastbuild opt"
 fi
 
+readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190329"
+
+# USE_BAZEL_CACHE=1 only works on Kokoro.
+# Without access to the credentials this won't work.
+if [ ${USE_BAZEL_CACHE:-0} -ne 0 ]; then
+  DOCKER_EXTRA_ARGS="--volume=${KOKORO_KEYSTORE_DIR}:/keystore:ro ${DOCKER_EXTRA_ARGS:-}"
+  # Bazel doesn't track changes to tools outside of the workspace
+  # (e.g. /usr/bin/gcc), so by appending the docker container to the
+  # remote_http_cache url, we make changes to the container part of
+  # the cache key. Hashing the key is to make it shorter and url-safe.
+  container_key=$(echo ${DOCKER_CONTAINER} | sha256sum | head -c 16)
+  BAZEL_EXTRA_ARGS="--remote_http_cache=https://storage.googleapis.com/absl-bazel-remote-cache/${container_key} --google_credentials=/keystore/73103_absl-bazel-remote-cache ${BAZEL_EXTRA_ARGS:-}"
+fi
+
 for std in ${STD}; do
   for compilation_mode in ${COMPILATION_MODE}; do
     echo "--------------------------------------------------------------------"
@@ -47,7 +61,8 @@
       -e BAZEL_CXXOPTS="-std=${std}:-nostdinc++" \
       -e BAZEL_LINKOPTS="-L/opt/llvm/libcxx/lib:-lc++:-lc++abi:-lm:-Wl,-rpath=/opt/llvm/libcxx/lib" \
       -e CPLUS_INCLUDE_PATH="/opt/llvm/libcxx/include/c++/v1" \
-      gcr.io/google.com/absl-177019/linux_clang-latest:20190313 \
+      ${DOCKER_EXTRA_ARGS:-} \
+      ${DOCKER_CONTAINER} \
       /usr/local/bin/bazel test ... \
         --compilation_mode=${compilation_mode} \
         --copt=-Werror \
@@ -57,6 +72,7 @@
         --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
         --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
         --test_output=errors \
-        --test_tag_filters=-benchmark
+        --test_tag_filters=-benchmark \
+        ${BAZEL_EXTRA_ARGS:-}
   done
 done
diff --git a/ci/linux_clang-latest_libstdcxx_bazel.sh b/ci/linux_clang-latest_libstdcxx_bazel.sh
index d703a77..611b7f2 100755
--- a/ci/linux_clang-latest_libstdcxx_bazel.sh
+++ b/ci/linux_clang-latest_libstdcxx_bazel.sh
@@ -32,6 +32,20 @@
   COMPILATION_MODE="fastbuild opt"
 fi
 
+readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190329"
+
+# USE_BAZEL_CACHE=1 only works on Kokoro.
+# Without access to the credentials this won't work.
+if [ ${USE_BAZEL_CACHE:-0} -ne 0 ]; then
+  DOCKER_EXTRA_ARGS="--volume=${KOKORO_KEYSTORE_DIR}:/keystore:ro ${DOCKER_EXTRA_ARGS:-}"
+  # Bazel doesn't track changes to tools outside of the workspace
+  # (e.g. /usr/bin/gcc), so by appending the docker container to the
+  # remote_http_cache url, we make changes to the container part of
+  # the cache key. Hashing the key is to make it shorter and url-safe.
+  container_key=$(echo ${DOCKER_CONTAINER} | sha256sum | head -c 16)
+  BAZEL_EXTRA_ARGS="--remote_http_cache=https://storage.googleapis.com/absl-bazel-remote-cache/${container_key} --google_credentials=/keystore/73103_absl-bazel-remote-cache ${BAZEL_EXTRA_ARGS:-}"
+fi
+
 for std in ${STD}; do
   for compilation_mode in ${COMPILATION_MODE}; do
     echo "--------------------------------------------------------------------"
@@ -46,7 +60,8 @@
       -e BAZEL_COMPILER="llvm" \
       -e BAZEL_CXXOPTS="-std=${std}" \
       -e CPLUS_INCLUDE_PATH="/usr/include/c++/6" \
-      gcr.io/google.com/absl-177019/linux_clang-latest:20190313 \
+      ${DOCKER_EXTRA_ARGS:-} \
+      ${DOCKER_CONTAINER} \
       /usr/local/bin/bazel test ... \
         --compilation_mode=${compilation_mode} \
         --copt=-Werror \
@@ -56,6 +71,7 @@
         --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
         --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
         --test_output=errors \
-        --test_tag_filters=-benchmark
+        --test_tag_filters=-benchmark \
+        ${BAZEL_EXTRA_ARGS:-}
   done
 done
diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh
index e14a019..2446962 100755
--- a/ci/linux_gcc-latest_libstdcxx_bazel.sh
+++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh
@@ -32,6 +32,20 @@
   COMPILATION_MODE="fastbuild opt"
 fi
 
+readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20190318"
+
+# USE_BAZEL_CACHE=1 only works on Kokoro.
+# Without access to the credentials this won't work.
+if [ ${USE_BAZEL_CACHE:-0} -ne 0 ]; then
+  DOCKER_EXTRA_ARGS="--volume=${KOKORO_KEYSTORE_DIR}:/keystore:ro ${DOCKER_EXTRA_ARGS:-}"
+  # Bazel doesn't track changes to tools outside of the workspace
+  # (e.g. /usr/bin/gcc), so by appending the docker container to the
+  # remote_http_cache url, we make changes to the container part of
+  # the cache key. Hashing the key is to make it shorter and url-safe.
+  container_key=$(echo ${DOCKER_CONTAINER} | sha256sum | head -c 16)
+  BAZEL_EXTRA_ARGS="--remote_http_cache=https://storage.googleapis.com/absl-bazel-remote-cache/${container_key} --google_credentials=/keystore/73103_absl-bazel-remote-cache ${BAZEL_EXTRA_ARGS:-}"
+fi
+
 for std in ${STD}; do
   for compilation_mode in ${COMPILATION_MODE}; do
     echo "--------------------------------------------------------------------"
@@ -44,7 +58,8 @@
       --rm \
       -e CC="/usr/local/bin/gcc" \
       -e BAZEL_CXXOPTS="-std=${std}" \
-      gcr.io/google.com/absl-177019/linux_gcc-latest:20190318 \
+      ${DOCKER_EXTRA_ARGS:-} \
+      ${DOCKER_CONTAINER} \
       /usr/local/bin/bazel test ... \
         --compilation_mode=${compilation_mode} \
         --copt=-Werror \
@@ -54,6 +69,7 @@
         --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
         --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
         --test_output=errors \
-        --test_tag_filters=-benchmark
+        --test_tag_filters=-benchmark \
+        ${BAZEL_EXTRA_ARGS:-}
   done
 done
diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh
new file mode 100644
index 0000000..e840e9d
--- /dev/null
+++ b/ci/macos_xcode_bazel.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# This script is invoked on Kokoro to test Abseil on MacOS.
+# It is not hermetic and may break when Kokoro is updated.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
+fi
+
+# Print the default compiler and Bazel versions.
+echo "---------------"
+gcc -v
+echo "---------------"
+bazel version
+echo "---------------"
+
+cd ${ABSEIL_ROOT}
+
+bazel test ... \
+  --copt=-Werror \
+  --keep_going \
+  --show_timestamps \
+  --test_env="TZDIR=${ABSEIL_ROOT}/absl/time/internal/cctz/testdata/zoneinfo" \
+  --test_output=errors \
+  --test_tag_filters=-benchmark
diff --git a/ci/macos_xcode_cmake.sh b/ci/macos_xcode_cmake.sh
new file mode 100644
index 0000000..4892e26
--- /dev/null
+++ b/ci/macos_xcode_cmake.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# This script is invoked on Kokoro to test Abseil on MacOS.
+# It is not hermetic and may break when Kokoro is updated.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(dirname ${0})/.."
+fi
+ABSEIL_ROOT=$(realpath ${ABSEIL_ROOT})
+
+if [ -z ${ABSL_CMAKE_BUILD_TYPES:-} ]; then
+  ABSL_CMAKE_BUILD_TYPES="Debug"
+fi
+
+for compilation_mode in ${ABSL_CMAKE_BUILD_TYPES}; do
+  BUILD_DIR=$(mktemp -d ${compilation_mode}.XXXXXXXX)
+  cd ${BUILD_DIR}
+
+  # TODO(absl-team): Enable -Werror once all warnings are fixed.
+  time cmake ${ABSEIL_ROOT} \
+    -GXcode \
+    -DCMAKE_BUILD_TYPE=${compilation_mode} \
+    -DABSL_USE_GOOGLETEST_HEAD=ON \
+    -DABSL_RUN_TESTS=ON
+  time cmake --build .
+  time ctest -C ${compilation_mode} --output-on-failure
+done