diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index 1d55240..e52d456 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -65,6 +65,8 @@
   "base/policy_checks.h"
   "base/port.h"
   "base/thread_annotations.h"
+  "base/throw_delegate.h"
+  "base/throw_delegate.cc"
   "cleanup/cleanup.h"
   "cleanup/internal/cleanup.h"
   "container/btree_map.h"
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 1d27796..72f9e24 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -377,13 +377,16 @@
 
 cc_library(
     name = "throw_delegate",
-    srcs = ["internal/throw_delegate.cc"],
-    hdrs = ["internal/throw_delegate.h"],
+    srcs = [
+        "internal/throw_delegate.cc",
+        "throw_delegate.cc",
+    ],
+    hdrs = [
+        "internal/throw_delegate.h",
+        "throw_delegate.h",
+    ],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
-    visibility = [
-        "//absl:__subpackages__",
-    ],
     deps = [
         ":config",
         ":raw_logging_internal",
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 84decab..f39a9ae 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -290,14 +290,15 @@
   PUBLIC
 )
 
-# Internal-only target, do not depend on directly.
 absl_cc_library(
   NAME
     throw_delegate
   HDRS
     "internal/throw_delegate.h"
+    "throw_delegate.h"
   SRCS
     "internal/throw_delegate.cc"
+    "throw_delegate.cc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
diff --git a/absl/base/call_once.h b/absl/base/call_once.h
index 7bfd916..1abac86 100644
--- a/absl/base/call_once.h
+++ b/absl/base/call_once.h
@@ -160,6 +160,7 @@
         old_control != kOnceRunning &&
         old_control != kOnceWaiter &&
         old_control != kOnceDone) {
+      // Memory corruption may cause this error.
       ABSL_RAW_LOG(FATAL, "Unexpected value for control word: 0x%lx",
                    static_cast<unsigned long>(old_control));  // NOLINT
     }
diff --git a/absl/base/casts.h b/absl/base/casts.h
index 38243d8..928f409 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -211,7 +211,7 @@
   // Assert only if RTTI is enabled and in debug mode or hardened asserts are
   // enabled.
 #ifdef ABSL_INTERNAL_HAS_RTTI
-#if !defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2)
+#if !defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1)
   // Suppress erroneous nonnull comparison warning on older GCC.
 #if defined(__GNUC__) && !defined(__clang__)
 #pragma GCC diagnostic push
diff --git a/absl/base/casts_test.cc b/absl/base/casts_test.cc
index 772225e..dda3ae6 100644
--- a/absl/base/casts_test.cc
+++ b/absl/base/casts_test.cc
@@ -92,8 +92,7 @@
   // Tests a bad downcast. We have to disguise the badness just enough
   // that the compiler doesn't warn about it at compile time.
   BaseForDownCast* base2 = new BaseForDownCast();
-#if GTEST_HAS_DEATH_TEST && (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1 || \
-                                                  ABSL_OPTION_HARDENED == 2))
+#if GTEST_HAS_DEATH_TEST && (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1))
   EXPECT_DEATH(static_cast<void>(absl::down_cast<DerivedForDownCast*>(base2)),
                ".*down cast from .*BaseForDownCast.* to "
                ".*DerivedForDownCast.* failed.*");
@@ -126,8 +125,7 @@
   // Tests a bad downcast. We have to disguise the badness just enough
   // that the compiler doesn't warn about it at compile time.
   BaseForDownCast& base2 = *new BaseForDownCast();
-#if GTEST_HAS_DEATH_TEST && (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1 || \
-                                                  ABSL_OPTION_HARDENED == 2))
+#if GTEST_HAS_DEATH_TEST && (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1))
   EXPECT_DEATH(static_cast<void>(absl::down_cast<DerivedForDownCast&>(base2)),
                ".*down cast from .*BaseForDownCast.* to "
                ".*DerivedForDownCast.* failed.*");
@@ -140,8 +138,7 @@
   BaseForDownCast& base = derived;
   (void)base;
 
-#if GTEST_HAS_DEATH_TEST && (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1 || \
-                                                  ABSL_OPTION_HARDENED == 2))
+#if GTEST_HAS_DEATH_TEST && (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1))
   EXPECT_DEATH(static_cast<void>(absl::down_cast<Derived2ForDownCast&>(base)),
                ".*down cast from .*DerivedForDownCast.* to "
                ".*Derived2ForDownCast.* failed.*");
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index 04678c4..b561128 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -222,7 +222,7 @@
 
 // `ABSL_UNREACHABLE()` is an unreachable statement.  A program which reaches
 // one has undefined behavior, and the compiler may optimize accordingly.
-#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
+#if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
 // Abort in hardened mode to avoid dangerous undefined behavior.
 #define ABSL_UNREACHABLE()                \
   do {                                    \
diff --git a/absl/base/throw_delegate.cc b/absl/base/throw_delegate.cc
new file mode 100644
index 0000000..b960edd
--- /dev/null
+++ b/absl/base/throw_delegate.cc
@@ -0,0 +1,205 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/base/throw_delegate.h"
+
+#include <cstdlib>
+#include <functional>
+#include <new>
+#include <stdexcept>
+
+#include "absl/base/config.h"
+#include "absl/base/internal/raw_logging.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+void ThrowStdLogicError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::logic_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdLogicError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::logic_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+void ThrowStdInvalidArgument(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::invalid_argument(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdInvalidArgument(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::invalid_argument(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdDomainError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::domain_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdDomainError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::domain_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdLengthError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::length_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdLengthError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::length_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdOutOfRange(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::out_of_range(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdOutOfRange(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::out_of_range(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdRuntimeError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::runtime_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdRuntimeError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::runtime_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdRangeError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::range_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdRangeError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::range_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdOverflowError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::overflow_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdOverflowError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::overflow_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdUnderflowError(const std::string& what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::underflow_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
+  std::abort();
+#endif
+}
+void ThrowStdUnderflowError(const char* what_arg) {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::underflow_error(what_arg);
+#else
+  ABSL_RAW_LOG(FATAL, "%s", what_arg);
+  std::abort();
+#endif
+}
+
+void ThrowStdBadFunctionCall() {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::bad_function_call();
+#else
+  std::abort();
+#endif
+}
+
+void ThrowStdBadAlloc() {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::bad_alloc();
+#else
+  std::abort();
+#endif
+}
+
+void ThrowStdBadArrayNewLength() {
+#ifdef ABSL_HAVE_EXCEPTIONS
+  throw std::bad_array_new_length();
+#else
+  std::abort();
+#endif
+}
+
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/absl/base/throw_delegate.h b/absl/base/throw_delegate.h
new file mode 100644
index 0000000..e89712a
--- /dev/null
+++ b/absl/base/throw_delegate.h
@@ -0,0 +1,65 @@
+// 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_BASE_THROW_DELEGATE_H_
+#define ABSL_BASE_THROW_DELEGATE_H_
+
+#include <string>
+
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+// Helper functions that allow throwing exceptions consistently from anywhere.
+// The main use case is for header-based libraries (eg templates), as they will
+// be built by many different targets with their own compiler options.
+// In particular, this will allow a safe way to throw exceptions even if the
+// caller is compiled with -fno-exceptions.  This is intended for implementing
+// things like map<>::at(), which the standard documents as throwing an
+// exception on error.
+//
+// Using other techniques like #if tricks could lead to ODR violations.
+//
+// You shouldn't use it unless you're writing code that you know will be built
+// both with and without exceptions and you need to conform to an interface
+// that uses exceptions.
+
+[[noreturn]] void ThrowStdLogicError(const std::string& what_arg);
+[[noreturn]] void ThrowStdLogicError(const char* what_arg);
+[[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg);
+[[noreturn]] void ThrowStdInvalidArgument(const char* what_arg);
+[[noreturn]] void ThrowStdDomainError(const std::string& what_arg);
+[[noreturn]] void ThrowStdDomainError(const char* what_arg);
+[[noreturn]] void ThrowStdLengthError(const std::string& what_arg);
+[[noreturn]] void ThrowStdLengthError(const char* what_arg);
+[[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg);
+[[noreturn]] void ThrowStdOutOfRange(const char* what_arg);
+[[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg);
+[[noreturn]] void ThrowStdRuntimeError(const char* what_arg);
+[[noreturn]] void ThrowStdRangeError(const std::string& what_arg);
+[[noreturn]] void ThrowStdRangeError(const char* what_arg);
+[[noreturn]] void ThrowStdOverflowError(const std::string& what_arg);
+[[noreturn]] void ThrowStdOverflowError(const char* what_arg);
+[[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg);
+[[noreturn]] void ThrowStdUnderflowError(const char* what_arg);
+
+[[noreturn]] void ThrowStdBadFunctionCall();
+[[noreturn]] void ThrowStdBadAlloc();
+[[noreturn]] void ThrowStdBadArrayNewLength();
+
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_BASE_THROW_DELEGATE_H_
diff --git a/absl/base/throw_delegate_test.cc b/absl/base/throw_delegate_test.cc
index e74362b..3cbc171 100644
--- a/absl/base/throw_delegate_test.cc
+++ b/absl/base/throw_delegate_test.cc
@@ -12,28 +12,29 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/base/internal/throw_delegate.h"
+#include "absl/base/throw_delegate.h"
 
 #include <functional>
 #include <new>
 #include <stdexcept>
 
-#include "absl/base/config.h"
 #include "gtest/gtest.h"
+#include "absl/base/config.h"
 
 namespace {
 
-using absl::base_internal::ThrowStdLogicError;
-using absl::base_internal::ThrowStdInvalidArgument;
-using absl::base_internal::ThrowStdDomainError;
-using absl::base_internal::ThrowStdLengthError;
-using absl::base_internal::ThrowStdOutOfRange;
-using absl::base_internal::ThrowStdRuntimeError;
-using absl::base_internal::ThrowStdRangeError;
-using absl::base_internal::ThrowStdOverflowError;
-using absl::base_internal::ThrowStdUnderflowError;
-using absl::base_internal::ThrowStdBadFunctionCall;
-using absl::base_internal::ThrowStdBadAlloc;
+using absl::ThrowStdBadAlloc;
+using absl::ThrowStdBadArrayNewLength;
+using absl::ThrowStdBadFunctionCall;
+using absl::ThrowStdDomainError;
+using absl::ThrowStdInvalidArgument;
+using absl::ThrowStdLengthError;
+using absl::ThrowStdLogicError;
+using absl::ThrowStdOutOfRange;
+using absl::ThrowStdOverflowError;
+using absl::ThrowStdRangeError;
+using absl::ThrowStdRuntimeError;
+using absl::ThrowStdUnderflowError;
 
 constexpr const char* what_arg = "The quick brown fox jumps over the lazy dog";
 
@@ -151,25 +152,15 @@
 }
 
 TEST(ThrowDelegate, ThrowStdBadFunctionCallNoWhat) {
-#ifdef ABSL_HAVE_EXCEPTIONS
-  try {
-    ThrowStdBadFunctionCall();
-    FAIL() << "Didn't throw";
-  } catch (const std::bad_function_call&) {
-  }
-#ifdef _LIBCPP_VERSION
-  catch (const std::exception&) {
-    // https://reviews.llvm.org/D92397 causes issues with the vtable for
-    // std::bad_function_call when using libc++ as a shared library.
-  }
-#endif
-#else
-  EXPECT_DEATH_IF_SUPPORTED(ThrowStdBadFunctionCall(), "");
-#endif
+  ExpectThrowNoWhat<std::bad_function_call>(ThrowStdBadFunctionCall);
 }
 
 TEST(ThrowDelegate, ThrowStdBadAllocNoWhat) {
   ExpectThrowNoWhat<std::bad_alloc>(ThrowStdBadAlloc);
 }
 
+TEST(ThrowDelegate, ThrowStdBadArrayNewLength) {
+  ExpectThrowNoWhat<std::bad_array_new_length>(ThrowStdBadArrayNewLength);
+}
+
 }  // namespace
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index d47b0e4..c51a19f 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -45,10 +45,10 @@
 #include "absl/base/config.h"
 #include "absl/base/dynamic_annotations.h"
 #include "absl/base/internal/iterator_traits.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/throw_delegate.h"
 #include "absl/container/internal/compressed_tuple.h"
 #include "absl/hash/internal/weakly_mixed_integer.h"
 #include "absl/memory/memory.h"
@@ -240,7 +240,7 @@
   // array, or throws std::out_of_range
   reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ABSL_PREDICT_FALSE(i >= size())) {
-      base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check");
+      ThrowStdOutOfRange("FixedArray::at failed bounds check");
     }
     return data()[i];
   }
@@ -249,7 +249,7 @@
   // of the fixed array.
   const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ABSL_PREDICT_FALSE(i >= size())) {
-      base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check");
+      ThrowStdOutOfRange("FixedArray::at failed bounds check");
     }
     return data()[i];
   }
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h
index 7ce3353..1677f6a 100644
--- a/absl/container/flat_hash_map.h
+++ b/absl/container/flat_hash_map.h
@@ -181,6 +181,11 @@
   //
   //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
   //   absl::flat_hash_map<int, std::string> map7(v.begin(), v.end());
+  //
+  // * from_range constructor (C++23)
+  //
+  //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
+  //   absl::flat_hash_map<int, std::string> map8(std::from_range, v);
   flat_hash_map() {}
   using Base::Base;
 
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc
index 73f28c7..a4efb7d 100644
--- a/absl/container/flat_hash_map_test.cc
+++ b/absl/container/flat_hash_map_test.cc
@@ -35,6 +35,10 @@
 #include "absl/meta/type_traits.h"
 #include "absl/types/any.h"
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <ranges>  // NOLINT(build/c++20)
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -445,6 +449,36 @@
   EXPECT_DEATH_IF_SUPPORTED(insert_conflicting_elems(), crash_message);
 }
 
+#if defined(__cpp_lib_containers_ranges) && \
+    __cpp_lib_containers_ranges >= 202202L
+TEST(FlatHashMap, FromRange) {
+  std::vector<std::pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}};
+  absl::flat_hash_map<int, int> m(std::from_range, v);
+  EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(3, 4), Pair(5, 6)));
+}
+
+TEST(FlatHashMap, FromRangeWithAllocator) {
+  std::vector<std::pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}};
+  absl::flat_hash_map<int, int,
+                      absl::container_internal::hash_default_hash<int>,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<std::pair<const int, int>>>
+      m(std::from_range, v, 0, Alloc<std::pair<const int, int>>());
+  EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(3, 4), Pair(5, 6)));
+}
+
+TEST(FlatHashMap, FromRangeWithHasherAndAllocator) {
+  std::vector<std::pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}};
+  using TestingHash = absl::container_internal::StatefulTestingHash;
+  absl::flat_hash_map<int, int, TestingHash,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<std::pair<const int, int>>>
+      m(std::from_range, v, 0, TestingHash{},
+        Alloc<std::pair<const int, int>>());
+  EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(3, 4), Pair(5, 6)));
+}
+#endif
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h
index a469fa0..f802057 100644
--- a/absl/container/flat_hash_set.h
+++ b/absl/container/flat_hash_set.h
@@ -177,6 +177,11 @@
   //
   //   std::vector<std::string> v = {"a", "b"};
   //   absl::flat_hash_set<std::string> set7(v.begin(), v.end());
+  //
+  // * from_range constructor (C++23)
+  //
+  //   std::vector<std::string> v = {"a", "b"};
+  //   absl::flat_hash_set<std::string> set8(std::from_range, v);
   flat_hash_set() {}
   using Base::Base;
 
diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc
index 9b6a6d1..f776f38 100644
--- a/absl/container/flat_hash_set_test.cc
+++ b/absl/container/flat_hash_set_test.cc
@@ -38,6 +38,10 @@
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <ranges>  // NOLINT(build/c++20)
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -395,6 +399,34 @@
             false);
 }
 
+#if defined(__cpp_lib_containers_ranges) && \
+    __cpp_lib_containers_ranges >= 202202L
+TEST(FlatHashSet, FromRange) {
+  std::vector<int> v = {1, 2, 3, 4, 5};
+  absl::flat_hash_set<int> s(std::from_range, v);
+  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(FlatHashSet, FromRangeWithAllocator) {
+  std::vector<int> v = {1, 2, 3, 4, 5};
+  absl::flat_hash_set<int, absl::container_internal::hash_default_hash<int>,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<int>>
+      s(std::from_range, v, 0, Alloc<int>());
+  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(FlatHashSet, FromRangeWithHasherAndAllocator) {
+  std::vector<int> v = {1, 2, 3, 4, 5};
+  using TestingHash = absl::container_internal::StatefulTestingHash;
+  absl::flat_hash_set<int, TestingHash,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<int>>
+      s(std::from_range, v, 0, TestingHash{}, Alloc<int>());
+  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
+}
+#endif
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 6b05d92..a9c2526 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -48,10 +48,10 @@
 #include "absl/algorithm/algorithm.h"
 #include "absl/base/attributes.h"
 #include "absl/base/internal/iterator_traits.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/throw_delegate.h"
 #include "absl/container/internal/inlined_vector.h"
 #include "absl/hash/internal/weakly_mixed_integer.h"
 #include "absl/memory/memory.h"
@@ -382,8 +382,7 @@
   // in both debug and non-debug builds, `std::out_of_range` will be thrown.
   reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ABSL_PREDICT_FALSE(i >= size())) {
-      base_internal::ThrowStdOutOfRange(
-          "`InlinedVector::at(size_type)` failed bounds check");
+      ThrowStdOutOfRange("`InlinedVector::at(size_type)` failed bounds check");
     }
     return data()[i];
   }
@@ -395,7 +394,7 @@
   // in both debug and non-debug builds, `std::out_of_range` will be thrown.
   const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ABSL_PREDICT_FALSE(i >= size())) {
-      base_internal::ThrowStdOutOfRange(
+      ThrowStdOutOfRange(
           "`InlinedVector::at(size_type) const` failed bounds check");
     }
     return data()[i];
diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h
index e1649e3..0ccf9d0 100644
--- a/absl/container/internal/btree_container.h
+++ b/absl/container/internal/btree_container.h
@@ -22,7 +22,7 @@
 #include <utility>
 
 #include "absl/base/attributes.h"
-#include "absl/base/internal/throw_delegate.h"
+#include "absl/base/throw_delegate.h"
 #include "absl/container/internal/btree.h"  // IWYU pragma: export
 #include "absl/container/internal/common.h"
 #include "absl/hash/internal/weakly_mixed_integer.h"
@@ -651,16 +651,14 @@
   template <typename K = key_type>
   mapped_type &at(const key_arg<K> &key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     auto it = this->find(key);
-    if (it == this->end())
-      base_internal::ThrowStdOutOfRange("absl::btree_map::at");
+    if (it == this->end()) ThrowStdOutOfRange("absl::btree_map::at");
     return it->second;
   }
   template <typename K = key_type>
   const mapped_type &at(const key_arg<K> &key) const
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     auto it = this->find(key);
-    if (it == this->end())
-      base_internal::ThrowStdOutOfRange("absl::btree_map::at");
+    if (it == this->end()) ThrowStdOutOfRange("absl::btree_map::at");
     return it->second;
   }
 
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h
index 9338f16..20b622b 100644
--- a/absl/container/internal/raw_hash_map.h
+++ b/absl/container/internal/raw_hash_map.h
@@ -21,7 +21,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/throw_delegate.h"
+#include "absl/base/throw_delegate.h"
 #include "absl/container/internal/common_policy_traits.h"
 #include "absl/container/internal/container_memory.h"
 #include "absl/container/internal/raw_hash_set.h"  // IWYU pragma: export
@@ -290,8 +290,7 @@
   MappedReference<P> at(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     auto it = this->find(key);
     if (it == this->end()) {
-      base_internal::ThrowStdOutOfRange(
-          "absl::container_internal::raw_hash_map<>::at");
+      ThrowStdOutOfRange("absl::container_internal::raw_hash_map<>::at");
     }
     return Policy::value(&*it);
   }
@@ -301,8 +300,7 @@
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     auto it = this->find(key);
     if (it == this->end()) {
-      base_internal::ThrowStdOutOfRange(
-          "absl::container_internal::raw_hash_map<>::at");
+      ThrowStdOutOfRange("absl::container_internal::raw_hash_map<>::at");
     }
     return Policy::value(&*it);
   }
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index d307e2d..a123ebd 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -221,6 +221,10 @@
 #include "absl/numeric/bits.h"
 #include "absl/utility/utility.h"
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <ranges>  // NOLINT(build/c++20)
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -2149,6 +2153,28 @@
                const allocator_type& alloc)
       : raw_hash_set(first, last, bucket_count, hasher(), key_equal(), alloc) {}
 
+#if defined(__cpp_lib_containers_ranges) && \
+    __cpp_lib_containers_ranges >= 202202L
+  template <typename R>
+  raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count = 0,
+               const hasher& hash = hasher(), const key_equal& eq = key_equal(),
+               const allocator_type& alloc = allocator_type())
+      : raw_hash_set(std::begin(rg), std::end(rg), bucket_count, hash, eq,
+                     alloc) {}
+
+  template <typename R>
+  raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count,
+               const allocator_type& alloc)
+      : raw_hash_set(std::from_range, std::forward<R>(rg), bucket_count,
+                     hasher(), key_equal(), alloc) {}
+
+  template <typename R>
+  raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count,
+               const hasher& hash, const allocator_type& alloc)
+      : raw_hash_set(std::from_range, std::forward<R>(rg), bucket_count, hash,
+                     key_equal(), alloc) {}
+#endif
+
   template <class InputIter>
   raw_hash_set(InputIter first, InputIter last, const allocator_type& alloc)
       : raw_hash_set(first, last, 0, hasher(), key_equal(), alloc) {}
diff --git a/absl/container/linked_hash_map.h b/absl/container/linked_hash_map.h
index e42a1f7..61720d6 100644
--- a/absl/container/linked_hash_map.h
+++ b/absl/container/linked_hash_map.h
@@ -43,8 +43,8 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/throw_delegate.h"
 #include "absl/base/optimization.h"
+#include "absl/base/throw_delegate.h"
 #include "absl/container/flat_hash_set.h"
 #include "absl/container/internal/common.h"
 
@@ -377,7 +377,7 @@
   mapped_type& at(const key_arg<K>& key) {
     auto it = find(key);
     if (ABSL_PREDICT_FALSE(it == end())) {
-      absl::base_internal::ThrowStdOutOfRange("absl::linked_hash_map::at");
+      ThrowStdOutOfRange("absl::linked_hash_map::at");
     }
     return it->second;
   }
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h
index 580a044..3ceef32 100644
--- a/absl/container/node_hash_map.h
+++ b/absl/container/node_hash_map.h
@@ -177,6 +177,11 @@
   //
   //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
   //   absl::node_hash_map<int, std::string> map7(v.begin(), v.end());
+  //
+  // * from_range constructor (C++23)
+  //
+  //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
+  //   absl::node_hash_map<int, std::string> map8(std::from_range, v);
   node_hash_map() {}
   using Base::Base;
 
diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc
index c67d81f..6e92bbe 100644
--- a/absl/container/node_hash_map_test.cc
+++ b/absl/container/node_hash_map_test.cc
@@ -32,6 +32,10 @@
 #include "absl/container/internal/unordered_map_members_test.h"
 #include "absl/container/internal/unordered_map_modifiers_test.h"
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <ranges>  // NOLINT(build/c++20)
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -342,6 +346,36 @@
   t.m[0] = RecursiveType{};
 }
 
+#if defined(__cpp_lib_containers_ranges) && \
+    __cpp_lib_containers_ranges >= 202202L
+TEST(NodeHashMap, FromRange) {
+  std::vector<std::pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}};
+  absl::node_hash_map<int, int> m(std::from_range, v);
+  EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(3, 4), Pair(5, 6)));
+}
+
+TEST(NodeHashMap, FromRangeWithAllocator) {
+  std::vector<std::pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}};
+  absl::node_hash_map<int, int,
+                      absl::container_internal::hash_default_hash<int>,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<std::pair<const int, int>>>
+      m(std::from_range, v, 0, Alloc<std::pair<const int, int>>());
+  EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(3, 4), Pair(5, 6)));
+}
+
+TEST(NodeHashMap, FromRangeWithHasherAndAllocator) {
+  std::vector<std::pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}};
+  using TestingHash = absl::container_internal::StatefulTestingHash;
+  absl::node_hash_map<int, int, TestingHash,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<std::pair<const int, int>>>
+      m(std::from_range, v, 0, TestingHash{},
+        Alloc<std::pair<const int, int>>());
+  EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(3, 4), Pair(5, 6)));
+}
+#endif
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h
index f69c6ab..17aa763 100644
--- a/absl/container/node_hash_set.h
+++ b/absl/container/node_hash_set.h
@@ -171,6 +171,11 @@
   //
   //   std::vector<std::string> v = {"a", "b"};
   //   absl::node_hash_set<std::string> set7(v.begin(), v.end());
+  //
+  // * from_range constructor (C++23)
+  //
+  //   std::vector<std::string> v = {"a", "b"};
+  //   absl::node_hash_set<std::string> set8(std::from_range, v);
   node_hash_set() {}
   using Base::Base;
 
diff --git a/absl/container/node_hash_set_test.cc b/absl/container/node_hash_set_test.cc
index e1f5bd9..b29d0ca 100644
--- a/absl/container/node_hash_set_test.cc
+++ b/absl/container/node_hash_set_test.cc
@@ -31,6 +31,10 @@
 #include "absl/container/internal/unordered_set_modifiers_test.h"
 #include "absl/memory/memory.h"
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <ranges>  // NOLINT(build/c++20)
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -182,6 +186,34 @@
   }
 }
 
+#if defined(__cpp_lib_containers_ranges) && \
+    __cpp_lib_containers_ranges >= 202202L
+TEST(NodeHashSet, FromRange) {
+  std::vector<int> v = {1, 2, 3, 4, 5};
+  absl::node_hash_set<int> s(std::from_range, v);
+  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(NodeHashSet, FromRangeWithAllocator) {
+  std::vector<int> v = {1, 2, 3, 4, 5};
+  absl::node_hash_set<int, absl::container_internal::hash_default_hash<int>,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<int>>
+      s(std::from_range, v, 0, Alloc<int>());
+  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(NodeHashSet, FromRangeWithHasherAndAllocator) {
+  std::vector<int> v = {1, 2, 3, 4, 5};
+  using TestingHash = absl::container_internal::StatefulTestingHash;
+  absl::node_hash_set<int, TestingHash,
+                      absl::container_internal::hash_default_eq<int>,
+                      Alloc<int>>
+      s(std::from_range, v, 0, TestingHash{}, Alloc<int>());
+  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
+}
+#endif
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index 89e0470..7395ab7 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -762,10 +762,8 @@
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
       V(Private{1}), V(Private{-1}), V(Private{2}), V("ABC"), V("BCD"))));
 
-#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
   struct S {};
   EXPECT_FALSE(is_hashable<absl::variant<S>>::value);
-#endif
 }
 
 TEST(HashValueTest, ReferenceWrapper) {
@@ -811,7 +809,6 @@
   EXPECT_TRUE(IsAggregateInitializable<absl::Hash<int>>::value);
 }
 
-#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
 TEST(IsHashableTest, PoisonHash) {
   struct X {};
   EXPECT_FALSE((is_hashable<X>::value));
@@ -826,7 +823,6 @@
   EXPECT_FALSE(IsAggregateInitializable<absl::Hash<X>>::value);
 #endif
 }
-#endif  // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
 
 // Hashable types
 //
@@ -962,13 +958,11 @@
 }
 
 void TestCustomHashType(InvokeTagConstant<InvokeTag::kNone>) {
-#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
   // is_hashable is false if we don't support any of the hooks.
   using type = CustomHashType<>;
   EXPECT_FALSE(is_hashable<type>());
   EXPECT_FALSE(is_hashable<const type>());
   EXPECT_FALSE(is_hashable<const type&>());
-#endif  // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
 }
 
 template <InvokeTag Tag, typename... T>
diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc
index 74b6d57..43cb561 100644
--- a/absl/hash/internal/hash.cc
+++ b/absl/hash/internal/hash.cc
@@ -78,6 +78,9 @@
   return _mm_sub_epi64(a, b);
 }
 
+// Bits of the second argument to Encrypt128/Decrypt128 are XORed with the
+// first argument after encryption/decryption.
+
 inline Vector128 Encrypt128(Vector128 data, Vector128 key) {
   return _mm_aesenc_si128(data, key);
 }
@@ -86,6 +89,28 @@
   return _mm_aesdec_si128(data, key);
 }
 
+// We use each value as the first argument to shuffle all the bits around. We do
+// not add any salt to the state or loaded data, instead we vary instructions
+// used to mix bits Encrypt128/Decrypt128 and Add128/Sub128. On x86,
+// Add128/Sub128 are combined to one instruction with data loading like
+// `vpaddq xmm1, xmm0, xmmword ptr [rdi]`.
+
+inline Vector128 MixA(Vector128 a, Vector128 state) {
+  return Decrypt128(Add128(state, a), state);
+}
+
+inline Vector128 MixB(Vector128 b, Vector128 state) {
+  return Decrypt128(Sub128(state, b), state);
+}
+
+inline Vector128 MixC(Vector128 c, Vector128 state) {
+  return Encrypt128(Add128(state, c), state);
+}
+
+inline Vector128 MixD(Vector128 d, Vector128 state) {
+  return Encrypt128(Sub128(state, d), state);
+}
+
 inline uint64_t ExtractLow64(Vector128 v) {
   return static_cast<uint64_t>(_mm_cvtsi128_si64(v));
 }
@@ -118,37 +143,41 @@
       vaddq_u64(vreinterpretq_u64_u8(a), vreinterpretq_u64_u8(b)));
 }
 
-inline Vector128 Sub128(Vector128 a, Vector128 b) {
-  return vreinterpretq_u8_u64(
-      vsubq_u64(vreinterpretq_u64_u8(a), vreinterpretq_u64_u8(b)));
-}
-
-// Encrypt128 and Decrypt128 are equivalent to x86 versions.
-// `vaeseq_u8` and `vaesdq_u8` perform `^ key` before encryption/decryption.
-// We need to perform `^ key` after encryption/decryption to improve hash
-// quality and match x86 version.
+// Bits of the second argument to Decrypt128/Encrypt128 are XORed with the
+// state argument BEFORE encryption (in x86 version they are XORed after).
 
 inline Vector128 Encrypt128(Vector128 data, Vector128 key) {
-  return vaesmcq_u8(vaeseq_u8(data, Vector128{})) ^ key;
-}
-
-inline Vector128 Decrypt128(Vector128 data, Vector128 key) {
-  return vaesimcq_u8(vaesdq_u8(data, Vector128{})) ^ key;
-}
-
-// ArmEncrypt128 and ArmDecrypt128 are ARM specific versions that use ARM
-// instructions directly.
-// We can only use these versions in the second round of encryption/decryption
-// to have good hash quality.
-
-inline Vector128 ArmEncrypt128(Vector128 data, Vector128 key) {
   return vaesmcq_u8(vaeseq_u8(data, key));
 }
 
-inline Vector128 ArmDecrypt128(Vector128 data, Vector128 key) {
+inline Vector128 Decrypt128(Vector128 data, Vector128 key) {
   return vaesimcq_u8(vaesdq_u8(data, key));
 }
 
+// We use decryption for a, b and encryption for c, d. That helps us to avoid
+// collisions for trivial byte rotations. Mix4x16Vectors later uses
+// encrypted/decrypted pairs differently to ensure that the order of blocks is
+// important for the hash value.
+// We also avoid using Add128/Sub128 instructions because state is being mixed
+// before encryption/decryption. On ARM, there is no fusion of load and add/sub
+// instructions so it is more expensive to use them.
+
+inline Vector128 MixA(Vector128 a, Vector128 state) {
+  return Decrypt128(a, state);
+}
+
+inline Vector128 MixB(Vector128 b, Vector128 state) {
+  return Decrypt128(b, state);
+}
+
+inline Vector128 MixC(Vector128 c, Vector128 state) {
+  return Encrypt128(c, state);
+}
+
+inline Vector128 MixD(Vector128 d, Vector128 state) {
+  return Encrypt128(d, state);
+}
+
 inline uint64_t ExtractLow64(Vector128 v) {
   return vgetq_lane_u64(vreinterpretq_u64_u8(v), 0);
 }
@@ -158,7 +187,7 @@
 }
 
 uint64_t Mix4x16Vectors(Vector128 a, Vector128 b, Vector128 c, Vector128 d) {
-  Vector128 res128 = Add128(ArmEncrypt128(a, c), ArmDecrypt128(b, d));
+  Vector128 res128 = Add128(Encrypt128(a, c), Decrypt128(b, d));
   uint64_t x64 = ExtractLow64(res128);
   uint64_t y64 = ExtractHigh64(res128);
   return x64 ^ y64;
@@ -176,16 +205,10 @@
   Vector128 c = Load128(last32_ptr);
   Vector128 d = Load128(last32_ptr + 16);
 
-  // Bits of the second argument to Decrypt128/Encrypt128 are XORed with the
-  // state argument after encryption. We use each value as the first argument to
-  // shuffle all the bits around. We do not add any salt to the state or loaded
-  // data, instead we vary instructions used to mix bits Decrypt128/Encrypt128
-  // and Add128/Sub128. On x86 Add128/Sub128 are combined to one instruction
-  // with data loading like `vpaddq  xmm1, xmm0, xmmword ptr [rdi]`.
-  Vector128 na = Decrypt128(Add128(state, a), state);
-  Vector128 nb = Decrypt128(Sub128(state, b), state);
-  Vector128 nc = Encrypt128(Add128(state, c), state);
-  Vector128 nd = Encrypt128(Sub128(state, d), state);
+  Vector128 na = MixA(a, state);
+  Vector128 nb = MixB(b, state);
+  Vector128 nc = MixC(c, state);
+  Vector128 nd = MixD(d, state);
 
   // We perform another round of encryption to mix bits between two halves of
   // the input.
@@ -216,15 +239,15 @@
                  &state1](const uint8_t* p) ABSL_ATTRIBUTE_ALWAYS_INLINE {
     Vector128 a = Load128(p);
     Vector128 b = Load128(p + 16);
-    state0 = Decrypt128(Add128(state0, a), state0);
-    state1 = Decrypt128(Sub128(state1, b), state1);
+    state0 = MixA(a, state0);
+    state1 = MixB(b, state1);
   };
   auto mix_cd = [&state2,
                  &state3](const uint8_t* p) ABSL_ATTRIBUTE_ALWAYS_INLINE {
     Vector128 c = Load128(p);
     Vector128 d = Load128(p + 16);
-    state2 = Encrypt128(Add128(state2, c), state2);
-    state3 = Encrypt128(Sub128(state3, d), state3);
+    state2 = MixC(c, state2);
+    state3 = MixD(d, state3);
   };
 
   do {
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 8b0f94a..ea04f47 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -1222,8 +1222,7 @@
 }
 #endif  // ABSL_HASH_INTERNAL_HAS_CRC32
 
-#if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \
-    ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
+#if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE)
 #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1
 #else
 #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0
diff --git a/absl/hash/internal/low_level_hash_test.cc b/absl/hash/internal/low_level_hash_test.cc
index 6476462..f1e2d15 100644
--- a/absl/hash/internal/low_level_hash_test.cc
+++ b/absl/hash/internal/low_level_hash_test.cc
@@ -405,38 +405,38 @@
   };
 #elif (defined(ABSL_INTERNAL_HAVE_ARM_NEON) && defined(__ARM_FEATURE_CRYPTO))
   constexpr uint64_t kGolden[kNumGoldenOutputs] = {
-      0x248c82373f7f0d24, 0x0a4f8cbf55047086, 0x498dd0a4445ed65f,
-      0x6d418b193638ab0f, 0x4112c1ce9142980e, 0x02132db6a189f206,
-      0x36e550ca9139ee44, 0xe0a67fdbd8627314, 0x2b9528fe18f65d1d,
-      0x037d9cf48ca9fd1c, 0xa87222631332ca06, 0x31f35e09af065022,
-      0xacd6f1d29071c8e5, 0x54eb4f229a0d15a4, 0x132c27c6a747e136,
-      0x13d7cb427efe7e2f, 0x71a5d21e00f00dcd, 0xdb909cbf1b0fbb64,
-      0x4dc943ad8901fa5b, 0xacf4b3d41a46feb5, 0x12a37d19c14ffd65,
-      0xdb511011bcdd95b9, 0xd6d75af1c8b86dbd, 0xc65aefdcff941a8e,
-      0xbea311ef212c0306, 0xc49861afe7a6888b, 0x598424b541daf528,
-      0x4cc264fbb57c4640, 0x1a7376211a5e674a, 0xcb82900ad06bf89b,
-      0xd9d6201d685a4971, 0x77ed120a277ce616, 0x9bd5ad973b4d358c,
-      0x880850ff91b6b772, 0xf9d24d40448fce38, 0x870b8ee54a31707d,
-      0x613130fe647bd169, 0x04a0cc02a81989f3, 0x998adbda0ab3f8fa,
-      0x2b28729269102040, 0xbdb9be95e352a6d5, 0xd5e2a55d78bd9fb0,
-      0xef609c2b22eb93d6, 0xac23eb02494ae8e0, 0xcb8c5ab08163d2a3,
-      0x63f822fc21b42698, 0xe7e8814288c470cc, 0x143b07aae2ccd592,
-      0xc5d142f4806e13a3, 0xe695de2a1d8a344b, 0xc8ddc3ed542a5988,
-      0x60ec526cc1e5274d, 0x732a04dcf34a7ac9, 0xf1daef52096a872a,
-      0x541f04b87b3de158, 0xeb143a708b621f94, 0x0849cd39e156b25f,
-      0x36eb0746caa62c5c, 0xbfa14eb3c31f78bf, 0x256637f35dc41f20,
-      0x08293113693a58e2, 0x064202395a685840, 0x0593285ee1ed42ea,
-      0xdcbf16fd8a44f213, 0xe9f5586745f4f23d, 0x66808a2c18365ae9,
-      0xa70496836a5166e1, 0xe9ed7d0f9f572246, 0x024ba6063287d0cb,
-      0xa441f6ac287479db, 0x72502c190698ee02, 0xb79705c6ced58c29,
-      0x5c03f52968cb1fdc, 0x6f4b7c6bed6cc232, 0xed834775697438d3,
-      0x6273b075725ffb6f, 0x60df77a69e9aafb2, 0x84483bf48b989c4e,
-      0x37e42a1d35795a31, 0x280dcdb36b853ae5, 0x63309d698f2dd42c,
-      0x24e65be2c805ea5b, 0x1db08e0d041efdf9, 0xb94aea8c4648772b,
-      0x109f2b81aa4660d2, 0xcae92809feb1a390, 0x0a1cbf9628383b41,
-      0xca0bf416706fc5c8, 0x9d4751bd7e638488, 0x343b363d5d96c7c7,
-      0x6bacaedde1daf5aa, 0x721ead1618c4e405, 0xcfc19e400cb6dbc6,
-      0x7ac0dd9128ec8cc3, 0xb7dd428bb44fc744,
+      0xe3de56d839559570, 0x77afbb8906ccf19a, 0xe66e02ad8e92c12f,
+      0x36cc6f2fe751bc64, 0xf4d28aea3ed69ade, 0xf246fd6a4ca33ab3,
+      0xcae9edaf829a6575, 0x11fa7c88bf4cc73a, 0x98c47bfbae3d8c02,
+      0x27545ea34451a56f, 0x14b4c1a27d26d2b2, 0x7613ca9857e7cbe0,
+      0x02efc8f12e71bb88, 0x9c1a83672eee7d5b, 0x2b89aa9cfde6d9b3,
+      0xabeb2cf68ab463dc, 0xfb3db51d62d71d28, 0x3177cc3e0927e344,
+      0xb5798fc1d348beb6, 0x212c471510859095, 0x191df651c270548d,
+      0x1b15d6b8e8cc3105, 0xdc51a9e369fbab13, 0xb674fd0372fab5aa,
+      0x048aec21666fc8d5, 0x8b15383bc4a7e244, 0xf8945c253a43469f,
+      0x513f31e6bf240064, 0xc37c6225063c266f, 0x2a6747f8952ec44c,
+      0xa7a0f11d3607f268, 0x9b58d5c889166fb3, 0xb75ca76a67212a39,
+      0x9a71a476bf4933f3, 0x3f049a71b475edf7, 0x7a49c8907a278e5e,
+      0xf9a78757d9355ac9, 0xbe1bd9d70ee46398, 0x600e24a76a359a39,
+      0x235905ade793a5f0, 0x940c36e0df8ec13a, 0x9300c551cb93a286,
+      0x5e265b90e4828aba, 0x42dee1626c647735, 0x8cd32910c1f17a8c,
+      0x642f44f3f8290fb0, 0xb73ee167c5f8655e, 0x9d05deadb2a47fe4,
+      0x03b359dff5351708, 0x19a6427c0ee9c907, 0x0692dc026847e0d9,
+      0xe4023ba608b25f1e, 0xf438ad7eea71dfc1, 0x205120c9355d4ac8,
+      0xd4cf2cb1f412c846, 0x82d7d98b87ecf53a, 0x2cc779469cc3d690,
+      0xf93545883141ce8e, 0x0f794c869b82a28a, 0x014e9fccfe7f7d9e,
+      0xb6953652e49e4e0a, 0x68035eabb056e9b6, 0xf1b3a6847e610274,
+      0x59dc584137c0cb55, 0xafb36238ad797ec6, 0xb9f331777a030104,
+      0x2899a97f98140d3b, 0x0ae342d8d4f80ad0, 0xcfb25544c873fbd1,
+      0xcb2498ca84b01a4c, 0x1a50e4a0d8db8406, 0x0afbf05b7c8c146e,
+      0x1b45ee2ee670d71b, 0xef9204d9fcc31075, 0x2a5750d2ef558495,
+      0x8e151888d0ce024e, 0x26882404dd58bcc9, 0x6c830f947bf2195f,
+      0x2ff0c1fa64bf8cfb, 0x8f108f869e11d224, 0x7ce757787a04fd76,
+      0xee55da944ebbbd85, 0x43563645bb00dcd0, 0x643848bf73336681,
+      0x050f54d0478ffd52, 0xc5c1bff1bc3c008c, 0x48fd0f2729c9402d,
+      0x7685b990e3e264af, 0x940dccac3264ed16, 0x688f94ee88c9ba90,
+      0xca112c7825f3944b, 0x584cb5ddba130be2, 0xb7ced01f7140dff6,
+      0xc10dcbb4e77168e6, 0xb5ea4360351ebaef,
   };
 #else
   constexpr uint64_t kGolden[kNumGoldenOutputs] = {
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index 59eb38b..2c651f2 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -211,21 +211,7 @@
 using result_of_t = typename type_traits_internal::result_of<F>::type;
 
 namespace type_traits_internal {
-// In MSVC we can't probe std::hash or stdext::hash because it triggers a
-// static_assert instead of failing substitution. Libc++ prior to 4.0
-// also used a static_assert.
-//
-#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \
-                          _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11)
-#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0
-#else
-#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1
-#endif
 
-#if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
-template <typename Key, typename = size_t>
-struct IsHashable : std::true_type {};
-#else   // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
 template <typename Key, typename = void>
 struct IsHashable : std::false_type {};
 
@@ -235,7 +221,6 @@
     absl::enable_if_t<std::is_convertible<
         decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())),
         std::size_t>::value>> : std::true_type {};
-#endif  // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
 
 struct AssertHashEnabledHelper {
  private:
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc
index 2f8cbc1..228e527 100644
--- a/absl/strings/escaping.cc
+++ b/absl/strings/escaping.cc
@@ -827,7 +827,7 @@
 }
 
 /* clang-format off */
-constexpr std::array<char, 256> kHexValueLenient = {
+constexpr std::array<uint8_t, 256> kHexValueLenient = {
     0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -846,7 +846,7 @@
     0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 };
 
-constexpr std::array<signed char, 256> kHexValueStrict = {
+constexpr std::array<int8_t, 256> kHexValueStrict = {
     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -874,7 +874,7 @@
                               size_t num) {
   for (size_t i = 0; i < num; i++) {
     to[i] = static_cast<char>(kHexValueLenient[from[i * 2] & 0xFF] << 4) +
-            (kHexValueLenient[from[i * 2 + 1] & 0xFF]);
+            static_cast<char>(kHexValueLenient[from[i * 2 + 1] & 0xFF]);
   }
 }
 
@@ -992,8 +992,10 @@
       output, num_bytes, [hex](char* buf, size_t buf_size) {
         auto hex_p = hex.cbegin();
         for (size_t i = 0; i < buf_size; ++i) {
-          int h1 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)];
-          int h2 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)];
+          int h1 = absl::kHexValueStrict[static_cast<size_t>(
+              static_cast<uint8_t>(*hex_p++))];
+          int h2 = absl::kHexValueStrict[static_cast<size_t>(
+              static_cast<uint8_t>(*hex_p++))];
           if (h1 == -1 || h2 == -1) {
             return size_t{0};
           }
diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc
index 4786c88..08618aa 100644
--- a/absl/strings/escaping_test.cc
+++ b/absl/strings/escaping_test.cc
@@ -733,6 +733,10 @@
   bytes = "abc";
   EXPECT_TRUE(absl::HexStringToBytes("", &bytes));
   EXPECT_EQ("", bytes);  // Results in empty output.
+
+  // Ensure there is no sign extension bug on a signed char.
+  hex.assign("\xC8" "b", 2);
+  EXPECT_FALSE(absl::HexStringToBytes(hex, &bytes));
 }
 
 TEST(HexAndBack, HexStringToBytes_and_BytesToHexString) {
diff --git a/absl/strings/internal/append_and_overwrite.h b/absl/strings/internal/append_and_overwrite.h
index 9dec73b..f8d62dc 100644
--- a/absl/strings/internal/append_and_overwrite.h
+++ b/absl/strings/internal/append_and_overwrite.h
@@ -16,9 +16,9 @@
 #define ABSL_STRINGS_INTERNAL_APPEND_AND_OVERWRITE_H_
 
 #include "absl/base/config.h"
-#include "absl/base/internal/throw_delegate.h"
 #include "absl/base/macros.h"
 #include "absl/base/optimization.h"
+#include "absl/base/throw_delegate.h"
 #include "absl/strings/resize_and_overwrite.h"
 
 namespace absl {
@@ -46,8 +46,7 @@
 void StringAppendAndOverwrite(T& str, typename T::size_type append_n,
                               Op append_op) {
   if (ABSL_PREDICT_FALSE(append_n > str.max_size() - str.size())) {
-    absl::base_internal::ThrowStdLengthError(
-        "absl::strings_internal::StringAppendAndOverwrite");
+    ThrowStdLengthError("absl::strings_internal::StringAppendAndOverwrite");
   }
 
   auto old_size = str.size();
diff --git a/absl/strings/resize_and_overwrite.h b/absl/strings/resize_and_overwrite.h
index 04c12d2..102b2bf 100644
--- a/absl/strings/resize_and_overwrite.h
+++ b/absl/strings/resize_and_overwrite.h
@@ -53,9 +53,9 @@
 
 #include "absl/base/config.h"
 #include "absl/base/dynamic_annotations.h"
-#include "absl/base/internal/throw_delegate.h"
 #include "absl/base/macros.h"
 #include "absl/base/optimization.h"
+#include "absl/base/throw_delegate.h"
 
 #if defined(__cpp_lib_string_resize_and_overwrite) && \
     __cpp_lib_string_resize_and_overwrite >= 202110L
@@ -124,7 +124,7 @@
 template <typename T, typename Op>
 void StringResizeAndOverwriteFallback(T& str, typename T::size_type n, Op op) {
   if (ABSL_PREDICT_FALSE(n > str.max_size())) {
-    absl::base_internal::ThrowStdLengthError("absl::StringResizeAndOverwrite");
+    ThrowStdLengthError("absl::StringResizeAndOverwrite");
   }
 #ifdef ABSL_HAVE_MEMORY_SANITIZER
   auto old_size = str.size();
diff --git a/absl/time/clock.h b/absl/time/clock.h
index 41d2cf2..2be89a2 100644
--- a/absl/time/clock.h
+++ b/absl/time/clock.h
@@ -34,6 +34,9 @@
 // Now()
 //
 // Returns the current time, expressed as an `absl::Time` absolute time value.
+//
+// To improve testability, consider injecting an absl::Clock and using
+// absl::Clock::TimeNow() instead.
 absl::Time Now();
 
 // GetCurrentTimeNanos()
diff --git a/absl/time/internal/cctz/src/time_zone_name_win.cc b/absl/time/internal/cctz/src/time_zone_name_win.cc
index 2b8724d..07aa8fa 100644
--- a/absl/time/internal/cctz/src/time_zone_name_win.cc
+++ b/absl/time/internal/cctz/src/time_zone_name_win.cc
@@ -131,7 +131,7 @@
 
 // Convert wchar_t array (UTF-16) to UTF-8 string
 std::string Utf16ToUtf8(const wchar_t* ptr, size_t size) {
-  if (size > std::numeric_limits<int>::max()) {
+  if (size > static_cast<size_t>(std::numeric_limits<int>::max())) {
     return std::string();
   }
   const int chars_len = static_cast<int>(size);
@@ -140,7 +140,6 @@
       std::min<size_t>(result.capacity(), std::numeric_limits<int>::max()), 1);
   do {
     result.resize(len);
-    // TODO: Switch to std::string::data() when we require C++17 or higher.
     len = static_cast<std::size_t>(::WideCharToMultiByte(
         CP_UTF8, WC_ERR_INVALID_CHARS, ptr, chars_len, &result[0],
         static_cast<int>(len), nullptr, nullptr));
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h
index cdf3941..9e8e418 100644
--- a/absl/types/internal/span.h
+++ b/absl/types/internal/span.h
@@ -23,7 +23,6 @@
 
 #include "absl/algorithm/algorithm.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/throw_delegate.h"
 #include "absl/meta/type_traits.h"
 
 namespace absl {
diff --git a/absl/types/span.h b/absl/types/span.h
index 60e1ea8..b9f6b74 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -64,11 +64,11 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/throw_delegate.h"
 #include "absl/base/macros.h"
 #include "absl/base/nullability.h"
 #include "absl/base/optimization.h"
 #include "absl/base/port.h"  // TODO(strel): remove this include
+#include "absl/base/throw_delegate.h"
 #include "absl/hash/internal/weakly_mixed_integer.h"
 #include "absl/meta/type_traits.h"
 #include "absl/types/internal/span.h"
@@ -345,8 +345,7 @@
   constexpr reference at(size_type i) const {
     return ABSL_PREDICT_TRUE(i < size())  //
                ? *(data() + i)
-               : (base_internal::ThrowStdOutOfRange(
-                      "Span::at failed bounds check"),
+               : (ThrowStdOutOfRange("Span::at failed bounds check"),
                   *(data() + i));
   }
 
@@ -465,9 +464,8 @@
   //   absl::MakeSpan(vec).subspan(4);     // {}
   //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
   constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
-    return (pos <= size())
-               ? Span(data() + pos, (std::min)(size() - pos, len))
-               : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
+    return (pos <= size()) ? Span(data() + pos, (std::min)(size() - pos, len))
+                           : (ThrowStdOutOfRange("pos > size()"), Span());
   }
 
   // Span::first()
@@ -482,9 +480,8 @@
   //   absl::MakeSpan(vec).first(3);  // {10, 11, 12}
   //   absl::MakeSpan(vec).first(5);  // throws std::out_of_range
   constexpr Span first(size_type len) const {
-    return (len <= size())
-               ? Span(data(), len)
-               : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
+    return (len <= size()) ? Span(data(), len)
+                           : (ThrowStdOutOfRange("len > size()"), Span());
   }
 
   // Span::last()
@@ -499,9 +496,8 @@
   //   absl::MakeSpan(vec).last(3);  // {11, 12, 13}
   //   absl::MakeSpan(vec).last(5);  // throws std::out_of_range
   constexpr Span last(size_type len) const {
-    return (len <= size())
-               ? Span(size() - len + data(), len)
-               : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
+    return (len <= size()) ? Span(size() - len + data(), len)
+                           : (ThrowStdOutOfRange("len > size()"), Span());
   }
 
   // Support for absl::Hash.
diff --git a/ci/linux_clang-latest_libcxx_asan_bazel.sh b/ci/linux_clang-latest_libcxx_asan_bazel.sh
index 0c1ba32..7f36980 100755
--- a/ci/linux_clang-latest_libcxx_asan_bazel.sh
+++ b/ci/linux_clang-latest_libcxx_asan_bazel.sh
@@ -94,6 +94,7 @@
           --copt=\"-fno-sanitize-recover=${UBSAN_CHECKS}\" \
           --copt=\"-fno-sanitize-blacklist\" \
           --copt=-Werror \
+          --define=\"absl=1\" \
           --enable_bzlmod=true \
           --features=external_include_paths \
           --keep_going \
diff --git a/ci/linux_clang-latest_libcxx_tsan_bazel.sh b/ci/linux_clang-latest_libcxx_tsan_bazel.sh
index 94f9c8a..235971b 100755
--- a/ci/linux_clang-latest_libcxx_tsan_bazel.sh
+++ b/ci/linux_clang-latest_libcxx_tsan_bazel.sh
@@ -89,6 +89,7 @@
           --copt=\"-fsanitize=thread\" \
           --copt=\"-fno-sanitize-blacklist\" \
           --copt=-Werror \
+          --define=\"absl=1\" \
           --enable_bzlmod=true \
           --features=external_include_paths \
           --keep_going \
diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh
index d50f979..1f509bd 100755
--- a/ci/macos_xcode_bazel.sh
+++ b/ci/macos_xcode_bazel.sh
@@ -57,6 +57,7 @@
 ${BAZEL_BIN} test ... \
   --copt="-DGTEST_REMOVE_LEGACY_TEST_CASEAPI_=1" \
   --copt="-Werror" \
+  --define="absl=1" \
   --cxxopt="-std=c++17" \
   --enable_bzlmod=true \
   --features=external_include_paths \