Replace std::TRAIT<...>::value with std::TRAIT_v<...> equivalents

PiperOrigin-RevId: 927479222
Change-Id: I70c38e557c8527f72bf86281d88621a5eca26df3
diff --git a/absl/base/casts.h b/absl/base/casts.h
index f75f235..1a85798 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -178,10 +178,10 @@
 
 template <typename Dest, typename Source,
           std::enable_if_t<sizeof(Dest) == sizeof(Source) &&
-                               std::is_trivially_copyable<Source>::value &&
-                               std::is_trivially_copyable<Dest>::value
+                               std::is_trivially_copyable_v<Source> &&
+                               std::is_trivially_copyable_v<Dest>
 #if !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
-                               && std::is_default_constructible<Dest>::value
+                               && std::is_default_constructible_v<Dest>
 #endif  // !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
                            ,
                            int> = 0>
@@ -253,19 +253,19 @@
 template <typename To, typename From>  // use like this: down_cast<T*>(foo);
 [[nodiscard]]
 inline To down_cast(From* f) {  // so we only accept pointers
-  static_assert(std::is_pointer<To>::value, "target type not a pointer");
+  static_assert(std::is_pointer_v<To>, "target type not a pointer");
   // dynamic_cast allows casting to the same type or a more cv-qualified
   // version of the same type without them being polymorphic.
-  if constexpr (!std::is_same<std::remove_cv_t<std::remove_pointer_t<To>>,
-                              std::remove_cv_t<From>>::value) {
-    static_assert(std::is_polymorphic<From>::value,
+  if constexpr (!std::is_same_v<std::remove_cv_t<std::remove_pointer_t<To>>,
+                                std::remove_cv_t<From>>) {
+    static_assert(std::is_polymorphic_v<From>,
                   "source type must be polymorphic");
-    static_assert(std::is_polymorphic<std::remove_pointer_t<To>>::value,
+    static_assert(std::is_polymorphic_v<std::remove_pointer_t<To>>,
                   "target type must be polymorphic");
   }
   static_assert(
-      std::is_convertible<std::remove_cv_t<std::remove_pointer_t<To>>*,
-                          std::remove_cv_t<From>*>::value,
+      std::is_convertible_v<std::remove_cv_t<std::remove_pointer_t<To>>*,
+                            std::remove_cv_t<From>*>,
       "target type not derived from source type");
 
   absl::base_internal::ValidateDownCast<To>(f);
@@ -284,20 +284,19 @@
 template <typename To, typename From>
 [[nodiscard]]
 inline To down_cast(From& f) {
-  static_assert(std::is_lvalue_reference<To>::value,
-                "target type not a reference");
+  static_assert(std::is_lvalue_reference_v<To>, "target type not a reference");
   // dynamic_cast allows casting to the same type or a more cv-qualified
   // version of the same type without them being polymorphic.
-  if constexpr (!std::is_same<std::remove_cv_t<std::remove_reference_t<To>>,
-                              std::remove_cv_t<From>>::value) {
-    static_assert(std::is_polymorphic<From>::value,
+  if constexpr (!std::is_same_v<std::remove_cv_t<std::remove_reference_t<To>>,
+                                std::remove_cv_t<From>>) {
+    static_assert(std::is_polymorphic_v<From>,
                   "source type must be polymorphic");
-    static_assert(std::is_polymorphic<std::remove_reference_t<To>>::value,
+    static_assert(std::is_polymorphic_v<std::remove_reference_t<To>>,
                   "target type must be polymorphic");
   }
   static_assert(
-      std::is_convertible<std::remove_cv_t<std::remove_reference_t<To>>*,
-                          std::remove_cv_t<From>*>::value,
+      std::is_convertible_v<std::remove_cv_t<std::remove_reference_t<To>>*,
+                            std::remove_cv_t<From>*>,
       "target type not derived from source type");
 
   absl::base_internal::ValidateDownCast<std::remove_reference_t<To>*>(
diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc
index d615a38..5e98c5f 100644
--- a/absl/base/exception_safety_testing_test.cc
+++ b/absl/base/exception_safety_testing_test.cc
@@ -936,8 +936,8 @@
 
 TEST(ThrowingValueTraitsTest, RelationalOperators) {
   ThrowingValue<> a, b;
-  EXPECT_TRUE((std::is_convertible<decltype(a == b), bool>::value));
-  EXPECT_TRUE((std::is_convertible<decltype(a != b), bool>::value));
+  EXPECT_TRUE((std::is_convertible_v<decltype(a == b), bool>));
+  EXPECT_TRUE((std::is_convertible_v<decltype(a != b), bool>));
   EXPECT_TRUE((std::is_convertible<decltype(a < b), bool>::value));
   EXPECT_TRUE((std::is_convertible<decltype(a <= b), bool>::value));
   EXPECT_TRUE((std::is_convertible<decltype(a > b), bool>::value));
@@ -945,10 +945,10 @@
 }
 
 TEST(ThrowingAllocatorTraitsTest, Assignablility) {
-  EXPECT_TRUE(std::is_move_assignable<ThrowingAllocator<int>>::value);
-  EXPECT_TRUE(std::is_copy_assignable<ThrowingAllocator<int>>::value);
-  EXPECT_TRUE(std::is_nothrow_move_assignable<ThrowingAllocator<int>>::value);
-  EXPECT_TRUE(std::is_nothrow_copy_assignable<ThrowingAllocator<int>>::value);
+  EXPECT_TRUE(std::is_move_assignable_v<ThrowingAllocator<int>>);
+  EXPECT_TRUE(std::is_copy_assignable_v<ThrowingAllocator<int>>);
+  EXPECT_TRUE(std::is_nothrow_move_assignable_v<ThrowingAllocator<int>>);
+  EXPECT_TRUE(std::is_nothrow_copy_assignable_v<ThrowingAllocator<int>>);
 }
 
 }  // namespace
diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h
index a2d128e..4cccf96 100644
--- a/absl/base/internal/exception_safety_testing.h
+++ b/absl/base/internal/exception_safety_testing.h
@@ -845,10 +845,10 @@
 
 template <size_t LazyContractsCount, typename LazyFactory,
           typename LazyOperation>
-using EnableIfTestable = typename std::enable_if_t<
-    LazyContractsCount != 0 &&
-    !std::is_same<LazyFactory, UninitializedT>::value &&
-    !std::is_same<LazyOperation, UninitializedT>::value>;
+using EnableIfTestable =
+    typename std::enable_if_t<LazyContractsCount != 0 &&
+                              !std::is_same_v<LazyFactory, UninitializedT> &&
+                              !std::is_same_v<LazyOperation, UninitializedT>>;
 
 template <typename Factory = UninitializedT,
           typename Operation = UninitializedT, typename... Contracts>
diff --git a/absl/base/internal/strerror.cc b/absl/base/internal/strerror.cc
index de91c05..519b93f 100644
--- a/absl/base/internal/strerror.cc
+++ b/absl/base/internal/strerror.cc
@@ -39,7 +39,7 @@
   // The type of `ret` is platform-specific; both of these branches must compile
   // either way but only one will execute on any given platform:
   auto ret = strerror_r(errnum, buf, buflen);
-  if (std::is_same<decltype(ret), int>::value) {
+  if (std::is_same_v<decltype(ret), int>) {
     // XSI `strerror_r`; `ret` is `int`:
     if (ret) *buf = '\0';
     return buf;
diff --git a/absl/base/no_destructor.h b/absl/base/no_destructor.h
index 7c8c826..a0e990e 100644
--- a/absl/base/no_destructor.h
+++ b/absl/base/no_destructor.h
@@ -115,8 +115,8 @@
   // Forwards arguments to the T's constructor: calls T(args...).
   template <typename... Ts,
             // Disable this overload when it might collide with copy/move.
-            std::enable_if_t<!std::is_same<void(std::decay_t<Ts>&...),
-                                           void(NoDestructor&)>::value,
+            std::enable_if_t<!std::is_same_v<void(std::decay_t<Ts>&...),
+                                             void(NoDestructor&)>,
                              int> = 0>
   explicit constexpr NoDestructor(Ts&&... args)
       : impl_(std::forward<Ts>(args)...) {}
@@ -175,7 +175,7 @@
   // potential once-init runtime initialization. It somewhat defeats the
   // purpose of NoDestructor in this case, but this makes the class more
   // friendly to generic code.
-  std::conditional_t<std::is_trivially_destructible<T>::value, DirectImpl,
+  std::conditional_t<std::is_trivially_destructible_v<T>, DirectImpl,
                      PlacementImpl>
       impl_;
 };
diff --git a/absl/base/no_destructor_test.cc b/absl/base/no_destructor_test.cc
index 316b213..161d86f 100644
--- a/absl/base/no_destructor_test.cc
+++ b/absl/base/no_destructor_test.cc
@@ -60,21 +60,20 @@
 TEST(NoDestructorTest, Noncopyable) {
   using T = absl::NoDestructor<int>;
 
-  EXPECT_FALSE((std::is_constructible<T, T>::value));
-  EXPECT_FALSE((std::is_constructible<T, const T>::value));
-  EXPECT_FALSE((std::is_constructible<T, T&>::value));
-  EXPECT_FALSE((std::is_constructible<T, const T&>::value));
+  EXPECT_FALSE((std::is_constructible_v<T, T>));
+  EXPECT_FALSE((std::is_constructible_v<T, const T>));
+  EXPECT_FALSE((std::is_constructible_v<T, T&>));
+  EXPECT_FALSE((std::is_constructible_v<T, const T&>));
 
-  EXPECT_FALSE((std::is_assignable<T&, T>::value));
-  EXPECT_FALSE((std::is_assignable<T&, const T>::value));
-  EXPECT_FALSE((std::is_assignable<T&, T&>::value));
-  EXPECT_FALSE((std::is_assignable<T&, const T&>::value));
+  EXPECT_FALSE((std::is_assignable_v<T&, T>));
+  EXPECT_FALSE((std::is_assignable_v<T&, const T>));
+  EXPECT_FALSE((std::is_assignable_v<T&, T&>));
+  EXPECT_FALSE((std::is_assignable_v<T&, const T&>));
 }
 
 TEST(NoDestructorTest, Interface) {
-  EXPECT_TRUE(std::is_trivially_destructible<absl::NoDestructor<Blob>>::value);
-  EXPECT_TRUE(
-      std::is_trivially_destructible<absl::NoDestructor<const Blob>>::value);
+  EXPECT_TRUE(std::is_trivially_destructible_v<absl::NoDestructor<Blob>>);
+  EXPECT_TRUE(std::is_trivially_destructible_v<absl::NoDestructor<const Blob>>);
   {
     absl::NoDestructor<Blob> b;  // default c-tor
     // access: *, ->, get()
@@ -173,12 +172,10 @@
 
 TEST(NoDestructorTest, StaticPattern) {
   EXPECT_TRUE(
-      std::is_trivially_destructible<absl::NoDestructor<std::string>>::value);
-  EXPECT_TRUE(
-      std::is_trivially_destructible<absl::NoDestructor<MyArray>>::value);
-  EXPECT_TRUE(
-      std::is_trivially_destructible<absl::NoDestructor<MyVector>>::value);
-  EXPECT_TRUE(std::is_trivially_destructible<absl::NoDestructor<int>>::value);
+      std::is_trivially_destructible_v<absl::NoDestructor<std::string>>);
+  EXPECT_TRUE(std::is_trivially_destructible_v<absl::NoDestructor<MyArray>>);
+  EXPECT_TRUE(std::is_trivially_destructible_v<absl::NoDestructor<MyVector>>);
+  EXPECT_TRUE(std::is_trivially_destructible_v<absl::NoDestructor<int>>);
 
   EXPECT_EQ(*Str0(), "");
   Str0()->append("foo");
@@ -198,7 +195,7 @@
 
 TEST(NoDestructorTest, ClassTemplateArgumentDeduction) {
   absl::NoDestructor i(1);
-  static_assert(std::is_same<decltype(i), absl::NoDestructor<int>>::value,
+  static_assert(std::is_same_v<decltype(i), absl::NoDestructor<int>>,
                 "Expected deduced type to be int.");
 }
 
diff --git a/absl/base/nullability_test.cc b/absl/base/nullability_test.cc
index bccf1af..648b4be 100644
--- a/absl/base/nullability_test.cc
+++ b/absl/base/nullability_test.cc
@@ -42,49 +42,49 @@
 }
 
 TEST(PassThroughTest, PassesThroughRawPointerToInt) {
-  EXPECT_TRUE((std::is_same<int* absl_nonnull, int*>::value));
-  EXPECT_TRUE((std::is_same<int* absl_nullable, int*>::value));
-  EXPECT_TRUE((std::is_same<int* absl_nullability_unknown, int*>::value));
+  EXPECT_TRUE((std::is_same_v<int* absl_nonnull, int*>));
+  EXPECT_TRUE((std::is_same_v<int* absl_nullable, int*>));
+  EXPECT_TRUE((std::is_same_v<int* absl_nullability_unknown, int*>));
 }
 
 TEST(PassThroughTest, PassesThroughRawPointerToVoid) {
-  EXPECT_TRUE((std::is_same<void* absl_nonnull, void*>::value));
-  EXPECT_TRUE((std::is_same<void* absl_nullable, void*>::value));
-  EXPECT_TRUE((std::is_same<void* absl_nullability_unknown, void*>::value));
+  EXPECT_TRUE((std::is_same_v<void* absl_nonnull, void*>));
+  EXPECT_TRUE((std::is_same_v<void* absl_nullable, void*>));
+  EXPECT_TRUE((std::is_same_v<void* absl_nullability_unknown, void*>));
 }
 
 TEST(PassThroughTest, PassesThroughUniquePointerToInt) {
   using T = std::unique_ptr<int>;
-  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+  EXPECT_TRUE((std::is_same_v<absl_nonnull T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullable T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullability_unknown T, T>));
 }
 
 TEST(PassThroughTest, PassesThroughSharedPointerToInt) {
   using T = std::shared_ptr<int>;
-  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+  EXPECT_TRUE((std::is_same_v<absl_nonnull T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullable T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullability_unknown T, T>));
 }
 
 TEST(PassThroughTest, PassesThroughSharedPointerToVoid) {
   using T = std::shared_ptr<void>;
-  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+  EXPECT_TRUE((std::is_same_v<absl_nonnull T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullable T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullability_unknown T, T>));
 }
 
 TEST(PassThroughTest, PassesThroughPointerToMemberObject) {
   using T = decltype(&std::pair<int, int>::first);
-  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+  EXPECT_TRUE((std::is_same_v<absl_nonnull T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullable T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullability_unknown T, T>));
 }
 
 TEST(PassThroughTest, PassesThroughPointerToMemberFunction) {
   using T = decltype(&std::unique_ptr<int>::reset);
-  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
-  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+  EXPECT_TRUE((std::is_same_v<absl_nonnull T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullable T, T>));
+  EXPECT_TRUE((std::is_same_v<absl_nullability_unknown T, T>));
 }
 }  // namespace
diff --git a/absl/cleanup/cleanup_test.cc b/absl/cleanup/cleanup_test.cc
index 52774d7..0d407b2 100644
--- a/absl/cleanup/cleanup_test.cc
+++ b/absl/cleanup/cleanup_test.cc
@@ -28,7 +28,7 @@
 
 template <typename Type1, typename Type2>
 constexpr bool IsSame() {
-  return (std::is_same<Type1, Type2>::value);
+  return (std::is_same_v<Type1, Type2>);
 }
 
 struct IdentityFactory {
diff --git a/absl/cleanup/internal/cleanup.h b/absl/cleanup/internal/cleanup.h
index 0a6c3ee..f078323 100644
--- a/absl/cleanup/internal/cleanup.h
+++ b/absl/cleanup/internal/cleanup.h
@@ -33,13 +33,12 @@
 
 template <typename Arg, typename... Args>
 constexpr bool WasDeduced() {
-  return (std::is_same<cleanup_internal::Tag, Arg>::value) &&
-         (sizeof...(Args) == 0);
+  return (std::is_same_v<cleanup_internal::Tag, Arg>) && (sizeof...(Args) == 0);
 }
 
 template <typename Callback>
 constexpr bool ReturnsVoid() {
-  return (std::is_same<std::invoke_result_t<Callback>, void>::value);
+  return (std::is_same_v<std::invoke_result_t<Callback>, void>);
 }
 
 template <typename Callback>
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc
index 1bae02e..8668777 100644
--- a/absl/container/btree_test.cc
+++ b/absl/container/btree_test.cc
@@ -1097,9 +1097,9 @@
 
   template <typename Btree>
   constexpr static bool FieldTypeEqualsSlotType() {
-    return std::is_same<
+    return std::is_same_v<
         typename btree_node<typename Btree::params_type>::field_type,
-        typename btree_node<typename Btree::params_type>::slot_type>::value;
+        typename btree_node<typename Btree::params_type>::slot_type>;
   }
 };
 
@@ -1237,16 +1237,16 @@
 void AssertKeyCompareStringAdapted() {
   using Adapted = typename key_compare_adapter<Compare, Key>::type;
   static_assert(
-      std::is_same<Adapted, StringBtreeDefaultLess>::value ||
-          std::is_same<Adapted, StringBtreeDefaultGreater>::value,
+      std::is_same_v<Adapted, StringBtreeDefaultLess> ||
+          std::is_same_v<Adapted, StringBtreeDefaultGreater>,
       "key_compare_adapter should have string-adapted this comparator.");
 }
 template <typename Compare, typename Key>
 void AssertKeyCompareNotStringAdapted() {
   using Adapted = typename key_compare_adapter<Compare, Key>::type;
   static_assert(
-      !std::is_same<Adapted, StringBtreeDefaultLess>::value &&
-          !std::is_same<Adapted, StringBtreeDefaultGreater>::value,
+      !std::is_same_v<Adapted, StringBtreeDefaultLess> &&
+          !std::is_same_v<Adapted, StringBtreeDefaultGreater>,
       "key_compare_adapter shouldn't have string-adapted this comparator.");
 }
 
@@ -2804,16 +2804,12 @@
 
 TEST(Btree, SetIteratorsAreConst) {
   using Set = absl::btree_set<int>;
-  EXPECT_TRUE(
-      (std::is_same<typename Set::iterator::reference, const int &>::value));
-  EXPECT_TRUE(
-      (std::is_same<typename Set::iterator::pointer, const int *>::value));
+  EXPECT_TRUE((std::is_same_v<typename Set::iterator::reference, const int&>));
+  EXPECT_TRUE((std::is_same_v<typename Set::iterator::pointer, const int*>));
 
   using MSet = absl::btree_multiset<int>;
-  EXPECT_TRUE(
-      (std::is_same<typename MSet::iterator::reference, const int &>::value));
-  EXPECT_TRUE(
-      (std::is_same<typename MSet::iterator::pointer, const int *>::value));
+  EXPECT_TRUE((std::is_same_v<typename MSet::iterator::reference, const int&>));
+  EXPECT_TRUE((std::is_same_v<typename MSet::iterator::pointer, const int*>));
 }
 
 TEST(Btree, AllocConstructor) {
diff --git a/absl/container/chunked_queue.h b/absl/container/chunked_queue.h
index 74bf39e..8503825 100644
--- a/absl/container/chunked_queue.h
+++ b/absl/container/chunked_queue.h
@@ -173,7 +173,7 @@
     using iterator_category = std::forward_iterator_tag;
     using value_type = typename AllocatorTraits::value_type;
     using difference_type = typename AllocatorTraits::difference_type;
-    using pointer = std::conditional_t<std::is_const<CT>::value,
+    using pointer = std::conditional_t<std::is_const_v<CT>,
                                        typename AllocatorTraits::const_pointer,
                                        typename AllocatorTraits::pointer>;
     using reference = CT&;
diff --git a/absl/container/chunked_queue_test.cc b/absl/container/chunked_queue_test.cc
index a66d0c2..bee7e03 100644
--- a/absl/container/chunked_queue_test.cc
+++ b/absl/container/chunked_queue_test.cc
@@ -525,8 +525,8 @@
 TEST(ChunkedQueue, IteratorConversion) {
   using ConstIter = absl::chunked_queue<int64_t>::const_iterator;
   using Iter = absl::chunked_queue<int64_t>::iterator;
-  EXPECT_FALSE((std::is_convertible<ConstIter, Iter>::value));
-  EXPECT_TRUE((std::is_convertible<Iter, ConstIter>::value));
+  EXPECT_FALSE((std::is_convertible_v<ConstIter, Iter>));
+  EXPECT_TRUE((std::is_convertible_v<Iter, ConstIter>));
   absl::chunked_queue<int64_t> q;
   ConstIter it1 = q.begin();
   ConstIter it2 = q.cbegin();
@@ -534,7 +534,7 @@
   it1 = q.end();
   it2 = q.cend();
   it3 = q.end();
-  EXPECT_FALSE((std::is_assignable<Iter, ConstIter>::value));
+  EXPECT_FALSE((std::is_assignable_v<Iter, ConstIter>));
 }
 
 struct TestEntry {
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index 77949bf..48ac57f 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -79,7 +79,7 @@
 template <typename T, size_t N = kFixedArrayUseDefault,
           typename A = std::allocator<T>>
 class ABSL_ATTRIBUTE_WARN_UNUSED FixedArray {
-  static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
+  static_assert(!std::is_array_v<T> || std::extent_v<T> > 0,
                 "Arrays with unknown bounds cannot be used with FixedArray.");
 
   static constexpr size_t kInlineBytesDefault = 256;
@@ -89,15 +89,15 @@
   using EnableIfInputIterator =
       std::enable_if_t<base_internal::IsAtLeastInputIterator<Iterator>::value>;
   static constexpr bool NoexceptCopyable() {
-    return std::is_nothrow_copy_constructible<StorageElement>::value &&
+    return std::is_nothrow_copy_constructible_v<StorageElement> &&
            absl::allocator_is_nothrow<allocator_type>::value;
   }
   static constexpr bool NoexceptMovable() {
-    return std::is_nothrow_move_constructible<StorageElement>::value &&
+    return std::is_nothrow_move_constructible_v<StorageElement> &&
            absl::allocator_is_nothrow<allocator_type>::value;
   }
   static constexpr bool DefaultConstructorIsNonTrivial() {
-    return !std::is_trivially_default_constructible<StorageElement>::value;
+    return !std::is_trivially_default_constructible_v<StorageElement>;
   }
 
  public:
@@ -416,14 +416,14 @@
   //     will always overflow destination buffer [-Werror]
   //
   template <typename OuterT, typename InnerT = std::remove_extent_t<OuterT>,
-            size_t InnerN = std::extent<OuterT>::value>
+            size_t InnerN = std::extent_v<OuterT>>
   struct StorageElementWrapper {
     InnerT array[InnerN];
   };
 
   using StorageElement =
-      std::conditional_t<std::is_array<value_type>::value,
-                          StorageElementWrapper<value_type>, value_type>;
+      std::conditional_t<std::is_array_v<value_type>,
+                         StorageElementWrapper<value_type>, value_type>;
 
   static pointer AsValueType(pointer ptr) { return ptr; }
   static pointer AsValueType(StorageElementWrapper<value_type>* ptr) {
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc
index 0839b00..effbae3 100644
--- a/absl/container/flat_hash_map_test.cc
+++ b/absl/container/flat_hash_map_test.cc
@@ -119,11 +119,11 @@
 TEST(FlatHashMap, Relocatability) {
   static_assert(absl::is_trivially_relocatable<int>::value);
   static_assert(
-      std::is_same<decltype(absl::container_internal::FlatHashMapPolicy<
-                            int, int>::transfer<std::allocator<char>>(nullptr,
-                                                                      nullptr,
-                                                                      nullptr)),
-                   std::true_type>::value);
+      std::is_same_v<
+          decltype(absl::container_internal::FlatHashMapPolicy<
+                   int, int>::transfer<std::allocator<char>>(nullptr, nullptr,
+                                                             nullptr)),
+          std::true_type>);
 
   struct NonRelocatable {
     NonRelocatable() = default;
@@ -134,11 +134,11 @@
 
   EXPECT_FALSE(absl::is_trivially_relocatable<NonRelocatable>::value);
   EXPECT_TRUE(
-      (std::is_same<decltype(absl::container_internal::FlatHashMapPolicy<
-                            int, NonRelocatable>::
-                                transfer<std::allocator<char>>(nullptr, nullptr,
-                                                               nullptr)),
-                   std::false_type>::value));
+      (std::is_same_v<decltype(absl::container_internal::FlatHashMapPolicy<
+                               int, NonRelocatable>::
+                                   transfer<std::allocator<char>>(
+                                       nullptr, nullptr, nullptr)),
+                      std::false_type>));
 }
 
 // gcc becomes unhappy if this is inside the method, so pull it out here.
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 020e37f..8132564 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -193,8 +193,8 @@
     // allocator doesn't do anything fancy, and there is nothing on the heap
     // then we know it is legal for us to simply memcpy the other vector's
     // inlined bytes to form our copy of its elements.
-    if (std::is_trivially_copy_constructible<value_type>::value &&
-        std::is_same<A, std::allocator<value_type>>::value &&
+    if (std::is_trivially_copy_constructible_v<value_type> &&
+        std::is_same_v<A, std::allocator<value_type>> &&
         !other.storage_.GetIsAllocated()) {
       storage_.MemcpyFrom(other.storage_);
       return;
@@ -219,7 +219,7 @@
   // or `value_type`'s move constructor is specified as `noexcept`.
   InlinedVector(InlinedVector&& other) noexcept(
       absl::allocator_is_nothrow<allocator_type>::value ||
-      std::is_nothrow_move_constructible<value_type>::value)
+      std::is_nothrow_move_constructible_v<value_type>)
       : storage_(other.storage_.GetAllocator()) {
     // Fast path: if the value type can be trivially relocated (i.e. moved from
     // and destroyed), and we know the allocator doesn't do anything fancy, then
@@ -227,7 +227,7 @@
     // and remove its own reference to them. It's as if we had individually
     // move-constructed each value and then destroyed the original.
     if (absl::is_trivially_relocatable<value_type>::value &&
-        std::is_same<A, std::allocator<value_type>>::value) {
+        std::is_same_v<A, std::allocator<value_type>>) {
       storage_.MemcpyFrom(other.storage_);
       other.storage_.SetInlinedSize(0);
       return;
@@ -273,7 +273,7 @@
     // and remove its own reference to them. It's as if we had individually
     // move-constructed each value and then destroyed the original.
     if (absl::is_trivially_relocatable<value_type>::value &&
-        std::is_same<A, std::allocator<value_type>>::value) {
+        std::is_same_v<A, std::allocator<value_type>>) {
       storage_.MemcpyFrom(other.storage_);
       other.storage_.SetInlinedSize(0);
       return;
@@ -858,8 +858,8 @@
     // Assumption check: we shouldn't be told to use memcpy to implement move
     // assignment unless we have trivially destructible elements and an
     // allocator that does nothing fancy.
-    static_assert(std::is_trivially_destructible<value_type>::value, "");
-    static_assert(std::is_same<A, std::allocator<value_type>>::value, "");
+    static_assert(std::is_trivially_destructible_v<value_type>, "");
+    static_assert(std::is_same_v<A, std::allocator<value_type>>, "");
 
     // Throw away our existing heap allocation, if any. There is no need to
     // destroy the existing elements one by one because we know they are
diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc
index ba96be3..56edf09 100644
--- a/absl/container/inlined_vector_test.cc
+++ b/absl/container/inlined_vector_test.cc
@@ -24,6 +24,7 @@
 #include <sstream>
 #include <stdexcept>
 #include <string>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
@@ -475,16 +476,16 @@
   v.emplace(v.begin(), MoveOnly{});
 }
 TEST(InlinedVectorTest, Noexcept) {
-  EXPECT_TRUE(std::is_nothrow_move_constructible<IntVec>::value);
-  EXPECT_TRUE((std::is_nothrow_move_constructible<
-               absl::InlinedVector<MoveOnly, 2>>::value));
+  EXPECT_TRUE(std::is_nothrow_move_constructible_v<IntVec>);
+  EXPECT_TRUE(
+      (std::is_nothrow_move_constructible_v<absl::InlinedVector<MoveOnly, 2>>));
 
   struct MoveCanThrow {
     MoveCanThrow(MoveCanThrow&&) {}
   };
   EXPECT_EQ(absl::default_allocator_is_nothrow::value,
-            (std::is_nothrow_move_constructible<
-                absl::InlinedVector<MoveCanThrow, 2>>::value));
+            (std::is_nothrow_move_constructible_v<
+                absl::InlinedVector<MoveCanThrow, 2>>));
 }
 
 TEST(InlinedVectorTest, EmplaceBack) {
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h
index 0e0b4bb..5d84bc6 100644
--- a/absl/container/internal/btree.h
+++ b/absl/container/internal/btree.h
@@ -171,7 +171,7 @@
 };
 
 // See below comments for checked_compare.
-template <typename Compare, bool is_class = std::is_class<Compare>::value>
+template <typename Compare, bool is_class = std::is_class_v<Compare>>
 struct checked_compare_base : Compare {
   using Compare::Compare;
   explicit checked_compare_base(Compare c) : Compare(std::move(c)) {}
@@ -232,11 +232,11 @@
     // Allow converting to Compare for use in key_comp()/value_comp().
     explicit operator Compare() const { return comp(); }
 
-    template <typename T, typename U,
-              std::enable_if_t<
-                  std::is_same<bool, compare_result_t<Compare, T, U>>::value,
-                  int> = 0>
-    bool operator()(const T &lhs, const U &rhs) const {
+    template <
+        typename T, typename U,
+        std::enable_if_t<std::is_same_v<bool, compare_result_t<Compare, T, U>>,
+                         int> = 0>
+    bool operator()(const T& lhs, const U& rhs) const {
       // NOTE: if any of these assertions fail, then the comparator does not
       // establish a strict-weak-ordering (see
       // https://en.cppreference.com/w/cpp/named_req/Compare).
@@ -249,10 +249,10 @@
 
     template <
         typename T, typename U,
-        std::enable_if_t<std::is_convertible<compare_result_t<Compare, T, U>,
-                                              absl::weak_ordering>::value,
-                          int> = 0>
-    absl::weak_ordering operator()(const T &lhs, const U &rhs) const {
+        std::enable_if_t<std::is_convertible_v<compare_result_t<Compare, T, U>,
+                                               absl::weak_ordering>,
+                         int> = 0>
+    absl::weak_ordering operator()(const T& lhs, const U& rhs) const {
       // NOTE: if any of these assertions fail, then the comparator does not
       // establish a strict-weak-ordering (see
       // https://en.cppreference.com/w/cpp/named_req/Compare).
@@ -273,7 +273,7 @@
     }
   };
   using type = std::conditional_t<
-      std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase, Compare>::value,
+      std::is_base_of_v<BtreeTestOnlyCheckedCompareOptOutBase, Compare>,
       Compare, checked_compare>;
 };
 
@@ -342,8 +342,8 @@
 template <typename Compare, typename Key>
 constexpr bool compare_has_valid_result_type() {
   using compare_result_type = compare_result_t<Compare, Key, Key>;
-  return std::is_same<compare_result_type, bool>::value ||
-         std::is_convertible<compare_result_type, absl::weak_ordering>::value;
+  return std::is_same_v<compare_result_type, bool> ||
+         std::is_convertible_v<compare_result_type, absl::weak_ordering>;
 }
 
 template <typename original_key_compare, typename value_type>
@@ -384,8 +384,8 @@
                           typename key_compare_adapter<Compare, Key>::type>;
 
   static constexpr bool kIsKeyCompareStringAdapted =
-      std::is_same<key_compare, StringBtreeDefaultLess>::value ||
-      std::is_same<key_compare, StringBtreeDefaultGreater>::value;
+      std::is_same_v<key_compare, StringBtreeDefaultLess> ||
+      std::is_same_v<key_compare, StringBtreeDefaultGreater>;
   static constexpr bool kIsKeyCompareTransparent =
       IsTransparent<original_key_compare>::value || kIsKeyCompareStringAdapted;
 
@@ -423,9 +423,9 @@
   //   that we know has the same equivalence classes for all lookup types.
   template <typename LookupKey>
   constexpr static bool can_have_multiple_equivalent_keys() {
-    return IsMulti || (IsTransparent<key_compare>::value &&
-                       !std::is_same<LookupKey, Key>::value &&
-                       !kIsKeyCompareStringAdapted);
+    return IsMulti ||
+           (IsTransparent<key_compare>::value &&
+            !std::is_same_v<LookupKey, Key> && !kIsKeyCompareStringAdapted);
   }
 
   enum {
@@ -519,15 +519,14 @@
   //   - Otherwise, choose binary.
   // TODO(ezb): Might make sense to add condition(s) based on node-size.
   using use_linear_search = std::integral_constant<
-      bool, has_linear_node_search_preference<original_key_compare>::value
-                ? prefers_linear_node_search<original_key_compare>::value
-            : has_linear_node_search_preference<key_type>::value
-                ? prefers_linear_node_search<key_type>::value
-                : std::is_arithmetic<key_type>::value &&
-                      (std::is_same<std::less<key_type>,
-                                    original_key_compare>::value ||
-                       std::is_same<std::greater<key_type>,
-                                    original_key_compare>::value)>;
+      bool,
+      has_linear_node_search_preference<original_key_compare>::value
+          ? prefers_linear_node_search<original_key_compare>::value
+      : has_linear_node_search_preference<key_type>::value
+          ? prefers_linear_node_search<key_type>::value
+          : std::is_arithmetic_v<key_type> &&
+                (std::is_same_v<std::less<key_type>, original_key_compare> ||
+                 std::is_same_v<std::greater<key_type>, original_key_compare>)>;
 
   // This class is organized by absl::container_internal::Layout as if it had
   // the following structure:
@@ -898,8 +897,7 @@
   // the whole tree so that this is constant time.
   template <typename Compare>
   bool is_ordered_correctly(field_type i, const Compare &comp) const {
-    if (std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase,
-                        Compare>::value ||
+    if (std::is_base_of_v<BtreeTestOnlyCheckedCompareOptOutBase, Compare> ||
         params_type::kIsKeyCompareStringAdapted) {
       return true;
     }
@@ -1147,11 +1145,11 @@
   // NOTE: this SFINAE allows for implicit conversions from iterator to
   // const_iterator, but it specifically avoids hiding the copy constructor so
   // that the trivial one will be used when possible.
-  template <typename N, typename R, typename P,
-            std::enable_if_t<
-                std::is_same<btree_iterator<N, R, P>, iterator>::value &&
-                    std::is_same<btree_iterator, const_iterator>::value,
-                int> = 0>
+  template <
+      typename N, typename R, typename P,
+      std::enable_if_t<std::is_same_v<btree_iterator<N, R, P>, iterator> &&
+                           std::is_same_v<btree_iterator, const_iterator>,
+                       int> = 0>
   btree_iterator(const btree_iterator<N, R, P> other)  // NOLINT
       : btree_iterator_generation_info(other),
         node_(other.node_),
@@ -1259,12 +1257,12 @@
   // non-const methods and the container owns the nodes.
   template <typename N, typename R, typename P,
             std::enable_if_t<
-                std::is_same<btree_iterator<N, R, P>, const_iterator>::value &&
-                    std::is_same<btree_iterator, iterator>::value,
+                std::is_same_v<btree_iterator<N, R, P>, const_iterator> &&
+                    std::is_same_v<btree_iterator, iterator>,
                 int> = 0>
   explicit btree_iterator(const btree_iterator<N, R, P> other)
       : btree_iterator_generation_info(other.generation()),
-        node_(const_cast<node_type *>(other.node_)),
+        node_(const_cast<node_type*>(other.node_)),
         position_(other.position_) {}
 
   bool Equals(const const_iterator other) const {
@@ -2288,9 +2286,9 @@
 template <typename P>
 template <typename Btree>
 void btree<P>::copy_or_move_values_in_order(Btree &other) {
-  static_assert(std::is_same<btree, Btree>::value ||
-                    std::is_same<const btree, Btree>::value,
-                "Btree type must be same or const.");
+  static_assert(
+      std::is_same_v<btree, Btree> || std::is_same_v<const btree, Btree>,
+      "Btree type must be same or const.");
   assert(empty());
 
   // We can avoid key comparisons because we know the order of the
@@ -2308,11 +2306,11 @@
 
 template <typename P>
 constexpr bool btree<P>::static_assert_validation() {
-  static_assert(std::is_nothrow_copy_constructible<key_compare>::value,
+  static_assert(std::is_nothrow_copy_constructible_v<key_compare>,
                 "Key comparison must be nothrow copy constructible");
-  static_assert(std::is_nothrow_copy_constructible<allocator_type>::value,
+  static_assert(std::is_nothrow_copy_constructible_v<allocator_type>,
                 "Allocator must be nothrow copy constructible");
-  static_assert(std::is_trivially_copyable<iterator>::value,
+  static_assert(std::is_trivially_copyable_v<iterator>,
                 "iterator not trivially copyable.");
 
   // Note: We assert that kTargetValues, which is computed from
diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h
index 5261b6f..2bd98c6 100644
--- a/absl/container/internal/btree_container.h
+++ b/absl/container/internal/btree_container.h
@@ -88,14 +88,14 @@
   btree_container(const btree_container &other, const allocator_type &alloc)
       : tree_(other.tree_, alloc) {}
 
-  btree_container(btree_container &&other) noexcept(
-      std::is_nothrow_move_constructible<Tree>::value) = default;
+  btree_container(btree_container&& other) noexcept(
+      std::is_nothrow_move_constructible_v<Tree>) = default;
   btree_container(btree_container &&other, const allocator_type &alloc)
       : tree_(std::move(other.tree_), alloc) {}
 
   btree_container &operator=(const btree_container &other) = default;
-  btree_container &operator=(btree_container &&other) noexcept(
-      std::is_nothrow_move_assignable<Tree>::value) = default;
+  btree_container& operator=(btree_container&& other) noexcept(
+      std::is_nothrow_move_assignable_v<Tree>) = default;
 
   // Iterator routines.
   iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { return tree_.begin(); }
@@ -411,16 +411,15 @@
   // Merge routines.
   // Moves elements from `src` into `this`. If the element already exists in
   // `this`, it is left unmodified in `src`.
-  template <
-      typename T,
-      typename std::enable_if_t<
-          std::conjunction<
-              std::is_same<value_type, typename T::value_type>,
-              std::is_same<allocator_type, typename T::allocator_type>,
-              std::is_same<typename params_type::is_map_container,
-                           typename T::params_type::is_map_container>>::value,
-          int> = 0>
-  void merge(btree_container<T> &src) {  // NOLINT
+  template <typename T,
+            typename std::enable_if_t<
+                std::conjunction_v<
+                    std::is_same<value_type, typename T::value_type>,
+                    std::is_same<allocator_type, typename T::allocator_type>,
+                    std::is_same<typename params_type::is_map_container,
+                                 typename T::params_type::is_map_container>>,
+                int> = 0>
+  void merge(btree_container<T>& src) {  // NOLINT
     for (auto src_it = src.begin(); src_it != src.end();) {
       if (insert(std::move(params_type::element(src_it.slot()))).second) {
         src_it = src.erase(src_it);
@@ -430,16 +429,15 @@
     }
   }
 
-  template <
-      typename T,
-      typename std::enable_if_t<
-          std::conjunction<
-              std::is_same<value_type, typename T::value_type>,
-              std::is_same<allocator_type, typename T::allocator_type>,
-              std::is_same<typename params_type::is_map_container,
-                           typename T::params_type::is_map_container>>::value,
-          int> = 0>
-  void merge(btree_container<T> &&src) {
+  template <typename T,
+            typename std::enable_if_t<
+                std::conjunction_v<
+                    std::is_same<value_type, typename T::value_type>,
+                    std::is_same<allocator_type, typename T::allocator_type>,
+                    std::is_same<typename params_type::is_map_container,
+                                 typename T::params_type::is_map_container>>,
+                int> = 0>
+  void merge(btree_container<T>&& src) {
     merge(src);
   }
 };
@@ -604,8 +602,7 @@
           decltype(EnableIf<LifetimeBoundK<                                    \
                        K, KValue, IfRRef<int KQual>::AddPtr<K>>>()) = 0,       \
           class... Args),                                                      \
-      std::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> =  \
-          0>                                                                   \
+      std::enable_if_t<!std::is_convertible_v<K, const_iterator>, int> = 0>    \
   decltype(auto) Func(                                                         \
       __VA_ARGS__ key_arg<K> KQual k ABSL_INTERNAL_IF_##KValue(                \
           ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)),                          \
@@ -823,32 +820,30 @@
 
   // Merge routines.
   // Moves all elements from `src` into `this`.
-  template <
-      typename T,
-      typename std::enable_if_t<
-          std::conjunction<
-              std::is_same<value_type, typename T::value_type>,
-              std::is_same<allocator_type, typename T::allocator_type>,
-              std::is_same<typename params_type::is_map_container,
-                           typename T::params_type::is_map_container>>::value,
-          int> = 0>
-  void merge(btree_container<T> &src) {  // NOLINT
+  template <typename T,
+            typename std::enable_if_t<
+                std::conjunction_v<
+                    std::is_same<value_type, typename T::value_type>,
+                    std::is_same<allocator_type, typename T::allocator_type>,
+                    std::is_same<typename params_type::is_map_container,
+                                 typename T::params_type::is_map_container>>,
+                int> = 0>
+  void merge(btree_container<T>& src) {  // NOLINT
     for (auto src_it = src.begin(), end = src.end(); src_it != end; ++src_it) {
       insert(std::move(params_type::element(src_it.slot())));
     }
     src.clear();
   }
 
-  template <
-      typename T,
-      typename std::enable_if_t<
-          std::conjunction<
-              std::is_same<value_type, typename T::value_type>,
-              std::is_same<allocator_type, typename T::allocator_type>,
-              std::is_same<typename params_type::is_map_container,
-                           typename T::params_type::is_map_container>>::value,
-          int> = 0>
-  void merge(btree_container<T> &&src) {
+  template <typename T,
+            typename std::enable_if_t<
+                std::conjunction_v<
+                    std::is_same<value_type, typename T::value_type>,
+                    std::is_same<allocator_type, typename T::allocator_type>,
+                    std::is_same<typename params_type::is_map_container,
+                                 typename T::params_type::is_map_container>>,
+                int> = 0>
+  void merge(btree_container<T>&& src) {
     merge(src);
   }
 };
diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h
index 5608b76..0eb0542 100644
--- a/absl/container/internal/common_policy_traits.h
+++ b/absl/container/internal/common_policy_traits.h
@@ -34,7 +34,7 @@
 template <class Policy>
 struct policy_trait_element_is_owner<
     Policy,
-    std::enable_if_t<!std::is_void<typename Policy::element_is_owner>::value>>
+    std::enable_if_t<!std::is_void_v<typename Policy::element_is_owner>>>
     : Policy::element_is_owner {};
 
 // Defines how slots are initialized/destroyed/moved.
@@ -91,16 +91,16 @@
   }
 
   static constexpr bool transfer_uses_memcpy() {
-    return std::is_same<decltype(transfer_impl<std::allocator<char>>(
-                            nullptr, nullptr, nullptr, Rank2{})),
-                        std::true_type>::value;
+    return std::is_same_v<decltype(transfer_impl<std::allocator<char>>(
+                              nullptr, nullptr, nullptr, Rank2{})),
+                          std::true_type>;
   }
 
   // Returns true if destroy is trivial and can be omitted.
   template <class Alloc>
   static constexpr bool destroy_is_trivial() {
-    return std::is_same<decltype(destroy<Alloc>(nullptr, nullptr)),
-                        std::true_type>::value;
+    return std::is_same_v<decltype(destroy<Alloc>(nullptr, nullptr)),
+                          std::true_type>;
   }
 
  private:
diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h
index 789e668..2e1c7ab 100644
--- a/absl/container/internal/compressed_tuple.h
+++ b/absl/container/internal/compressed_tuple.h
@@ -67,8 +67,7 @@
 
 template <typename T>
 constexpr bool ShouldUseBase() {
-  return std::is_class<T>::value && std::is_empty<T>::value &&
-         !std::is_final<T>::value;
+  return std::is_class_v<T> && std::is_empty_v<T> && !std::is_final_v<T>;
 }
 
 // Tag type used to disambiguate Storage types for different CompresseedTuples.
@@ -156,7 +155,7 @@
 
 template <typename T, typename V>
 using TupleElementMoveConstructible =
-    std::conditional_t<std::is_reference<T>::value, std::is_convertible<V, T>,
+    std::conditional_t<std::is_reference_v<T>, std::is_convertible<V, T>,
                        std::is_constructible<T, V&&>>;
 
 template <bool SizeMatches, class T, class... Vs>
@@ -165,8 +164,8 @@
 template <class... Ts, class... Vs>
 struct TupleMoveConstructible<true, CompressedTuple<Ts...>, Vs...>
     : std::integral_constant<
-          bool, std::conjunction<
-                    TupleElementMoveConstructible<Ts, Vs&&>...>::value> {};
+          bool,
+          std::conjunction_v<TupleElementMoveConstructible<Ts, Vs&&>...>> {};
 
 template <typename T>
 struct compressed_tuple_size;
@@ -227,12 +226,12 @@
 
   template <typename First, typename... Vs,
             std::enable_if_t<
-                std::conjunction<
+                std::conjunction_v<
                     // Ensure we are not hiding default copy/move constructors.
                     std::negation<std::is_same<void(CompressedTuple),
                                                void(std::decay_t<First>)>>,
                     internal_compressed_tuple::TupleItemsMoveConstructible<
-                        CompressedTuple<Ts...>, First, Vs...>>::value,
+                        CompressedTuple<Ts...>, First, Vs...>>,
                 bool> = true>
   explicit constexpr CompressedTuple(First&& first, Vs&&... base)
       : CompressedTuple::CompressedTupleImpl(std::in_place,
diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc
index 96b3917..2331fc4 100644
--- a/absl/container/internal/compressed_tuple_test.cc
+++ b/absl/container/internal/compressed_tuple_test.cc
@@ -302,14 +302,14 @@
   EXPECT_EQ(4 * sizeof(char),
             sizeof(CompressedTuple<CompressedTuple<char, char>,
                                    CompressedTuple<char, char>>));
-  EXPECT_TRUE((std::is_empty<CompressedTuple<Empty<0>, Empty<1>>>::value));
+  EXPECT_TRUE((std::is_empty_v<CompressedTuple<Empty<0>, Empty<1>>>));
 
   // Make sure everything still works when things are nested.
   struct CT_Empty : CompressedTuple<Empty<0>> {};
   CompressedTuple<Empty<0>, CT_Empty> nested_empty;
   auto contained = nested_empty.get<0>();
   auto nested = nested_empty.get<1>().get<0>();
-  EXPECT_TRUE((std::is_same<decltype(contained), decltype(nested)>::value));
+  EXPECT_TRUE((std::is_same_v<decltype(contained), decltype(nested)>));
 }
 
 TEST(CompressedTupleTest, Reference) {
@@ -332,7 +332,7 @@
 TEST(CompressedTupleTest, NoElements) {
   CompressedTuple<> x;
   static_cast<void>(x);  // Silence -Wunused-variable.
-  EXPECT_TRUE(std::is_empty<CompressedTuple<>>::value);
+  EXPECT_TRUE(std::is_empty_v<CompressedTuple<>>);
 }
 
 TEST(CompressedTupleTest, MoveOnlyElements) {
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index bfa9825..a30395b 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -80,10 +80,10 @@
 template <class Allocator, class ValueType>
 constexpr auto IsDestructionTrivial() {
   constexpr bool result =
-      std::is_trivially_destructible<ValueType>::value &&
-      std::is_same<typename std::allocator_traits<
-                       Allocator>::template rebind_alloc<char>,
-                   std::allocator<char>>::value;
+      std::is_trivially_destructible_v<ValueType> &&
+      std::is_same_v<typename std::allocator_traits<
+                         Allocator>::template rebind_alloc<char>,
+                     std::allocator<char>>;
   return std::integral_constant<bool, result>();
 }
 
diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc
index 946d1d3..9a8ba67 100644
--- a/absl/container/internal/container_memory_test.cc
+++ b/absl/container/internal/container_memory_test.cc
@@ -270,9 +270,9 @@
   {
     using slot_policy = map_slot_policy<int, float>;
     EXPECT_TRUE(
-        (std::is_same<decltype(slot_policy::transfer<std::allocator<char>>(
-                          nullptr, nullptr, nullptr)),
-                      std::true_type>::value));
+        (std::is_same_v<decltype(slot_policy::transfer<std::allocator<char>>(
+                            nullptr, nullptr, nullptr)),
+                        std::true_type>));
   }
   {
     struct NonRelocatable {
@@ -285,9 +285,9 @@
     EXPECT_FALSE(absl::is_trivially_relocatable<NonRelocatable>::value);
     using slot_policy = map_slot_policy<int, NonRelocatable>;
     EXPECT_TRUE(
-        (std::is_same<decltype(slot_policy::transfer<std::allocator<char>>(
-                          nullptr, nullptr, nullptr)),
-                      std::false_type>::value));
+        (std::is_same_v<decltype(slot_policy::transfer<std::allocator<char>>(
+                            nullptr, nullptr, nullptr)),
+                        std::false_type>));
   }
 }
 
@@ -295,17 +295,17 @@
   {
     using slot_policy = map_slot_policy<int, float>;
     EXPECT_TRUE(
-        (std::is_same<decltype(slot_policy::destroy<std::allocator<char>>(
-                          nullptr, nullptr)),
-                      std::true_type>::value));
+        (std::is_same_v<decltype(slot_policy::destroy<std::allocator<char>>(
+                            nullptr, nullptr)),
+                        std::true_type>));
   }
   {
-    EXPECT_FALSE(std::is_trivially_destructible<std::unique_ptr<int>>::value);
+    EXPECT_FALSE(std::is_trivially_destructible_v<std::unique_ptr<int>>);
     using slot_policy = map_slot_policy<int, std::unique_ptr<int>>;
     EXPECT_TRUE(
-        (std::is_same<decltype(slot_policy::destroy<std::allocator<char>>(
-                          nullptr, nullptr)),
-                      std::false_type>::value));
+        (std::is_same_v<decltype(slot_policy::destroy<std::allocator<char>>(
+                            nullptr, nullptr)),
+                        std::false_type>));
   }
 }
 
diff --git a/absl/container/internal/hash_generator_testing.h b/absl/container/internal/hash_generator_testing.h
index 9b50152..79bff7c 100644
--- a/absl/container/internal/hash_generator_testing.h
+++ b/absl/container/internal/hash_generator_testing.h
@@ -69,7 +69,7 @@
 struct Generator;
 
 template <class T>
-struct Generator<T, std::enable_if_t<std::is_integral<T>::value>> {
+struct Generator<T, std::enable_if_t<std::is_integral_v<T>>> {
   T operator()() const { return dist(gen); }
   mutable absl::InsecureBitGen gen;
   mutable std::uniform_int_distribution<T> dist;
diff --git a/absl/container/internal/hash_policy_traits.h b/absl/container/internal/hash_policy_traits.h
index ab92060..e469d71 100644
--- a/absl/container/internal/hash_policy_traits.h
+++ b/absl/container/internal/hash_policy_traits.h
@@ -38,7 +38,7 @@
  private:
   struct ReturnKey {
     template <class Key,
-              std::enable_if_t<std::is_lvalue_reference<Key>::value, int> = 0>
+              std::enable_if_t<std::is_lvalue_reference_v<Key>, int> = 0>
     static key_type& Impl(Key&& k, int) {
       return *std::launder(
           const_cast<key_type*>(std::addressof(std::forward<Key>(k))));
diff --git a/absl/container/internal/hashtable_control_bytes.h b/absl/container/internal/hashtable_control_bytes.h
index 70016e1..f2b1efe 100644
--- a/absl/container/internal/hashtable_control_bytes.h
+++ b/absl/container/internal/hashtable_control_bytes.h
@@ -125,7 +125,7 @@
           bool NullifyBitsOnIteration = false>
 class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> {
   using Base = NonIterableBitMask<T, SignificantBits, Shift>;
-  static_assert(std::is_unsigned<T>::value, "");
+  static_assert(std::is_unsigned_v<T>, "");
   static_assert(Shift == 0 || Shift == 3, "");
   static_assert(!NullifyBitsOnIteration || Shift == 3, "");
 
@@ -263,7 +263,7 @@
 // when using -funsigned-char under GCC.
 inline __m128i _mm_cmpgt_epi8_fixed(__m128i a, __m128i b) {
 #if defined(__GNUC__) && !defined(__clang__)
-  if (std::is_unsigned<char>::value) {
+  if (std::is_unsigned_v<char>) {
     const __m128i mask = _mm_set1_epi8(0x80);
     const __m128i diff = _mm_subs_epi8(b, a);
     return _mm_cmpeq_epi8(_mm_and_si128(diff, mask), mask);
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h
index 6bda9d5..4e9b87e 100644
--- a/absl/container/internal/inlined_vector.h
+++ b/absl/container/internal/inlined_vector.h
@@ -78,10 +78,9 @@
 template <typename A>
 using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>;
 
-template <typename A,
-          bool IsTriviallyDestructible =
-              std::is_trivially_destructible<ValueType<A>>::value &&
-              std::is_same<A, std::allocator<ValueType<A>>>::value>
+template <typename A, bool IsTriviallyDestructible =
+                          std::is_trivially_destructible_v<ValueType<A>> &&
+                          std::is_same_v<A, std::allocator<ValueType<A>>>>
 struct DestroyAdapter;
 
 template <typename A>
@@ -295,9 +294,9 @@
       // it's safe for us to simply adopt the contents of the storage for
       // `other` and remove its own reference to them. It's as if we had
       // individually move-assigned each value and then destroyed the original.
-      std::conjunction<std::is_trivially_move_assignable<ValueType<A>>,
-                        std::is_trivially_destructible<ValueType<A>>,
-                        std::is_same<A, std::allocator<ValueType<A>>>>::value,
+      std::conjunction_v<std::is_trivially_move_assignable<ValueType<A>>,
+                         std::is_trivially_destructible<ValueType<A>>,
+                         std::is_same<A, std::allocator<ValueType<A>>>>,
       MemcpyPolicy,
       // Otherwise we use move assignment if possible. If not, we simulate
       // move assignment using move construction.
@@ -306,7 +305,7 @@
       // which are themselves not move-assignable when their contained type is
       // not.
       std::conditional_t<IsMoveAssignOk<A>::value, ElementwiseAssignPolicy,
-                          ElementwiseConstructPolicy>>;
+                         ElementwiseConstructPolicy>>;
 
   // The policy to be used specifically when swapping inlined elements.
   using SwapInlinedElementsPolicy = std::conditional_t<
@@ -316,11 +315,11 @@
       // relocated the first vector's elements into temporary storage,
       // relocated the second's elements into the (now-empty) first's,
       // and then relocated from temporary storage into the second.
-      std::conjunction<absl::is_trivially_relocatable<ValueType<A>>,
-                        std::is_same<A, std::allocator<ValueType<A>>>>::value,
+      std::conjunction_v<absl::is_trivially_relocatable<ValueType<A>>,
+                         std::is_same<A, std::allocator<ValueType<A>>>>,
       MemcpyPolicy,
       std::conditional_t<IsSwapOk<A>::value, ElementwiseSwapPolicy,
-                          ElementwiseConstructPolicy>>;
+                         ElementwiseConstructPolicy>>;
 
   static SizeType<A> NextCapacity(SizeType<A> current_capacity) {
     return current_capacity * 2;
@@ -349,8 +348,8 @@
     // Fast path: if no destructors need to be run and we know the allocator
     // doesn't do anything fancy, then all we need to do is deallocate (and
     // maybe not even that).
-    if (std::is_trivially_destructible<ValueType<A>>::value &&
-        std::is_same<A, std::allocator<ValueType<A>>>::value) {
+    if (std::is_trivially_destructible_v<ValueType<A>> &&
+        std::is_same_v<A, std::allocator<ValueType<A>>>) {
       DeallocateIfAllocated();
       return;
     }
@@ -502,16 +501,16 @@
     {
       using V = ValueType<A>;
       ABSL_ASSERT(other_storage.GetIsAllocated() ||
-                  (std::is_same<A, std::allocator<V>>::value &&
+                  (std::is_same_v<A, std::allocator<V>> &&
                    (
                        // First case above
                        absl::is_trivially_relocatable<V>::value ||
                        // Second case above
-                       (std::is_trivially_move_assignable<V>::value &&
-                        std::is_trivially_destructible<V>::value) ||
+                       (std::is_trivially_move_assignable_v<V> &&
+                        std::is_trivially_destructible_v<V>) ||
                        // Third case above
-                       (std::is_trivially_copy_constructible<V>::value ||
-                        std::is_trivially_copy_assignable<V>::value))));
+                       (std::is_trivially_copy_constructible_v<V> ||
+                        std::is_trivially_copy_assignable_v<V>))));
     }
 
     GetSizeAndIsAllocated() = other_storage.GetSizeAndIsAllocated();
@@ -596,8 +595,8 @@
   // Fast path: if the value type is trivially copy constructible and we know
   // the allocator doesn't do anything fancy, then we know it is legal for us to
   // simply memcpy the other vector's elements.
-  if (std::is_trivially_copy_constructible<ValueType<A>>::value &&
-      std::is_same<A, std::allocator<ValueType<A>>>::value) {
+  if (std::is_trivially_copy_constructible_v<ValueType<A>> &&
+      std::is_same_v<A, std::allocator<ValueType<A>>>) {
     std::memcpy(reinterpret_cast<char*>(dst),
                 reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>));
   } else {
@@ -878,8 +877,8 @@
   // simply destroy the elements in the "erasure window" (which cannot throw)
   // and then memcpy downward to close the window.
   if (absl::is_trivially_relocatable<ValueType<A>>::value &&
-      std::is_nothrow_destructible<ValueType<A>>::value &&
-      std::is_same<A, std::allocator<ValueType<A>>>::value) {
+      std::is_nothrow_destructible_v<ValueType<A>> &&
+      std::is_same_v<A, std::allocator<ValueType<A>>>) {
     DestroyAdapter<A>::DestroyElements(
         GetAllocator(), storage_view.data + erase_index, erase_size);
     std::memmove(
diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h
index 3a599a8..fac7d81 100644
--- a/absl/container/internal/layout.h
+++ b/absl/container/internal/layout.h
@@ -264,7 +264,7 @@
 using Contains = std::disjunction<std::is_same<T, Ts>...>;
 
 template <class From, class To>
-using CopyConst = std::conditional_t<std::is_const<From>::value, const To, To>;
+using CopyConst = std::conditional_t<std::is_const_v<From>, const To, To>;
 
 // Note: We're not qualifying this with absl:: because it doesn't compile under
 // MSVC.
@@ -316,11 +316,12 @@
 
 // Can `T` be a template argument of `Layout`?
 template <class T>
-using IsLegalElementType = std::integral_constant<
-    bool, !std::is_reference<T>::value && !std::is_volatile<T>::value &&
-              !std::is_reference<typename Type<T>::type>::value &&
-              !std::is_volatile<typename Type<T>::type>::value &&
-              adl_barrier::IsPow2(AlignOf<T>::value)>;
+using IsLegalElementType =
+    std::integral_constant<bool,
+                           !std::is_reference_v<T> && !std::is_volatile_v<T> &&
+                               !std::is_reference_v<typename Type<T>::type> &&
+                               !std::is_volatile_v<typename Type<T>::type> &&
+                               adl_barrier::IsPow2(AlignOf<T>::value)>;
 
 template <class Elements, class StaticSizeSeq, class RuntimeSizeSeq,
           class SizeSeq, class OffsetSeq>
@@ -351,7 +352,7 @@
                  std::index_sequence<OffsetSeq...>> {
  private:
   static_assert(sizeof...(Elements) > 0, "At least one field is required");
-  static_assert(std::conjunction<IsLegalElementType<Elements>...>::value,
+  static_assert(std::conjunction_v<IsLegalElementType<Elements>...>,
                 "Invalid element type (see IsLegalElementType)");
   static_assert(sizeof...(StaticSizeSeq) <= sizeof...(Elements),
                 "Too many static sizes specified");
diff --git a/absl/container/internal/node_slot_policy.h b/absl/container/internal/node_slot_policy.h
index 1d65828..7213dda 100644
--- a/absl/container/internal/node_slot_policy.h
+++ b/absl/container/internal/node_slot_policy.h
@@ -47,7 +47,7 @@
 
 template <class Reference, class Policy>
 struct node_slot_policy {
-  static_assert(std::is_lvalue_reference<Reference>::value, "");
+  static_assert(std::is_lvalue_reference_v<Reference>, "");
 
   using slot_type = std::remove_cv_t<std::remove_reference_t<Reference>>*;
 
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h
index 9c2737c..e039753 100644
--- a/absl/container/internal/raw_hash_map.h
+++ b/absl/container/internal/raw_hash_map.h
@@ -95,11 +95,11 @@
   using key_type = typename Policy::key_type;
   using mapped_type = typename Policy::mapped_type;
 
-  static_assert(!std::is_reference<key_type>::value, "");
+  static_assert(!std::is_reference_v<key_type>, "");
 
   // TODO(b/187807849): Evaluate whether to support reference mapped_type and
   // remove this assertion if/when it is supported.
-  static_assert(!std::is_reference<mapped_type>::value, "");
+  static_assert(!std::is_reference_v<mapped_type>, "");
 
   using iterator = typename raw_hash_map::raw_hash_set::iterator;
   using const_iterator = typename raw_hash_map::raw_hash_set::const_iterator;
@@ -218,7 +218,7 @@
   template <
       class K = key_type, int = EnableIf<LifetimeBoundK<K, false, K*>>(),
       class... Args,
-      std::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> = 0>
+      std::enable_if_t<!std::is_convertible_v<K, const_iterator>, int> = 0>
   std::pair<iterator, bool> try_emplace(key_arg<K>&& k, Args&&... args)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace_impl(std::forward<key_arg<K>>(k),
@@ -228,7 +228,7 @@
   template <
       class K = key_type, class... Args,
       EnableIf<LifetimeBoundK<K, true, K*>> = 0,
-      std::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> = 0>
+      std::enable_if_t<!std::is_convertible_v<K, const_iterator>, int> = 0>
   std::pair<iterator, bool> try_emplace(
       key_arg<K>&& k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this),
       Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
@@ -239,14 +239,14 @@
   template <
       class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>(),
       class... Args,
-      std::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> = 0>
+      std::enable_if_t<!std::is_convertible_v<K, const_iterator>, int> = 0>
   std::pair<iterator, bool> try_emplace(const key_arg<K>& k, Args&&... args)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace_impl(k, std::forward<Args>(args)...);
   }
   template <
       class K = key_type, class... Args, EnableIf<LifetimeBoundK<K, true>> = 0,
-      std::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> = 0>
+      std::enable_if_t<!std::is_convertible_v<K, const_iterator>, int> = 0>
   std::pair<iterator, bool> try_emplace(
       const key_arg<K>& k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this),
       Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 1736dcd..befc8a5 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -2271,7 +2271,7 @@
   using SlotAllocTraits = typename std::allocator_traits<
       allocator_type>::template rebind_traits<slot_type>;
 
-  static_assert(std::is_lvalue_reference<reference>::value,
+  static_assert(std::is_lvalue_reference_v<reference>,
                 "Policy::element() must return a reference");
 
   // An enabler for insert(T&&): T must be convertible to init_type or be the
@@ -2286,8 +2286,7 @@
   // RequiresNotInit is a workaround for gcc prior to 7.1.
   // See https://godbolt.org/g/Y4xsUh.
   template <class T>
-  using RequiresNotInit =
-      std::enable_if_t<!std::is_same<T, init_type>::value, int>;
+  using RequiresNotInit = std::enable_if_t<!std::is_same_v<T, init_type>, int>;
 
   template <class... Ts>
   using IsDecomposable = IsDecomposable<void, PolicyTraits, Hash, Eq, Ts...>;
@@ -2304,9 +2303,9 @@
       type_traits_internal::IsLifetimeBoundAssignment<init_type, U>>;
 
  public:
-  static_assert(std::is_same<pointer, value_type*>::value,
+  static_assert(std::is_same_v<pointer, value_type*>,
                 "Allocators with custom pointer types are not supported");
-  static_assert(std::is_same<const_pointer, const value_type*>::value,
+  static_assert(std::is_same_v<const_pointer, const value_type*>,
                 "Allocators with custom pointer types are not supported");
 
   class iterator : private HashSetIteratorGenerationInfo {
@@ -2480,9 +2479,9 @@
   // Note: can't use `= default` due to non-default noexcept (causes
   // problems for some compilers). NOLINTNEXTLINE
   raw_hash_set() noexcept(
-      std::is_nothrow_default_constructible<hasher>::value &&
-      std::is_nothrow_default_constructible<key_equal>::value &&
-      std::is_nothrow_default_constructible<allocator_type>::value) {}
+      std::is_nothrow_default_constructible_v<hasher> &&
+      std::is_nothrow_default_constructible_v<key_equal> &&
+      std::is_nothrow_default_constructible_v<allocator_type>) {}
 
   explicit raw_hash_set(
       size_t bucket_count, const hasher& hash = hasher(),
@@ -2633,9 +2632,9 @@
   }
 
   ABSL_ATTRIBUTE_NOINLINE raw_hash_set(raw_hash_set&& that) noexcept(
-      std::is_nothrow_copy_constructible<hasher>::value &&
-      std::is_nothrow_copy_constructible<key_equal>::value &&
-      std::is_nothrow_copy_constructible<allocator_type>::value)
+      std::is_nothrow_copy_constructible_v<hasher> &&
+      std::is_nothrow_copy_constructible_v<key_equal> &&
+      std::is_nothrow_copy_constructible_v<allocator_type>)
       :  // Hash, equality and allocator are copied instead of moved because
          // `that` must be left valid. If Hash is std::function<Key>, moving it
          // would create a nullptr functor that cannot be called.
@@ -2681,8 +2680,8 @@
 
   raw_hash_set& operator=(raw_hash_set&& that) noexcept(
       AllocTraits::is_always_equal::value &&
-      std::is_nothrow_move_assignable<hasher>::value &&
-      std::is_nothrow_move_assignable<key_equal>::value) {
+      std::is_nothrow_move_assignable_v<hasher> &&
+      std::is_nothrow_move_assignable_v<key_equal>) {
     // TODO(sbenza): We should only use the operations from the noexcept clause
     // to make sure we actually adhere to that contract.
     // NOLINTNEXTLINE: not returning *this for performance.
@@ -3124,7 +3123,7 @@
   }
 
   template <class K = key_type,
-            std::enable_if_t<!std::is_same<K, iterator>::value, int> = 0>
+            std::enable_if_t<!std::is_same_v<K, iterator>, int> = 0>
   node_type extract(const key_arg<K>& key) {
     auto it = find(key);
     return it == end() ? node_type() : extract(const_iterator{it});
@@ -3132,8 +3131,8 @@
 
   void swap(raw_hash_set& that) noexcept(
       AllocTraits::is_always_equal::value &&
-      std::is_nothrow_swappable<hasher>::value &&
-      std::is_nothrow_swappable<key_equal>::value) {
+      std::is_nothrow_swappable_v<hasher> &&
+      std::is_nothrow_swappable_v<key_equal>) {
     AssertNotDebugCapacity();
     that.AssertNotDebugCapacity();
     using std::swap;
@@ -3268,8 +3267,8 @@
       // mapped_types could be unequal in a map or even in a set, key_equal
       // could ignore some fields that aren't ignored by operator==.
       static constexpr bool kKeyEqIsValueEq =
-          std::is_same<key_type, value_type>::value &&
-          std::is_same<key_equal, hash_default_eq<key_type>>::value;
+          std::is_same_v<key_type, value_type> &&
+          std::is_same_v<key_equal, hash_default_eq<key_type>>;
       if (!kKeyEqIsValueEq && !(*it == elem)) return false;
     }
     return true;
@@ -3730,13 +3729,13 @@
     return;
 #endif
     // If the hash/eq functors are known to be consistent, then skip validation.
-    if (std::is_same<hasher, absl::container_internal::StringHash>::value &&
-        std::is_same<key_equal, absl::container_internal::StringEq>::value) {
+    if (std::is_same_v<hasher, absl::container_internal::StringHash> &&
+        std::is_same_v<key_equal, absl::container_internal::StringEq>) {
       return;
     }
-    if (std::is_scalar<key_type>::value &&
-        std::is_same<hasher, absl::Hash<key_type>>::value &&
-        std::is_same<key_equal, std::equal_to<key_type>>::value) {
+    if (std::is_scalar_v<key_type> &&
+        std::is_same_v<hasher, absl::Hash<key_type>> &&
+        std::is_same_v<key_equal, std::equal_to<key_type>>) {
       return;
     }
     if (empty()) return;
diff --git a/absl/container/internal/raw_hash_set_benchmark.cc b/absl/container/internal/raw_hash_set_benchmark.cc
index d1e82c2..5cbaf5c 100644
--- a/absl/container/internal/raw_hash_set_benchmark.cc
+++ b/absl/container/internal/raw_hash_set_benchmark.cc
@@ -78,7 +78,7 @@
 class StringPolicy {
   template <class F, class K, class V,
             class = std::enable_if_t<
-                std::is_convertible<const K&, absl::string_view>::value>>
+                std::is_convertible_v<const K&, absl::string_view>>>
   decltype(std::declval<F>()(
       std::declval<const absl::string_view&>(), std::piecewise_construct,
       std::declval<std::tuple<K>>(),
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index e9b37f7..c7241c4 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -982,7 +982,7 @@
 class StringPolicy {
   template <class F, class K, class V,
             class = std::enable_if_t<
-                std::is_convertible<const K&, absl::string_view>::value>>
+                std::is_convertible_v<const K&, absl::string_view>>>
   decltype(std::declval<F>()(
       std::declval<const absl::string_view&>(), std::piecewise_construct,
       std::declval<std::tuple<K>>(),
@@ -1215,8 +1215,8 @@
                ChangingSizeAndTrackingTypeAlloc<int64_t>>;
 
 TEST(Table, EmptyFunctorOptimization) {
-  static_assert(std::is_empty<std::equal_to<absl::string_view>>::value, "");
-  static_assert(std::is_empty<std::allocator<int>>::value, "");
+  static_assert(std::is_empty_v<std::equal_to<absl::string_view>>, "");
+  static_assert(std::is_empty_v<std::allocator<int>>, "");
 
   struct MockTableByValue {
     size_t capacity;
@@ -3028,22 +3028,21 @@
 
 TEST(Table, NoThrowMoveConstruct) {
   ASSERT_TRUE(
-      std::is_nothrow_copy_constructible<absl::Hash<absl::string_view>>::value);
-  ASSERT_TRUE(std::is_nothrow_copy_constructible<
-              std::equal_to<absl::string_view>>::value);
-  ASSERT_TRUE(std::is_nothrow_copy_constructible<std::allocator<int>>::value);
-  EXPECT_TRUE(std::is_nothrow_move_constructible<StringTable>::value);
+      std::is_nothrow_copy_constructible_v<absl::Hash<absl::string_view>>);
+  ASSERT_TRUE(
+      std::is_nothrow_copy_constructible_v<std::equal_to<absl::string_view>>);
+  ASSERT_TRUE(std::is_nothrow_copy_constructible_v<std::allocator<int>>);
+  EXPECT_TRUE(std::is_nothrow_move_constructible_v<StringTable>);
 }
 
 TEST(Table, NoThrowMoveAssign) {
+  ASSERT_TRUE(std::is_nothrow_move_assignable_v<absl::Hash<absl::string_view>>);
   ASSERT_TRUE(
-      std::is_nothrow_move_assignable<absl::Hash<absl::string_view>>::value);
-  ASSERT_TRUE(
-      std::is_nothrow_move_assignable<std::equal_to<absl::string_view>>::value);
-  ASSERT_TRUE(std::is_nothrow_move_assignable<std::allocator<int>>::value);
+      std::is_nothrow_move_assignable_v<std::equal_to<absl::string_view>>);
+  ASSERT_TRUE(std::is_nothrow_move_assignable_v<std::allocator<int>>);
   ASSERT_TRUE(
       std::allocator_traits<std::allocator<int>>::is_always_equal::value);
-  EXPECT_TRUE(std::is_nothrow_move_assignable<StringTable>::value);
+  EXPECT_TRUE(std::is_nothrow_move_assignable_v<StringTable>);
 }
 
 TEST(Table, NoThrowSwappable) {
@@ -3231,8 +3230,8 @@
   EXPECT_FALSE(n);
   EXPECT_TRUE(n.empty());
 
-  EXPECT_TRUE((std::is_same<node_type::allocator_type,
-                            StringTable::allocator_type>::value));
+  EXPECT_TRUE(
+      (std::is_same_v<node_type::allocator_type, StringTable::allocator_type>));
 }
 
 TEST(Nodes, ExtractInsert) {
@@ -3565,7 +3564,7 @@
 TYPED_TEST_SUITE(RawHashSamplerTest, RawHashSamplerTestTypes);
 
 TYPED_TEST(RawHashSamplerTest, Sample) {
-  constexpr bool soo_enabled = std::is_same<SooInt32Table, TypeParam>::value;
+  constexpr bool soo_enabled = std::is_same_v<SooInt32Table, TypeParam>;
   // Enable the feature even if the prod default is off.
   SetSamplingRateTo1Percent();
 
@@ -4239,9 +4238,8 @@
       SCOPED_TRACE("const iteration");
       std::vector<int64_t> actual;
       auto f = [&](auto& x) {
-        static_assert(
-            std::is_const<std::remove_reference_t<decltype(x)>>::value,
-            "no mutable values should be passed to const ForEach");
+        static_assert(std::is_const_v<std::remove_reference_t<decltype(x)>>,
+                      "no mutable values should be passed to const ForEach");
         actual.push_back(static_cast<int64_t>(x));
       };
       const auto& ct = t;
diff --git a/absl/container/internal/unordered_map_modifiers_test.h b/absl/container/internal/unordered_map_modifiers_test.h
index 7c01d11..bb41e07 100644
--- a/absl/container/internal/unordered_map_modifiers_test.h
+++ b/absl/container/internal/unordered_map_modifiers_test.h
@@ -207,7 +207,7 @@
 }
 
 template <class V>
-using IfNotVoid = std::enable_if_t<!std::is_void<V>::value, V>;
+using IfNotVoid = std::enable_if_t<!std::is_void_v<V>, V>;
 
 // In openmap we chose not to return the iterator from erase because that's
 // more expensive. As such we adapt erase to return an iterator here.
diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h
index dc63118..2c9f57f 100644
--- a/absl/container/internal/unordered_set_lookup_test.h
+++ b/absl/container/internal/unordered_set_lookup_test.h
@@ -51,9 +51,9 @@
   m.insert(values.begin(), values.end());
   for (const auto& v : values) {
     typename TypeParam::iterator it = m.find(v);
-    static_assert(std::is_same<const typename TypeParam::value_type&,
-                               decltype(*it)>::value,
-                  "");
+    static_assert(
+        std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>,
+        "");
     static_assert(std::is_same<const typename TypeParam::value_type*,
                                decltype(it.operator->())>::value,
                   "");
diff --git a/absl/container/internal/unordered_set_modifiers_test.h b/absl/container/internal/unordered_set_modifiers_test.h
index a2f2b4b..1d686af 100644
--- a/absl/container/internal/unordered_set_modifiers_test.h
+++ b/absl/container/internal/unordered_set_modifiers_test.h
@@ -130,7 +130,7 @@
 }
 
 template <class V>
-using IfNotVoid = std::enable_if_t<!std::is_void<V>::value, V>;
+using IfNotVoid = std::enable_if_t<!std::is_void_v<V>, V>;
 
 // In openmap we chose not to return the iterator from erase because that's
 // more expensive. As such we adapt erase to return an iterator here.
diff --git a/absl/container/linked_hash_set.h b/absl/container/linked_hash_set.h
index 1b5d578..fe207c8 100644
--- a/absl/container/linked_hash_set.h
+++ b/absl/container/linked_hash_set.h
@@ -450,8 +450,8 @@
     return node_type(std::move(extracted_node_list));
   }
 
-  template <class K = key_type, typename std::enable_if_t<
-                                    !std::is_same<K, iterator>::value, int> = 0>
+  template <class K = key_type,
+            typename std::enable_if_t<!std::is_same_v<K, iterator>, int> = 0>
   node_type extract(const key_arg<K>& key) {
     auto node = set_.extract(key);
     if (node.empty()) return node_type();
diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc
index 6e92bbe..107b329 100644
--- a/absl/container/node_hash_map_test.cc
+++ b/absl/container/node_hash_map_test.cc
@@ -196,7 +196,7 @@
 
   // NonMovableKey is neither copyable nor movable. We should still be able to
   // move nodes around.
-  static_assert(!std::is_move_constructible<NonMovableKey>::value, "");
+  static_assert(!std::is_move_constructible_v<NonMovableKey>, "");
   set1.merge(set2);
 
   EXPECT_THAT(set1,
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index d9b2c0e..fd41040 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -282,9 +282,8 @@
   return T{};
 }
 
-template <
-    typename ValueT, typename GenT,
-    std::enable_if_t<std::is_integral<ValueT>::value, int> = ((void)GenT{}, 0)>
+template <typename ValueT, typename GenT,
+          std::enable_if_t<std::is_integral_v<ValueT>, int> = ((void)GenT{}, 0)>
 constexpr FlagDefaultArg DefaultArg(int) {
   return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord};
 }
@@ -300,19 +299,19 @@
 
 template <typename T>
 using FlagUseValueAndInitBitStorage =
-    std::integral_constant<bool, std::is_trivially_copyable<T>::value &&
-                                     std::is_default_constructible<T>::value &&
+    std::integral_constant<bool, std::is_trivially_copyable_v<T> &&
+                                     std::is_default_constructible_v<T> &&
                                      (sizeof(T) < 8)>;
 
 template <typename T>
 using FlagUseOneWordStorage =
-    std::integral_constant<bool, std::is_trivially_copyable<T>::value &&
-                                     (sizeof(T) <= 8)>;
+    std::integral_constant<bool,
+                           std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>;
 
 template <class T>
 using FlagUseSequenceLockStorage =
-    std::integral_constant<bool, std::is_trivially_copyable<T>::value &&
-                                     (sizeof(T) > 8)>;
+    std::integral_constant<bool,
+                           std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>;
 
 enum class FlagValueStorageKind : uint8_t {
   kValueAndInitBit = 0,
diff --git a/absl/functional/any_invocable.h b/absl/functional/any_invocable.h
index 2fddb72..867885e 100644
--- a/absl/functional/any_invocable.h
+++ b/absl/functional/any_invocable.h
@@ -164,7 +164,7 @@
     : private internal_any_invocable::Impl<Sig> {
  private:
   static_assert(
-      std::is_function<Sig>::value,
+      std::is_function_v<Sig>,
       "The template argument of AnyInvocable must be a function type.");
 
   using Impl = internal_any_invocable::Impl<Sig>;
@@ -210,7 +210,7 @@
                 internal_any_invocable::CanEmplace<Sig, T, Args...>::value>>
   explicit AnyInvocable(std::in_place_type_t<T>, Args&&... args)
       : Impl(std::in_place_type<std::decay_t<T>>, std::forward<Args>(args)...) {
-    static_assert(std::is_same<T, std::decay_t<T>>::value,
+    static_assert(std::is_same_v<T, std::decay_t<T>>,
                   "The explicit template argument of in_place_type is required "
                   "to be an unqualified object type.");
   }
@@ -223,7 +223,7 @@
                         Args&&... args)
       : Impl(std::in_place_type<std::decay_t<T>>, ilist,
              std::forward<Args>(args)...) {
-    static_assert(std::is_same<T, std::decay_t<T>>::value,
+    static_assert(std::is_same_v<T, std::decay_t<T>>,
                   "The explicit template argument of in_place_type is required "
                   "to be an unqualified object type.");
   }
diff --git a/absl/functional/any_invocable_test.cc b/absl/functional/any_invocable_test.cc
index b79460d..1ad6d7b 100644
--- a/absl/functional/any_invocable_test.cc
+++ b/absl/functional/any_invocable_test.cc
@@ -40,15 +40,14 @@
 
 template <class T>
 struct Wrapper {
-  template <class U,
-            class = std::enable_if_t<std::is_convertible<U, T>::value>>
+  template <class U, class = std::enable_if_t<std::is_convertible_v<U, T>>>
   Wrapper(U&&);  // NOLINT
 };
 
 // This will cause a recursive trait instantiation if the SFINAE checks are
 // not ordered correctly for constructibility.
-static_assert(std::is_constructible<Wrapper<absl::AnyInvocable<void()>>,
-                                    Wrapper<absl::AnyInvocable<void()>>>::value,
+static_assert(std::is_constructible_v<Wrapper<absl::AnyInvocable<void()>>,
+                                      Wrapper<absl::AnyInvocable<void()>>>,
               "");
 
 // A metafunction that takes the cv and l-value reference qualifiers that were
@@ -56,9 +55,9 @@
 // type), and .
 template <class Qualifiers, class This>
 struct QualifiersForThisImpl {
-  static_assert(std::is_object<This>::value, "");
+  static_assert(std::is_object_v<This>, "");
   using type =
-      std::conditional_t<std::is_const<Qualifiers>::value, const This, This>&;
+      std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&;
 };
 
 template <class Qualifiers, class This>
@@ -67,9 +66,9 @@
 
 template <class Qualifiers, class This>
 struct QualifiersForThisImpl<Qualifiers&&, This> {
-  static_assert(std::is_object<This>::value, "");
+  static_assert(std::is_object_v<This>, "");
   using type =
-      std::conditional_t<std::is_const<Qualifiers>::value, const This, This>&&;
+      std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&&;
 };
 
 template <class Qualifiers, class This>
@@ -83,39 +82,37 @@
 
 template <class T, class R, class... P>
 struct GiveQualifiersToFunImpl<T, R(P...)> {
-  using type =
-      std::conditional_t<std::is_const<T>::value, R(P...) const, R(P...)>;
+  using type = std::conditional_t<std::is_const_v<T>, R(P...) const, R(P...)>;
 };
 
 template <class T, class R, class... P>
 struct GiveQualifiersToFunImpl<T&, R(P...)> {
   using type =
-      std::conditional_t<std::is_const<T>::value, R(P...) const&, R(P...) &>;
+      std::conditional_t<std::is_const_v<T>, R(P...) const&, R(P...) &>;
 };
 
 template <class T, class R, class... P>
 struct GiveQualifiersToFunImpl<T&&, R(P...)> {
   using type =
-      std::conditional_t<std::is_const<T>::value, R(P...) const&&, R(P...) &&>;
+      std::conditional_t<std::is_const_v<T>, R(P...) const&&, R(P...) &&>;
 };
 
 template <class T, class R, class... P>
 struct GiveQualifiersToFunImpl<T, R(P...) noexcept> {
-  using type = std::conditional_t<std::is_const<T>::value,
-                                  R(P...) const noexcept, R(P...) noexcept>;
+  using type = std::conditional_t<std::is_const_v<T>, R(P...) const noexcept,
+                                  R(P...) noexcept>;
 };
 
 template <class T, class R, class... P>
 struct GiveQualifiersToFunImpl<T&, R(P...) noexcept> {
-  using type = std::conditional_t<std::is_const<T>::value,
-                                  R(P...) const & noexcept, R(P...) & noexcept>;
+  using type = std::conditional_t<std::is_const_v<T>, R(P...) const & noexcept,
+                                  R(P...) & noexcept>;
 };
 
 template <class T, class R, class... P>
 struct GiveQualifiersToFunImpl<T&&, R(P...) noexcept> {
-  using type =
-      std::conditional_t<std::is_const<T>::value, R(P...) const && noexcept,
-                         R(P...) && noexcept>;
+  using type = std::conditional_t<std::is_const_v<T>, R(P...) const && noexcept,
+                                  R(P...) && noexcept>;
 };
 
 template <class T, class Fun>
@@ -305,8 +302,7 @@
   using Qualifiers = Qual;
   static constexpr NothrowCall kCallExceptionSpec = CallExceptionSpec;
   static constexpr bool kIsNoexcept = kCallExceptionSpec == NothrowCall::yes;
-  static constexpr bool kIsRvalueQualified =
-      std::is_rvalue_reference<Qual>::value;
+  static constexpr bool kIsRvalueQualified = std::is_rvalue_reference_v<Qual>;
   static constexpr ObjSize kSize = Size;
   static constexpr ObjAlign kAlignment = Alignment;
 
@@ -364,14 +360,14 @@
   }
 
   using CompatibleAnyInvocableFunType =
-      std::conditional_t<std::is_rvalue_reference<Qual>::value,
+      std::conditional_t<std::is_rvalue_reference_v<Qual>,
                          GiveQualifiersToFun<const _&&, UnqualifiedFunType>,
                          GiveQualifiersToFun<const _&, UnqualifiedFunType>>;
 
   using CompatibleAnyInvType = AnyInvocable<CompatibleAnyInvocableFunType>;
 
   using IncompatibleInvocable =
-      std::conditional_t<std::is_rvalue_reference<Qual>::value,
+      std::conditional_t<std::is_rvalue_reference_v<Qual>,
                          GiveQualifiersToFun<_&, UnqualifiedFunType>(_::*),
                          GiveQualifiersToFun<_&&, UnqualifiedFunType>(_::*)>;
 };
@@ -423,7 +419,7 @@
 
   EXPECT_FALSE(static_cast<bool>(fun));
 
-  EXPECT_TRUE(std::is_nothrow_default_constructible<AnyInvType>::value);
+  EXPECT_TRUE(std::is_nothrow_default_constructible_v<AnyInvType>);
 }
 
 TYPED_TEST_P(AnyInvTestBasic, ConstructionNullptr) {
@@ -433,8 +429,7 @@
 
   EXPECT_FALSE(static_cast<bool>(fun));
 
-  EXPECT_TRUE(
-      (std::is_nothrow_constructible<AnyInvType, std::nullptr_t>::value));
+  EXPECT_TRUE((std::is_nothrow_constructible_v<AnyInvType, std::nullptr_t>));
 }
 
 TYPED_TEST_P(AnyInvTestBasic, ConstructionNullFunctionPtr) {
@@ -533,9 +528,8 @@
     EXPECT_FALSE(fun ? true : false);  // NOLINT
 
     // Make sure that the conversion is not implicit.
-    EXPECT_TRUE(
-        (std::is_nothrow_constructible<bool, const AnyInvType&>::value));
-    EXPECT_FALSE((std::is_convertible<const AnyInvType&, bool>::value));
+    EXPECT_TRUE((std::is_nothrow_constructible_v<bool, const AnyInvType&>));
+    EXPECT_FALSE((std::is_convertible_v<const AnyInvType&, bool>));
   }
 
   {
@@ -554,7 +548,7 @@
 
   // Make sure the function call operator of AnyInvocable always has the
   // type that was specified via the template argument.
-  EXPECT_TRUE((std::is_same<AnyInvCallType, FunType>::value));
+  EXPECT_TRUE((std::is_same_v<AnyInvCallType, FunType>));
 
   AnyInvType fun = &add_function;
 
@@ -658,7 +652,7 @@
 
   EXPECT_FALSE(static_cast<bool>(fun));
 
-  EXPECT_TRUE(std::is_nothrow_move_constructible<AnyInvType>::value);
+  EXPECT_TRUE(std::is_nothrow_move_constructible_v<AnyInvType>);
 }
 
 TYPED_TEST_P(AnyInvTestBasic, MoveConstructionFromNonEmpty) {
@@ -671,7 +665,7 @@
   EXPECT_TRUE(static_cast<bool>(fun));
   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
 
-  EXPECT_TRUE(std::is_nothrow_move_constructible<AnyInvType>::value);
+  EXPECT_TRUE(std::is_nothrow_move_constructible_v<AnyInvType>);
 }
 
 TYPED_TEST_P(AnyInvTestBasic, ComparisonWithNullptrEmpty) {
@@ -703,8 +697,8 @@
   using AnyInvType = typename TypeParam::AnyInvType;
   using ExpectedResultType = typename TypeParam::ResultType;
 
-  EXPECT_TRUE((std::is_same<typename AnyInvType::result_type,
-                            ExpectedResultType>::value));
+  EXPECT_TRUE(
+      (std::is_same_v<typename AnyInvType::result_type, ExpectedResultType>));
 }
 
 template <class T>
@@ -1195,23 +1189,23 @@
 TYPED_TEST_P(AnyInvTestNoexceptFalse, ConversionConstructionConstraints) {
   using AnyInvType = typename TypeParam::AnyInvType;
 
-  EXPECT_TRUE((std::is_constructible<
-               AnyInvType,
-               typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
-  EXPECT_FALSE((
-      std::is_constructible<AnyInvType,
-                            typename TypeParam::IncompatibleInvocable>::value));
+  EXPECT_TRUE(
+      (std::is_constructible_v<
+          AnyInvType, typename TypeParam::AnyInvocableFunTypeNotNoexcept*>));
+  EXPECT_FALSE(
+      (std::is_constructible_v<AnyInvType,
+                               typename TypeParam::IncompatibleInvocable>));
 }
 
 TYPED_TEST_P(AnyInvTestNoexceptFalse, ConversionAssignConstraints) {
   using AnyInvType = typename TypeParam::AnyInvType;
 
-  EXPECT_TRUE((std::is_assignable<
-               AnyInvType&,
-               typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
+  EXPECT_TRUE(
+      (std::is_assignable_v<
+          AnyInvType&, typename TypeParam::AnyInvocableFunTypeNotNoexcept*>));
   EXPECT_FALSE(
-      (std::is_assignable<AnyInvType&,
-                          typename TypeParam::IncompatibleInvocable>::value));
+      (std::is_assignable_v<AnyInvType&,
+                            typename TypeParam::IncompatibleInvocable>));
 }
 
 template <class T>
@@ -1222,23 +1216,23 @@
 TYPED_TEST_P(AnyInvTestNoexceptTrue, ConversionConstructionConstraints) {
   using AnyInvType = typename TypeParam::AnyInvType;
 
-  EXPECT_FALSE((std::is_constructible<
-                AnyInvType,
-                typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
-  EXPECT_FALSE((
-      std::is_constructible<AnyInvType,
-                            typename TypeParam::IncompatibleInvocable>::value));
+  EXPECT_FALSE(
+      (std::is_constructible_v<
+          AnyInvType, typename TypeParam::AnyInvocableFunTypeNotNoexcept*>));
+  EXPECT_FALSE(
+      (std::is_constructible_v<AnyInvType,
+                               typename TypeParam::IncompatibleInvocable>));
 }
 
 TYPED_TEST_P(AnyInvTestNoexceptTrue, ConversionAssignConstraints) {
   using AnyInvType = typename TypeParam::AnyInvType;
 
-  EXPECT_FALSE((std::is_assignable<
-                AnyInvType&,
-                typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
   EXPECT_FALSE(
-      (std::is_assignable<AnyInvType&,
-                          typename TypeParam::IncompatibleInvocable>::value));
+      (std::is_assignable_v<
+          AnyInvType&, typename TypeParam::AnyInvocableFunTypeNotNoexcept*>));
+  EXPECT_FALSE(
+      (std::is_assignable_v<AnyInvType&,
+                            typename TypeParam::IncompatibleInvocable>));
 }
 
 template <class T>
@@ -1270,8 +1264,8 @@
     Result(Result&&) = delete;
   };
 
-  static_assert(!std::is_move_constructible<Result>::value, "");
-  static_assert(!std::is_copy_constructible<Result>::value, "");
+  static_assert(!std::is_move_constructible_v<Result>, "");
+  static_assert(!std::is_copy_constructible_v<Result>, "");
 
   // Assumption check: it should nevertheless be possible to use functors that
   // return a Result struct according to the language rules.
@@ -1298,9 +1292,8 @@
   AnyInvType fun;
   fun = std::ref(add);
   add.state = 5;
-  EXPECT_TRUE(
-      (std::is_nothrow_assignable<AnyInvType&,
-                                  std::reference_wrapper<AddType>>::value));
+  EXPECT_TRUE((std::is_nothrow_assignable_v<AnyInvType&,
+                                            std::reference_wrapper<AddType>>));
 
   EXPECT_TRUE(static_cast<bool>(fun));
   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
@@ -1317,9 +1310,8 @@
   AnyInvType fun = &mult_function;
   fun = std::ref(add);
   add.state = 5;
-  EXPECT_TRUE(
-      (std::is_nothrow_assignable<AnyInvType&,
-                                  std::reference_wrapper<AddType>>::value));
+  EXPECT_TRUE((std::is_nothrow_assignable_v<AnyInvType&,
+                                            std::reference_wrapper<AddType>>));
 
   EXPECT_TRUE(static_cast<bool>(fun));
   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
@@ -1337,8 +1329,8 @@
   using AnyInvType = typename TypeParam::AnyInvType;
   using AddType = typename TypeParam::AddType;
 
-  EXPECT_FALSE((
-      std::is_convertible<std::reference_wrapper<AddType>, AnyInvType>::value));
+  EXPECT_FALSE(
+      (std::is_convertible_v<std::reference_wrapper<AddType>, AnyInvType>));
 }
 
 TYPED_TEST_P(AnyInvTestRvalue, NonMoveableResultType) {
@@ -1350,8 +1342,8 @@
     Result(Result&&) = delete;
   };
 
-  static_assert(!std::is_move_constructible<Result>::value, "");
-  static_assert(!std::is_copy_constructible<Result>::value, "");
+  static_assert(!std::is_move_constructible_v<Result>, "");
+  static_assert(!std::is_copy_constructible_v<Result>, "");
 
   // Assumption check: it should nevertheless be possible to use functors that
   // return a Result struct according to the language rules.
@@ -1373,8 +1365,8 @@
   using AnyInvType = typename TypeParam::AnyInvType;
   using AddType = typename TypeParam::AddType;
 
-  EXPECT_FALSE((
-      std::is_assignable<AnyInvType&, std::reference_wrapper<AddType>>::value));
+  EXPECT_FALSE(
+      (std::is_assignable_v<AnyInvType&, std::reference_wrapper<AddType>>));
 }
 
 TYPED_TEST_P(AnyInvTestRvalue, NonConstCrashesOnSecondCall) {
@@ -1676,9 +1668,8 @@
 
 // Minimal SFINAE testing for platforms where we can't run the tests, but we can
 // build binaries for.
-static_assert(
-    std::is_convertible<void (*)(), absl::AnyInvocable<void() &&>>::value, "");
-static_assert(!std::is_convertible<void*, absl::AnyInvocable<void() &&>>::value,
+static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>,
               "");
+static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>, "");
 
 }  // namespace
diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h
index 3882eb0..f6b2f22 100644
--- a/absl/functional/function_ref.h
+++ b/absl/functional/function_ref.h
@@ -91,7 +91,7 @@
   // signature of this FunctionRef.
   template <typename F, typename... U>
   using EnableIfCompatible =
-      std::enable_if_t<std::is_invocable_r<R, F, U..., Args...>::value>;
+      std::enable_if_t<std::is_invocable_r_v<R, F, U..., Args...>>;
 
   // Internal constructor to supersede the copying constructor
   template <typename F>
diff --git a/absl/functional/function_ref_test.cc b/absl/functional/function_ref_test.cc
index 81da61a..69513f4 100644
--- a/absl/functional/function_ref_test.cc
+++ b/absl/functional/function_ref_test.cc
@@ -255,31 +255,28 @@
     void* p[3];
   };
 
-  static_assert(std::is_same<Invoker<void, int>, void (*)(VoidPtr, int)>::value,
+  static_assert(std::is_same_v<Invoker<void, int>, void (*)(VoidPtr, int)>,
                 "Scalar types should be passed by value");
   static_assert(
-      std::is_same<Invoker<void, Trivial>, void (*)(VoidPtr, Trivial)>::value,
+      std::is_same_v<Invoker<void, Trivial>, void (*)(VoidPtr, Trivial)>,
       "Small trivial types should be passed by value");
-  static_assert(std::is_same<Invoker<void, LargeTrivial>,
-                             void (*)(VoidPtr, LargeTrivial&&)>::value,
+  static_assert(std::is_same_v<Invoker<void, LargeTrivial>,
+                               void (*)(VoidPtr, LargeTrivial&&)>,
                 "Large trivial types should be passed by rvalue reference");
   static_assert(
-      std::is_same<Invoker<void, CopyableMovableInstance>,
-                   void (*)(VoidPtr, CopyableMovableInstance&&)>::value,
+      std::is_same_v<Invoker<void, CopyableMovableInstance>,
+                     void (*)(VoidPtr, CopyableMovableInstance&&)>,
       "Types with copy/move ctor should be passed by rvalue reference");
 
   // References are passed as references.
-  static_assert(
-      std::is_same<Invoker<void, int&>, void (*)(VoidPtr, int&)>::value,
-      "Reference types should be preserved");
-  static_assert(
-      std::is_same<Invoker<void, CopyableMovableInstance&>,
-                   void (*)(VoidPtr, CopyableMovableInstance&)>::value,
-      "Reference types should be preserved");
-  static_assert(
-      std::is_same<Invoker<void, CopyableMovableInstance&&>,
-                   void (*)(VoidPtr, CopyableMovableInstance&&)>::value,
-      "Reference types should be preserved");
+  static_assert(std::is_same_v<Invoker<void, int&>, void (*)(VoidPtr, int&)>,
+                "Reference types should be preserved");
+  static_assert(std::is_same_v<Invoker<void, CopyableMovableInstance&>,
+                               void (*)(VoidPtr, CopyableMovableInstance&)>,
+                "Reference types should be preserved");
+  static_assert(std::is_same_v<Invoker<void, CopyableMovableInstance&&>,
+                               void (*)(VoidPtr, CopyableMovableInstance&&)>,
+                "Reference types should be preserved");
 
   // Make sure the address of an object received by reference is the same as the
   // address of the object passed by the caller.
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h
index 46f7266..ecf0319 100644
--- a/absl/functional/internal/any_invocable.h
+++ b/absl/functional/internal/any_invocable.h
@@ -104,7 +104,7 @@
 constexpr bool IsStoredLocally() {
   if constexpr (sizeof(T) <= kStorageSize && alignof(T) <= kAlignment &&
                 kAlignment % alignof(T) == 0) {
-    return std::is_nothrow_move_constructible<T>::value;
+    return std::is_nothrow_move_constructible_v<T>;
   }
   return false;
 }
@@ -146,8 +146,7 @@
 template <class T>
 struct ForwardedParameter {
   using type = decltype((
-      ForwardImpl<T>)(std::integral_constant<bool,
-                                             std::is_scalar<T>::value>()));
+      ForwardImpl<T>)(std::integral_constant<bool, std::is_scalar_v<T>>()));
 };
 
 template <class T>
@@ -243,7 +242,7 @@
                             TypeErasedState* const to) noexcept {
   static_assert(IsStoredLocally<T>(),
                 "Local storage must only be used for supported types.");
-  static_assert(!std::is_trivially_copyable<T>::value,
+  static_assert(!std::is_trivially_copyable_v<T>,
                 "Locally stored types must be trivially copyable.");
 
   T& from_object = (ObjectInLocalStorage<T>)(from);
@@ -416,8 +415,8 @@
   explicit CoreImpl(TypedConversionConstruct<QualDecayedTRef>, F&& f) {
     using DecayedT = RemoveCVRef<QualDecayedTRef>;
 
-    if constexpr (std::is_pointer<DecayedT>::value ||
-                  std::is_member_pointer<DecayedT>::value) {
+    if constexpr (std::is_pointer_v<DecayedT> ||
+                  std::is_member_pointer_v<DecayedT>) {
       // This condition handles types that decay into pointers. This includes
       // function references, which cannot be null. GCC warns against comparing
       // their decayed form with nullptr (https://godbolt.org/z/9r9TMTcPK).
@@ -614,13 +613,13 @@
 /*SFINAE constraints for the conversion-constructor.*/
 template <class Sig, class F,
           class = std::enable_if_t<
-              !std::is_same<RemoveCVRef<F>, AnyInvocable<Sig>>::value>>
-using CanConvert = TrueAlias<
-    std::enable_if_t<!IsInPlaceType<RemoveCVRef<F>>::value>,
-    std::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
-    std::enable_if_t<
-        Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
-    std::enable_if_t<std::is_constructible<std::decay_t<F>, F>::value>>;
+              !std::is_same_v<RemoveCVRef<F>, AnyInvocable<Sig>>>>
+using CanConvert =
+    TrueAlias<std::enable_if_t<!IsInPlaceType<RemoveCVRef<F>>::value>,
+              std::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
+              std::enable_if_t<
+                  Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
+              std::enable_if_t<std::is_constructible_v<std::decay_t<F>, F>>>;
 
 /*SFINAE constraints for the std::in_place constructors.*/
 template <class Sig, class F, class... Args>
@@ -628,17 +627,17 @@
     std::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
     std::enable_if_t<
         Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
-    std::enable_if_t<std::is_constructible<std::decay_t<F>, Args...>::value>>;
+    std::enable_if_t<std::is_constructible_v<std::decay_t<F>, Args...>>>;
 
 /*SFINAE constraints for the conversion-assign operator.*/
 template <class Sig, class F,
           class = std::enable_if_t<
-              !std::is_same<RemoveCVRef<F>, AnyInvocable<Sig>>::value>>
-using CanAssign = TrueAlias<
-    std::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
-    std::enable_if_t<
-        Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
-    std::enable_if_t<std::is_constructible<std::decay_t<F>, F>::value>>;
+              !std::is_same_v<RemoveCVRef<F>, AnyInvocable<Sig>>>>
+using CanAssign =
+    TrueAlias<std::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
+              std::enable_if_t<
+                  Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
+              std::enable_if_t<std::is_constructible_v<std::decay_t<F>, F>>>;
 
 /*SFINAE constraints for the reference-wrapper conversion-assign operator.*/
 template <class Sig, class F>
@@ -658,19 +657,19 @@
 // to give the right result when ReturnType is non-moveable in toolchains that
 // don't treat non-moveable result types correctly. For example this was the
 // case in libc++ before commit c3a24882 (2022-05).
-#define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_true(inv_quals)      \
-  std::enable_if_t<std::disjunction<                                       \
-      std::is_nothrow_invocable_r<                                           \
+#define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_true(inv_quals)     \
+  std::enable_if_t<std::disjunction_v<                                      \
+      std::is_nothrow_invocable_r<                                          \
           ReturnType, UnwrapStdReferenceWrapper<std::decay_t<F>> inv_quals, \
-          P...>,                                                             \
-      std::conjunction<                                                      \
-          std::is_nothrow_invocable<                                         \
+          P...>,                                                            \
+      std::conjunction<                                                     \
+          std::is_nothrow_invocable<                                        \
               UnwrapStdReferenceWrapper<std::decay_t<F>> inv_quals, P...>,  \
-          std::is_same<                                                      \
-              ReturnType,                                                    \
-              std::invoke_result_t<                                          \
+          std::is_same<                                                     \
+              ReturnType,                                                   \
+              std::invoke_result_t<                                         \
                   UnwrapStdReferenceWrapper<std::decay_t<F>> inv_quals,     \
-                  P...>>>>::value>
+                  P...>>>>>
 
 #define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_false(inv_quals)
 //
@@ -737,8 +736,8 @@
     InvokerType<noex, ReturnType, P...>* ExtractInvoker() cv {                 \
       using QualifiedTestType = int cv ref;                                    \
       auto* invoker = this->invoker_;                                          \
-      if (!std::is_const<QualifiedTestType>::value &&                          \
-          std::is_rvalue_reference<QualifiedTestType>::value) {                \
+      if (!std::is_const_v<QualifiedTestType> &&                               \
+          std::is_rvalue_reference_v<QualifiedTestType>) {                     \
         ABSL_ASSERT([this]() {                                                 \
           /* We checked that this isn't const above, so const_cast is safe */  \
           const_cast<Impl*>(this)->invoker_ = InvokedAfterMove;                \
diff --git a/absl/functional/internal/function_ref.h b/absl/functional/internal/function_ref.h
index a8667ea..3170ff9 100644
--- a/absl/functional/internal/function_ref.h
+++ b/absl/functional/internal/function_ref.h
@@ -40,18 +40,16 @@
 // Chooses the best type for passing T as an argument.
 // Attempt to be close to SystemV AMD64 ABI. Objects with trivial copy ctor are
 // passed by value.
-template <typename T,
-          bool IsLValueReference = std::is_lvalue_reference<T>::value>
+template <typename T, bool IsLValueReference = std::is_lvalue_reference_v<T>>
 struct PassByValue : std::false_type {};
 
 template <typename T>
 struct PassByValue<T, /*IsLValueReference=*/false>
     : std::integral_constant<
-          bool,
-          std::is_trivially_copy_constructible<T>::value &&
-              std::is_trivially_copy_assignable<std::remove_cv_t<T>>::value &&
-              std::is_trivially_destructible<T>::value &&
-              sizeof(T) <= 2 * sizeof(void*)> {};
+          bool, std::is_trivially_copy_constructible_v<T> &&
+                    std::is_trivially_copy_assignable_v<std::remove_cv_t<T>> &&
+                    std::is_trivially_destructible_v<T> &&
+                    sizeof(T) <= 2 * sizeof(void*)> {};
 
 template <typename T>
 struct ForwardT : std::conditional<PassByValue<T>::value, T, T&&> {};
diff --git a/absl/hash/hash.h b/absl/hash/hash.h
index e2bde0c..fc791ab 100644
--- a/absl/hash/hash.h
+++ b/absl/hash/hash.h
@@ -327,10 +327,9 @@
   // redirected to the original `state` object. The `state` object must outlive
   // the `HashState` instance. `T` must be a subclass of `HashStateBase<T>` -
   // users should not define their own HashState types.
-  template <
-      typename T,
-      std::enable_if_t<
-          std::is_base_of<hash_internal::HashStateBase<T>, T>::value, int> = 0>
+  template <typename T,
+            std::enable_if_t<
+                std::is_base_of_v<hash_internal::HashStateBase<T>, T>, int> = 0>
   static HashState Create(T* state) {
     HashState s;
     s.Init(state);
diff --git a/absl/hash/hash_benchmark.cc b/absl/hash/hash_benchmark.cc
index b39ef75..d0ebdbc 100644
--- a/absl/hash/hash_benchmark.cc
+++ b/absl/hash/hash_benchmark.cc
@@ -350,7 +350,7 @@
 
 template <class T>
 struct PodRand {
-  static_assert(std::is_pod<T>::value, "");
+  static_assert(std::is_pod_v<T>, "");
   static_assert(kEntropySize + sizeof(T) < sizeof(entropy), "");
 
   T Get(size_t i) const {
diff --git a/absl/hash/hash_instantiated_test.cc b/absl/hash/hash_instantiated_test.cc
index 280b1c3..a7b7826 100644
--- a/absl/hash/hash_instantiated_test.cc
+++ b/absl/hash/hash_instantiated_test.cc
@@ -59,9 +59,8 @@
   template <typename TT>
   UnorderedSequence(std::initializer_list<TT> l)
       : values_(l.begin(), l.end()) {}
-  template <
-      typename ForwardIterator,
-      std::enable_if_t<!std::is_integral<ForwardIterator>::value, bool> = true>
+  template <typename ForwardIterator,
+            std::enable_if_t<!std::is_integral_v<ForwardIterator>, bool> = true>
   UnorderedSequence(ForwardIterator begin, ForwardIterator end)
       : values_(begin, end) {}
   // one-argument constructor of value type T, to appease older toolchains that
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index d888660..e128b62 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -800,11 +800,11 @@
 
 TEST(IsHashableTest, ValidHash) {
   EXPECT_TRUE((is_hashable<int>::value));
-  EXPECT_TRUE(std::is_default_constructible<absl::Hash<int>>::value);
-  EXPECT_TRUE(std::is_copy_constructible<absl::Hash<int>>::value);
-  EXPECT_TRUE(std::is_move_constructible<absl::Hash<int>>::value);
-  EXPECT_TRUE(std::is_copy_assignable<absl::Hash<int>>::value);
-  EXPECT_TRUE(std::is_move_assignable<absl::Hash<int>>::value);
+  EXPECT_TRUE(std::is_default_constructible_v<absl::Hash<int>>);
+  EXPECT_TRUE(std::is_copy_constructible_v<absl::Hash<int>>);
+  EXPECT_TRUE(std::is_move_constructible_v<absl::Hash<int>>);
+  EXPECT_TRUE(std::is_copy_assignable_v<absl::Hash<int>>);
+  EXPECT_TRUE(std::is_move_assignable_v<absl::Hash<int>>);
   EXPECT_TRUE(IsHashCallable<int>::value);
   EXPECT_TRUE(IsAggregateInitializable<absl::Hash<int>>::value);
 }
@@ -812,11 +812,11 @@
 TEST(IsHashableTest, PoisonHash) {
   struct X {};
   EXPECT_FALSE((is_hashable<X>::value));
-  EXPECT_FALSE(std::is_default_constructible<absl::Hash<X>>::value);
-  EXPECT_FALSE(std::is_copy_constructible<absl::Hash<X>>::value);
-  EXPECT_FALSE(std::is_move_constructible<absl::Hash<X>>::value);
-  EXPECT_FALSE(std::is_copy_assignable<absl::Hash<X>>::value);
-  EXPECT_FALSE(std::is_move_assignable<absl::Hash<X>>::value);
+  EXPECT_FALSE(std::is_default_constructible_v<absl::Hash<X>>);
+  EXPECT_FALSE(std::is_copy_constructible_v<absl::Hash<X>>);
+  EXPECT_FALSE(std::is_move_constructible_v<absl::Hash<X>>);
+  EXPECT_FALSE(std::is_copy_assignable_v<absl::Hash<X>>);
+  EXPECT_FALSE(std::is_move_assignable_v<absl::Hash<X>>);
   EXPECT_FALSE(IsHashCallable<X>::value);
 #if !defined(__GNUC__) || defined(__clang__)
   // TODO(b/144368551): As of GCC 8.4 this does not compile.
@@ -891,8 +891,8 @@
 
 template <InvokeTag allowed, InvokeTag... tags>
 struct EnableIfContained
-    : std::enable_if<std::disjunction<
-          std::integral_constant<bool, allowed == tags>...>::value> {};
+    : std::enable_if<std::disjunction_v<
+          std::integral_constant<bool, allowed == tags>...>> {};
 
 template <
     typename H, InvokeTag... Tags,
@@ -1016,10 +1016,10 @@
 
 static_assert(sizeof(StructWithPadding) > sizeof(char) + sizeof(int),
               "StructWithPadding doesn't have padding");
-static_assert(std::is_standard_layout<StructWithPadding>::value, "");
+static_assert(std::is_standard_layout_v<StructWithPadding>, "");
 
 // This check has to be disabled because libstdc++ doesn't support it.
-// static_assert(std::is_trivially_constructible<StructWithPadding>::value, "");
+// static_assert(std::is_trivially_constructible_v<StructWithPadding>, "");
 
 template <typename T>
 struct ArraySlice {
diff --git a/absl/hash/hash_testing.h b/absl/hash/hash_testing.h
index fb878aa..d932f63 100644
--- a/absl/hash/hash_testing.h
+++ b/absl/hash/hash_testing.h
@@ -282,7 +282,7 @@
 
 template <typename... T>
 struct TypeSet {
-  template <typename U, bool = std::disjunction<std::is_same<T, U>...>::value>
+  template <typename U, bool = std::disjunction_v<std::is_same<T, U>...>>
   struct Insert {
     using type = TypeSet<U, T...>;
   };
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index a21f8ec..972e9bd 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -381,8 +381,8 @@
 // Integral types other than bool should be uniquely represented on any
 // platform that this will plausibly be ported to.
 template <typename Integral>
-struct is_uniquely_represented<
-    Integral, std::enable_if_t<std::is_integral<Integral>::value>>
+struct is_uniquely_represented<Integral,
+                               std::enable_if_t<std::is_integral_v<Integral>>>
     : std::true_type {};
 
 template <>
@@ -460,8 +460,8 @@
 // We use SFINAE to ensure that this overload only accepts bool, not types that
 // are convertible to bool.
 template <typename H, typename B>
-std::enable_if_t<std::is_same<B, bool>::value, H> AbslHashValue(H hash_state,
-                                                                B value) {
+std::enable_if_t<std::is_same_v<B, bool>, H> AbslHashValue(H hash_state,
+                                                           B value) {
   // We use ~size_t{} instead of 1 so that all bits are different between
   // true/false instead of only 1.
   return H::combine(std::move(hash_state),
@@ -470,8 +470,7 @@
 
 // AbslHashValue() for hashing enum values
 template <typename H, typename Enum>
-std::enable_if_t<std::is_enum<Enum>::value, H> AbslHashValue(H hash_state,
-                                                             Enum e) {
+std::enable_if_t<std::is_enum_v<Enum>, H> AbslHashValue(H hash_state, Enum e) {
   // In practice, we could almost certainly just invoke hash_bytes directly,
   // but it's possible that a sanitizer might one day want to
   // store data in the unused bits of an enum. To avoid that risk, we
@@ -482,8 +481,8 @@
 }
 // AbslHashValue() for hashing floating-point values
 template <typename H, typename Float>
-std::enable_if_t<
-    std::is_same<Float, float>::value || std::is_same<Float, double>::value, H>
+std::enable_if_t<std::is_same_v<Float, float> || std::is_same_v<Float, double>,
+                 H>
 AbslHashValue(H hash_state, Float value) {
   return hash_internal::hash_bytes(std::move(hash_state),
                                    value == 0 ? 0 : value);
@@ -494,7 +493,7 @@
 // of it. This means we can't use hash_bytes on a long double and have to
 // convert it to something else first.
 template <typename H, typename LongDouble>
-std::enable_if_t<std::is_same<LongDouble, long double>::value, H> AbslHashValue(
+std::enable_if_t<std::is_same_v<LongDouble, long double>, H> AbslHashValue(
     H hash_state, LongDouble value) {
   const int category = std::fpclassify(value);
   switch (category) {
@@ -539,8 +538,7 @@
 
 // AbslHashValue() for hashing pointers
 template <typename H, typename T>
-std::enable_if_t<std::is_pointer<T>::value, H> AbslHashValue(H hash_state,
-                                                             T ptr) {
+std::enable_if_t<std::is_pointer_v<T>, H> AbslHashValue(H hash_state, T ptr) {
   auto v = reinterpret_cast<uintptr_t>(ptr);
   // Due to alignment, pointers tend to have low bits as zero, and the next few
   // bits follow a pattern since they are also multiples of some base value.
@@ -578,7 +576,7 @@
   // On other platforms, we assume that pointers-to-members do not have
   // padding.
 #ifdef __cpp_lib_has_unique_object_representations
-    static_assert(std::has_unique_object_representations<T C::*>::value);
+    static_assert(std::has_unique_object_representations_v<T C::*>);
 #endif  // __cpp_lib_has_unique_object_representations
     return n;
 #endif
@@ -613,7 +611,7 @@
 // for now.
 H
 #else   // _MSC_VER
-std::enable_if_t<std::conjunction<is_hashable<Ts>...>::value, H>
+std::enable_if_t<std::conjunction_v<is_hashable<Ts>...>, H>
 #endif  // _MSC_VER
 AbslHashValue(H hash_state, const std::tuple<Ts...>& t) {
   return hash_internal::hash_tuple(std::move(hash_state), t,
@@ -662,9 +660,9 @@
 
 // Support std::wstring, std::u16string and std::u32string.
 template <typename Char, typename Alloc, typename H,
-          typename = std::enable_if_t<std::is_same<Char, wchar_t>::value ||
-                                       std::is_same<Char, char16_t>::value ||
-                                       std::is_same<Char, char32_t>::value>>
+          typename = std::enable_if_t<std::is_same_v<Char, wchar_t> ||
+                                      std::is_same_v<Char, char16_t> ||
+                                      std::is_same_v<Char, char32_t>>>
 H AbslHashValue(
     H hash_state,
     const std::basic_string<Char, std::char_traits<Char>, Alloc>& str) {
@@ -673,9 +671,9 @@
 
 // Support std::wstring_view, std::u16string_view and std::u32string_view.
 template <typename Char, typename H,
-          typename = std::enable_if_t<std::is_same<Char, wchar_t>::value ||
-                                       std::is_same<Char, char16_t>::value ||
-                                       std::is_same<Char, char32_t>::value>>
+          typename = std::enable_if_t<std::is_same_v<Char, wchar_t> ||
+                                      std::is_same_v<Char, char16_t> ||
+                                      std::is_same_v<Char, char32_t>>>
 H AbslHashValue(H hash_state, std::basic_string_view<Char> str) {
   return H::combine_contiguous(std::move(hash_state), str.data(), str.size());
 }
@@ -757,7 +755,7 @@
 // implementation of std::hash. It does not have a .data(), and a fallback for
 // std::hash<> is most likely faster.
 template <typename H, typename T, typename Allocator>
-std::enable_if_t<is_hashable<T>::value && !std::is_same<T, bool>::value, H>
+std::enable_if_t<is_hashable<T>::value && !std::is_same_v<T, bool>, H>
 AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
   return H::combine_contiguous(std::move(hash_state), vector.data(),
                                vector.size());
@@ -773,7 +771,7 @@
 // it. More details on the bug:
 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531
 template <typename H, typename T, typename Allocator>
-std::enable_if_t<is_hashable<T>::value && std::is_same<T, bool>::value, H>
+std::enable_if_t<is_hashable<T>::value && std::is_same_v<T, bool>, H>
 AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
   typename H::AbslInternalPiecewiseCombiner combiner;
   for (const auto& i : vector) {
@@ -792,7 +790,7 @@
 // Mixing in the size (as we do in our other vector<> implementations) on top
 // of the library-provided hash implementation avoids this QOI issue.
 template <typename H, typename T, typename Allocator>
-std::enable_if_t<is_hashable<T>::value && std::is_same<T, bool>::value, H>
+std::enable_if_t<is_hashable<T>::value && std::is_same_v<T, bool>, H>
 AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
   return H::combine(std::move(hash_state),
                     std::hash<std::vector<T, Allocator>>{}(vector),
@@ -924,7 +922,7 @@
 
 // AbslHashValue for hashing std::variant
 template <typename H, typename... T>
-std::enable_if_t<std::conjunction<is_hashable<T>...>::value, H> AbslHashValue(
+std::enable_if_t<std::conjunction_v<is_hashable<T>...>, H> AbslHashValue(
     H hash_state, const std::variant<T...>& v) {
   if (!v.valueless_by_exception()) {
     hash_state = std::visit(VariantVisitor<H>{std::move(hash_state)}, v);
@@ -1312,8 +1310,7 @@
   struct HashValueProbe {
     template <typename H, typename T>
     static auto Invoke(H state, const T& value) -> std::enable_if_t<
-        std::is_same<H,
-                     decltype(AbslHashValue(std::move(state), value))>::value,
+        std::is_same_v<H, decltype(AbslHashValue(std::move(state), value))>,
         H> {
       return AbslHashValue(std::move(state), value);
     }
@@ -1323,9 +1320,9 @@
 #if ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_
     template <typename H, typename T>
     static auto Invoke(H state, const T& value) -> std::enable_if_t<
-        std::is_convertible<
+        std::is_convertible_v<
             decltype(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE::hash<T>()(value)),
-            size_t>::value,
+            size_t>,
         H> {
       return hash_internal::hash_bytes(
           std::move(state),
diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h
index 0eb9ffe..51caaf1 100644
--- a/absl/hash/internal/spy_hash_state.h
+++ b/absl/hash/internal/spy_hash_state.h
@@ -48,7 +48,7 @@
 class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
  public:
   SpyHashStateImpl() : error_(std::make_shared<std::optional<std::string>>()) {
-    static_assert(std::is_void<T>::value, "");
+    static_assert(std::is_void_v<T>, "");
   }
 
   // Move-only
@@ -270,7 +270,7 @@
 template <
     typename T, typename U,
     // Only trigger for when (T != U),
-    typename = std::enable_if_t<!std::is_same<T, U>::value>,
+    typename = std::enable_if_t<!std::is_same_v<T, U>>,
     // This statement works in two ways:
     //  - First, it instantiates RunOnStartup and forces the initialization of
     //    `run`, which set the global variable.
diff --git a/absl/log/internal/container.h b/absl/log/internal/container.h
index 82ca840..ea2445f 100644
--- a/absl/log/internal/container.h
+++ b/absl/log/internal/container.h
@@ -301,7 +301,7 @@
 //   LOG(INFO) << LogEnum(kRed);
 template <typename E>
 detail::EnumLogger<E> LogEnum(E e) {
-  static_assert(std::is_enum<E>::value, "must be an enum");
+  static_assert(std::is_enum_v<E>, "must be an enum");
   return detail::EnumLogger<E>(e);
 }
 
diff --git a/absl/log/internal/log_format.cc b/absl/log/internal/log_format.cc
index 23cef88..d54cf19 100644
--- a/absl/log/internal/log_format.cc
+++ b/absl/log/internal/log_format.cc
@@ -51,8 +51,8 @@
 // comparisons when log_internal::Tid is unsigned. It can be replaced with a
 // constexpr if once the minimum C++ version Abseil supports is C++17.
 template <typename T>
-inline std::enable_if_t<!std::is_signed<T>::value>
-PutLeadingWhitespace(T tid, char*& p) {
+inline std::enable_if_t<!std::is_signed_v<T>> PutLeadingWhitespace(T tid,
+                                                                   char*& p) {
   if (tid < 10) *p++ = ' ';
   if (tid < 100) *p++ = ' ';
   if (tid < 1000) *p++ = ' ';
@@ -62,8 +62,8 @@
 }
 
 template <typename T>
-inline std::enable_if_t<std::is_signed<T>::value>
-PutLeadingWhitespace(T tid, char*& p) {
+inline std::enable_if_t<std::is_signed_v<T>> PutLeadingWhitespace(T tid,
+                                                                  char*& p) {
   if (tid >= 0 && tid < 10) *p++ = ' ';
   if (tid > -10 && tid < 100) *p++ = ' ';
   if (tid > -100 && tid < 1000) *p++ = ' ';
diff --git a/absl/log/internal/vlog_config.h b/absl/log/internal/vlog_config.h
index da020f8..f65eb5d 100644
--- a/absl/log/internal/vlog_config.h
+++ b/absl/log/internal/vlog_config.h
@@ -120,7 +120,7 @@
   std::atomic<int> v_;
   std::atomic<VLogSite*> next_;
 };
-static_assert(std::is_trivially_destructible<VLogSite>::value,
+static_assert(std::is_trivially_destructible_v<VLogSite>,
               "VLogSite must be trivially destructible");
 
 // Returns the current verbose log level of `file`.
diff --git a/absl/log/internal/vlog_config_benchmark.cc b/absl/log/internal/vlog_config_benchmark.cc
index 9438324..7700edb 100644
--- a/absl/log/internal/vlog_config_benchmark.cc
+++ b/absl/log/internal/vlog_config_benchmark.cc
@@ -116,7 +116,7 @@
     sites[num_tus - 1]->next_.store(nullptr, std::memory_order_seq_cst);
   }
   ~SyntheticBinary() {
-    static_assert(std::is_trivially_destructible<VLogSite>::value, "");
+    static_assert(std::is_trivially_destructible_v<VLogSite>, "");
     absl::log_internal::SetVModuleListHeadForTestOnly(nullptr);
   }
 
diff --git a/absl/log/log_entry_test.cc b/absl/log/log_entry_test.cc
index d9bfa1f..3af10b6 100644
--- a/absl/log/log_entry_test.cc
+++ b/absl/log/log_entry_test.cc
@@ -208,7 +208,7 @@
 TEST(LogEntryTest, NegativeFields) {
   // When Abseil's minimum C++ version is C++17, this conditional can be
   // converted to a constexpr if and the static_cast below removed.
-  if (std::is_signed<absl::LogEntry::tid_t>::value) {
+  if (std::is_signed_v<absl::LogEntry::tid_t>) {
     LogEntryTestPeer entry(
         "foo.cc", -1234, kUsePrefix, absl::LogSeverity::kInfo,
         "2020-01-02T03:04:05.6789", static_cast<absl::LogEntry::tid_t>(-451),
@@ -318,7 +318,7 @@
 TEST(LogEntryTest, LongNegativeFields) {
   // When Abseil's minimum C++ version is C++17, this conditional can be
   // converted to a constexpr if and the static_cast below removed.
-  if (std::is_signed<absl::LogEntry::tid_t>::value) {
+  if (std::is_signed_v<absl::LogEntry::tid_t>) {
     LogEntryTestPeer entry(
         "I am the very model of a modern Major-General / "
         "I've information vegetable, animal, and mineral.",
diff --git a/absl/log/log_format_test.cc b/absl/log/log_format_test.cc
index 64035ce..aa520e4 100644
--- a/absl/log/log_format_test.cc
+++ b/absl/log/log_format_test.cc
@@ -326,9 +326,10 @@
 
 template <typename T>
 class UnsignedEnumLogFormatTest : public testing::Test {};
-using UnsignedEnumTypes = std::conditional_t<
-    std::is_signed<std::underlying_type_t<MyUnsignedEnum>>::value,
-    Types<MyUnsignedIntEnum>, Types<MyUnsignedEnum, MyUnsignedIntEnum>>;
+using UnsignedEnumTypes =
+    std::conditional_t<std::is_signed_v<std::underlying_type_t<MyUnsignedEnum>>,
+                       Types<MyUnsignedIntEnum>,
+                       Types<MyUnsignedEnum, MyUnsignedIntEnum>>;
 TYPED_TEST_SUITE(UnsignedEnumLogFormatTest, UnsignedEnumTypes);
 
 TYPED_TEST(UnsignedEnumLogFormatTest, Positive) {
@@ -387,10 +388,10 @@
 
 template <typename T>
 class SignedEnumLogFormatTest : public testing::Test {};
-using SignedEnumTypes = std::conditional_t<
-    std::is_signed<std::underlying_type_t<MyUnsignedEnum>>::value,
-    Types<MyUnsignedEnum, MySignedEnum, MySignedIntEnum>,
-    Types<MySignedEnum, MySignedIntEnum>>;
+using SignedEnumTypes =
+    std::conditional_t<std::is_signed_v<std::underlying_type_t<MyUnsignedEnum>>,
+                       Types<MyUnsignedEnum, MySignedEnum, MySignedIntEnum>,
+                       Types<MySignedEnum, MySignedIntEnum>>;
 TYPED_TEST_SUITE(SignedEnumLogFormatTest, SignedEnumTypes);
 
 TYPED_TEST(SignedEnumLogFormatTest, Positive) {
diff --git a/absl/memory/memory.h b/absl/memory/memory.h
index 88320e5..4719364 100644
--- a/absl/memory/memory.h
+++ b/absl/memory/memory.h
@@ -70,8 +70,8 @@
 // obtained from array-new expressions (even though that would compile!).
 template <typename T>
 std::unique_ptr<T> WrapUnique(T* ptr) {
-  static_assert(!std::is_array<T>::value, "array types are unsupported");
-  static_assert(std::is_object<T>::value, "non-object types are unsupported");
+  static_assert(!std::is_array_v<T>, "array types are unsupported");
+  static_assert(std::is_object_v<T>, "non-object types are unsupported");
   return std::unique_ptr<T>(ptr);
 }
 
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc
index 34bd212..8ed14c6 100644
--- a/absl/memory/memory_test.cc
+++ b/absl/memory/memory_test.cc
@@ -148,7 +148,7 @@
   ArrayWatch::allocs().clear();
 
   auto p = absl::make_unique_for_overwrite<ArrayWatch[]>(5);
-  static_assert(std::is_same<decltype(p), std::unique_ptr<ArrayWatch[]>>::value,
+  static_assert(std::is_same_v<decltype(p), std::unique_ptr<ArrayWatch[]>>,
                 "unexpected return type");
   EXPECT_THAT(ArrayWatch::allocs(), ElementsAre(5 * sizeof(ArrayWatch)));
 }
@@ -194,19 +194,19 @@
 
 TEST(RawPtrTest, Nullptr) {
   auto p = absl::RawPtr(nullptr);
-  EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
+  EXPECT_TRUE((std::is_same_v<std::nullptr_t, decltype(p)>));
   EXPECT_EQ(nullptr, p);
 }
 
 TEST(RawPtrTest, Null) {
   auto p = absl::RawPtr(nullptr);
-  EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
+  EXPECT_TRUE((std::is_same_v<std::nullptr_t, decltype(p)>));
   EXPECT_EQ(nullptr, p);
 }
 
 TEST(RawPtrTest, Zero) {
   auto p = absl::RawPtr(nullptr);
-  EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
+  EXPECT_TRUE((std::is_same_v<std::nullptr_t, decltype(p)>));
   EXPECT_EQ(nullptr, p);
 }
 
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index 50850d4..437580c 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -296,9 +296,9 @@
 template <typename Key>
 struct IsHashable<
     Key,
-    std::enable_if_t<std::is_convertible<
+    std::enable_if_t<std::is_convertible_v<
         decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())),
-        std::size_t>::value>> : std::true_type {};
+        std::size_t>>> : std::true_type {};
 
 struct AssertHashEnabledHelper {
  private:
@@ -316,19 +316,19 @@
     static_assert(IsHashable<Key>::value,
                   "std::hash<Key> does not provide a call operator");
     static_assert(
-        std::is_default_constructible<std::hash<Key>>::value,
+        std::is_default_constructible_v<std::hash<Key>>,
         "std::hash<Key> must be default constructible when it is enabled");
     static_assert(
-        std::is_copy_constructible<std::hash<Key>>::value,
+        std::is_copy_constructible_v<std::hash<Key>>,
         "std::hash<Key> must be copy constructible when it is enabled");
-    static_assert(std::is_copy_assignable<std::hash<Key>>::value,
+    static_assert(std::is_copy_assignable_v<std::hash<Key>>,
                   "std::hash<Key> must be copy assignable when it is enabled");
     // is_destructible is unchecked as it's implied by each of the
     // is_constructible checks.
     using ReturnType = decltype(GetReturnType<Key>(0));
-    static_assert(std::is_same<ReturnType, NAT>::value ||
-                      std::is_same<ReturnType, size_t>::value,
-                  "std::hash<Key> must return size_t");
+    static_assert(
+        std::is_same_v<ReturnType, NAT> || std::is_same_v<ReturnType, size_t>,
+        "std::hash<Key> must return size_t");
     return nullptr;
   }
 
@@ -481,10 +481,10 @@
 // TODO(b/325479096): Remove this case.
 template <class T>
 struct is_trivially_relocatable
-    : std::integral_constant<
-          bool, std::is_trivially_copyable<T>::value ||
-                    (__is_trivially_relocatable(T) &&
-                     std::is_trivially_move_assignable<T>::value)> {};
+    : std::integral_constant<bool,
+                             std::is_trivially_copyable_v<T> ||
+                                 (__is_trivially_relocatable(T) &&
+                                  std::is_trivially_move_assignable_v<T>)> {};
 #else
 // Otherwise we use a fallback that detects only those types we can feasibly
 // detect. Any type that is trivially copyable is by definition trivially
@@ -545,14 +545,13 @@
 // Do not specialize or use this directly. It's an implementation detail.
 template <typename T, typename = void>
 struct IsOwnerImpl : std::false_type {
-  static_assert(std::is_same<T, absl::remove_cvref_t<T>>::value,
+  static_assert(std::is_same_v<T, absl::remove_cvref_t<T>>,
                 "type must lack qualifiers");
 };
 
 template <typename T>
 struct IsOwnerImpl<
-    T,
-    std::enable_if_t<std::is_class<typename T::absl_internal_is_view>::value>>
+    T, std::enable_if_t<std::is_class_v<typename T::absl_internal_is_view>>>
     : std::negation<typename T::absl_internal_is_view> {};
 
 // A trait to determine whether a type is an owner.
@@ -588,14 +587,13 @@
 // Do not specialize or use this directly.
 template <typename T, typename = void>
 struct IsViewImpl : std::false_type {
-  static_assert(std::is_same<T, absl::remove_cvref_t<T>>::value,
+  static_assert(std::is_same_v<T, absl::remove_cvref_t<T>>,
                 "type must lack qualifiers");
 };
 
 template <typename T>
 struct IsViewImpl<
-    T,
-    std::enable_if_t<std::is_class<typename T::absl_internal_is_view>::value>>
+    T, std::enable_if_t<std::is_class_v<typename T::absl_internal_is_view>>>
     : T::absl_internal_is_view {};
 
 // A trait to determine whether a type is a view.
@@ -607,7 +605,7 @@
 // If it ever becomes possible to detect [[gsl::Pointer]], we should leverage
 // it: https://wg21.link/p1179
 template <typename T>
-struct IsView : std::integral_constant<bool, std::is_pointer<T>::value ||
+struct IsView : std::integral_constant<bool, std::is_pointer_v<T> ||
                                                  IsViewImpl<T>::value> {};
 
 // This allows incomplete types to be used for associative containers, and also
@@ -634,7 +632,7 @@
 // to a "view" (such as std::string_view) to be a lifetime-bound assignment.
 template <typename T, typename U>
 using IsLifetimeBoundAssignment = std::conjunction<
-    std::integral_constant<bool, !std::is_lvalue_reference<U>::value>,
+    std::integral_constant<bool, !std::is_lvalue_reference_v<U>>,
     IsOwner<absl::remove_cvref_t<U>>, IsView<absl::remove_cvref_t<T>>>;
 
 }  // namespace type_traits_internal
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 6d0085c..9734fc1 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -69,14 +69,12 @@
 struct StructC {};
 
 struct TypeWithBarFunction {
-  template <class T,
-            std::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0>
+  template <class T, std::enable_if_t<std::is_same_v<T&&, StructA&>, int> = 0>
   ReturnType bar(T&&, const StructB&, StructC&&) &&;  // NOLINT
 };
 
 struct TypeWithBarFunctionAndConvertibleReturnType {
-  template <class T,
-            std::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0>
+  template <class T, std::enable_if_t<std::is_same_v<T&&, StructA&>, int> = 0>
   ConvertibleToReturnType bar(T&&, const StructB&, StructC&&) &&;  // NOLINT
 };
 
@@ -110,31 +108,29 @@
 }
 
 TEST(TypeTraitsTest, TestRemoveCVRef) {
+  EXPECT_TRUE((std::is_same_v<typename absl::remove_cvref<int>::type, int>));
+  EXPECT_TRUE((std::is_same_v<typename absl::remove_cvref<int&>::type, int>));
+  EXPECT_TRUE((std::is_same_v<typename absl::remove_cvref<int&&>::type, int>));
   EXPECT_TRUE(
-      (std::is_same<typename absl::remove_cvref<int>::type, int>::value));
-  EXPECT_TRUE(
-      (std::is_same<typename absl::remove_cvref<int&>::type, int>::value));
-  EXPECT_TRUE(
-      (std::is_same<typename absl::remove_cvref<int&&>::type, int>::value));
-  EXPECT_TRUE((
-      std::is_same<typename absl::remove_cvref<const int&>::type, int>::value));
-  EXPECT_TRUE(
-      (std::is_same<typename absl::remove_cvref<int*>::type, int*>::value));
+      (std::is_same_v<typename absl::remove_cvref<const int&>::type, int>));
+  EXPECT_TRUE((std::is_same_v<typename absl::remove_cvref<int*>::type, int*>));
   // Does not remove const in this case.
-  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int*>::type,
-                            const int*>::value));
+  EXPECT_TRUE((std::is_same_v<typename absl::remove_cvref<const int*>::type,
+                              const int*>));
   EXPECT_TRUE(
-      (std::is_same<typename absl::remove_cvref<int[2]>::type, int[2]>::value));
-  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<int(&)[2]>::type,
-                            int[2]>::value));
-  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<int(&&)[2]>::type,
-                            int[2]>::value));
-  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int[2]>::type,
-                            int[2]>::value));
-  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int(&)[2]>::type,
-                            int[2]>::value));
-  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int(&&)[2]>::type,
-                            int[2]>::value));
+      (std::is_same_v<typename absl::remove_cvref<int[2]>::type, int[2]>));
+  EXPECT_TRUE(
+      (std::is_same_v<typename absl::remove_cvref<int (&)[2]>::type, int[2]>));
+  EXPECT_TRUE(
+      (std::is_same_v<typename absl::remove_cvref<int (&&)[2]>::type, int[2]>));
+  EXPECT_TRUE((
+      std::is_same_v<typename absl::remove_cvref<const int[2]>::type, int[2]>));
+  EXPECT_TRUE(
+      (std::is_same_v<typename absl::remove_cvref<const int (&)[2]>::type,
+                      int[2]>));
+  EXPECT_TRUE(
+      (std::is_same_v<typename absl::remove_cvref<const int (&&)[2]>::type,
+                      int[2]>));
 }
 
 TEST(TypeTraitsTest, TestTypeIdentity) {
@@ -159,20 +155,17 @@
 enum class TypeEnum { A, B, C, D };
 
 struct GetTypeT {
-  template <typename T,
-            std::enable_if_t<std::is_same<T, TypeA>::value, int> = 0>
+  template <typename T, std::enable_if_t<std::is_same_v<T, TypeA>, int> = 0>
   TypeEnum operator()(Wrap<T>) const {
     return TypeEnum::A;
   }
 
-  template <typename T,
-            std::enable_if_t<std::is_same<T, TypeB>::value, int> = 0>
+  template <typename T, std::enable_if_t<std::is_same_v<T, TypeB>, int> = 0>
   TypeEnum operator()(Wrap<T>) const {
     return TypeEnum::B;
   }
 
-  template <typename T,
-            std::enable_if_t<std::is_same<T, TypeC>::value, int> = 0>
+  template <typename T, std::enable_if_t<std::is_same_v<T, TypeC>, int> = 0>
   TypeEnum operator()(Wrap<T>) const {
     return TypeEnum::C;
   }
diff --git a/absl/numeric/bits.h b/absl/numeric/bits.h
index 4d369e3..47e9901 100644
--- a/absl/numeric/bits.h
+++ b/absl/numeric/bits.h
@@ -68,13 +68,13 @@
 
 // Rotating functions
 template <class T>
-[[nodiscard]] constexpr std::enable_if_t<std::is_unsigned<T>::value, T> rotl(
+[[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<T>, T> rotl(
     T x, int s) noexcept {
   return numeric_internal::RotateLeft(x, s);
 }
 
 template <class T>
-[[nodiscard]] constexpr std::enable_if_t<std::is_unsigned<T>::value, T> rotr(
+[[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<T>, T> rotr(
     T x, int s) noexcept {
   return numeric_internal::RotateRight(x, s);
 }
@@ -101,38 +101,34 @@
 // not be marked as constexpr due to constraints of the compiler/available
 // intrinsics.
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    int>
+ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>, int>
 countl_zero(T x) noexcept {
   return numeric_internal::CountLeadingZeroes(x);
 }
 
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    int>
+ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>, int>
 countl_one(T x) noexcept {
   // Avoid integer promotion to a wider type
   return countl_zero(static_cast<T>(~x));
 }
 
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CTZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    int>
+ABSL_INTERNAL_CONSTEXPR_CTZ inline std::enable_if_t<std::is_unsigned_v<T>, int>
 countr_zero(T x) noexcept {
   return numeric_internal::CountTrailingZeroes(x);
 }
 
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CTZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    int>
+ABSL_INTERNAL_CONSTEXPR_CTZ inline std::enable_if_t<std::is_unsigned_v<T>, int>
 countr_one(T x) noexcept {
   // Avoid integer promotion to a wider type
   return countr_zero(static_cast<T>(~x));
 }
 
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline std::enable_if_t<
-    std::is_unsigned<T>::value, int>
+ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline std::enable_if_t<std::is_unsigned_v<T>,
+                                                         int>
 popcount(T x) noexcept {
   return numeric_internal::Popcount(x);
 }
@@ -150,16 +146,15 @@
 
 // Returns: true if x is an integral power of two; false otherwise.
 template <class T>
-constexpr inline std::enable_if_t<std::is_unsigned<T>::value, bool>
-has_single_bit(T x) noexcept {
+constexpr inline std::enable_if_t<std::is_unsigned_v<T>, bool> has_single_bit(
+    T x) noexcept {
   return x != 0 && (x & (x - 1)) == 0;
 }
 
 // Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any
 // fractional part discarded.
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    int>
+ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>, int>
 bit_width(T x) noexcept {
   return std::numeric_limits<T>::digits - countl_zero(x);
 }
@@ -167,8 +162,7 @@
 // Returns: If x == 0, 0; otherwise the maximal value y such that
 // has_single_bit(y) is true and y <= x.
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    T>
+ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>, T>
 bit_floor(T x) noexcept {
   return x == 0 ? 0 : T{1} << (bit_width(x) - 1);
 }
@@ -177,8 +171,7 @@
 //
 // Preconditions: N is representable as a value of type T.
 template <class T>
-ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned<T>::value,
-                                                    T>
+ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>, T>
 bit_ceil(T x) {
   // If T is narrower than unsigned, T{1} << bit_width will be promoted.  We
   // want to force it to wraparound so that bit_ceil of an invalid value are not
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc
index 281bf12..9987c15 100644
--- a/absl/numeric/int128.cc
+++ b/absl/numeric/int128.cc
@@ -90,7 +90,7 @@
 
 template <typename T>
 uint128 MakeUint128FromFloat(T v) {
-  static_assert(std::is_floating_point<T>::value, "");
+  static_assert(std::is_floating_point_v<T>, "");
 
   // Rounding behavior is towards zero, same as for built-in types.
 
diff --git a/absl/numeric/int128_benchmark.cc b/absl/numeric/int128_benchmark.cc
index 9e1d78d..3fee6be 100644
--- a/absl/numeric/int128_benchmark.cc
+++ b/absl/numeric/int128_benchmark.cc
@@ -146,7 +146,7 @@
 // Some implementations of <random> do not support __int128 when it is
 // available, so we make our own uniform_int_distribution-like type.
 template <typename T, typename H = std::conditional_t<
-                          std::is_same<T, __int128>::value, int64_t, uint64_t>>
+                          std::is_same_v<T, __int128>, int64_t, uint64_t>>
 class UniformIntDistribution128 {
  public:
   // NOLINTNEXTLINE: mimicking std::uniform_int_distribution API
@@ -160,7 +160,7 @@
 };
 
 template <typename T, typename H = std::conditional_t<
-                          std::is_same<T, __int128>::value, int64_t, uint64_t>>
+                          std::is_same_v<T, __int128>, int64_t, uint64_t>>
 std::vector<std::pair<T, T>> GetRandomIntrinsic128SampleUniformDivisor() {
   std::vector<std::pair<T, T>> values;
   absl::InsecureBitGen random;
@@ -200,7 +200,7 @@
 BENCHMARK_TEMPLATE(BM_RemainderIntrinsic128UniformDivisor, __int128);
 
 template <typename T, typename H = std::conditional_t<
-                          std::is_same<T, __int128>::value, int64_t, uint64_t>>
+                          std::is_same_v<T, __int128>, int64_t, uint64_t>>
 std::vector<std::pair<T, H>> GetRandomIntrinsic128SampleSmallDivisor() {
   std::vector<std::pair<T, H>> values;
   absl::InsecureBitGen random;
diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc
index 336db78..35eacae 100644
--- a/absl/numeric/int128_test.cc
+++ b/absl/numeric/int128_test.cc
@@ -53,22 +53,22 @@
 TYPED_TEST_SUITE(Uint128IntegerTraitsTest, IntegerTypes);
 
 TYPED_TEST(Uint128IntegerTraitsTest, ConstructAssignTest) {
-  static_assert(std::is_constructible<absl::uint128, TypeParam>::value,
+  static_assert(std::is_constructible_v<absl::uint128, TypeParam>,
                 "absl::uint128 must be constructible from TypeParam");
-  static_assert(std::is_assignable<absl::uint128&, TypeParam>::value,
+  static_assert(std::is_assignable_v<absl::uint128&, TypeParam>,
                 "absl::uint128 must be assignable from TypeParam");
-  static_assert(!std::is_assignable<TypeParam&, absl::uint128>::value,
+  static_assert(!std::is_assignable_v<TypeParam&, absl::uint128>,
                 "TypeParam must not be assignable from absl::uint128");
 }
 
 TYPED_TEST_SUITE(Uint128FloatTraitsTest, FloatingPointTypes);
 
 TYPED_TEST(Uint128FloatTraitsTest, ConstructAssignTest) {
-  static_assert(std::is_constructible<absl::uint128, TypeParam>::value,
+  static_assert(std::is_constructible_v<absl::uint128, TypeParam>,
                 "absl::uint128 must be constructible from TypeParam");
-  static_assert(!std::is_assignable<absl::uint128&, TypeParam>::value,
+  static_assert(!std::is_assignable_v<absl::uint128&, TypeParam>,
                 "absl::uint128 must not be assignable from TypeParam");
-  static_assert(!std::is_assignable<TypeParam&, absl::uint128>::value,
+  static_assert(!std::is_assignable_v<TypeParam&, absl::uint128>,
                 "TypeParam must not be assignable from absl::uint128");
 }
 
@@ -76,29 +76,27 @@
 // These type traits done separately as TYPED_TEST requires typeinfo, and not
 // all platforms have this for __int128 even though they define the type.
 TEST(Uint128, IntrinsicTypeTraitsTest) {
-  static_assert(std::is_constructible<absl::uint128, __int128>::value,
+  static_assert(std::is_constructible_v<absl::uint128, __int128>,
                 "absl::uint128 must be constructible from __int128");
-  static_assert(std::is_assignable<absl::uint128&, __int128>::value,
+  static_assert(std::is_assignable_v<absl::uint128&, __int128>,
                 "absl::uint128 must be assignable from __int128");
-  static_assert(!std::is_assignable<__int128&, absl::uint128>::value,
+  static_assert(!std::is_assignable_v<__int128&, absl::uint128>,
                 "__int128 must not be assignable from absl::uint128");
 
-  static_assert(std::is_constructible<absl::uint128, unsigned __int128>::value,
+  static_assert(std::is_constructible_v<absl::uint128, unsigned __int128>,
                 "absl::uint128 must be constructible from unsigned __int128");
-  static_assert(std::is_assignable<absl::uint128&, unsigned __int128>::value,
+  static_assert(std::is_assignable_v<absl::uint128&, unsigned __int128>,
                 "absl::uint128 must be assignable from unsigned __int128");
-  static_assert(!std::is_assignable<unsigned __int128&, absl::uint128>::value,
+  static_assert(!std::is_assignable_v<unsigned __int128&, absl::uint128>,
                 "unsigned __int128 must not be assignable from absl::uint128");
 }
 #endif  // ABSL_HAVE_INTRINSIC_INT128
 
 TEST(Uint128, TrivialTraitsTest) {
-  static_assert(std::is_trivially_default_constructible<absl::uint128>::value,
-                "");
-  static_assert(std::is_trivially_copy_constructible<absl::uint128>::value,
-                "");
-  static_assert(std::is_trivially_copy_assignable<absl::uint128>::value, "");
-  static_assert(std::is_trivially_destructible<absl::uint128>::value, "");
+  static_assert(std::is_trivially_default_constructible_v<absl::uint128>, "");
+  static_assert(std::is_trivially_copy_constructible_v<absl::uint128>, "");
+  static_assert(std::is_trivially_copy_assignable_v<absl::uint128>, "");
+  static_assert(std::is_trivially_destructible_v<absl::uint128>, "");
 }
 
 TEST(Uint128, AllTests) {
@@ -576,11 +574,11 @@
 TYPED_TEST_SUITE(Int128IntegerTraitsTest, IntegerTypes);
 
 TYPED_TEST(Int128IntegerTraitsTest, ConstructAssignTest) {
-  static_assert(std::is_constructible<absl::int128, TypeParam>::value,
+  static_assert(std::is_constructible_v<absl::int128, TypeParam>,
                 "absl::int128 must be constructible from TypeParam");
-  static_assert(std::is_assignable<absl::int128&, TypeParam>::value,
+  static_assert(std::is_assignable_v<absl::int128&, TypeParam>,
                 "absl::int128 must be assignable from TypeParam");
-  static_assert(!std::is_assignable<TypeParam&, absl::int128>::value,
+  static_assert(!std::is_assignable_v<TypeParam&, absl::int128>,
                 "TypeParam must not be assignable from absl::int128");
 }
 
@@ -590,11 +588,11 @@
 TYPED_TEST_SUITE(Int128FloatTraitsTest, FloatingPointTypes);
 
 TYPED_TEST(Int128FloatTraitsTest, ConstructAssignTest) {
-  static_assert(std::is_constructible<absl::int128, TypeParam>::value,
+  static_assert(std::is_constructible_v<absl::int128, TypeParam>,
                 "absl::int128 must be constructible from TypeParam");
-  static_assert(!std::is_assignable<absl::int128&, TypeParam>::value,
+  static_assert(!std::is_assignable_v<absl::int128&, TypeParam>,
                 "absl::int128 must not be assignable from TypeParam");
-  static_assert(!std::is_assignable<TypeParam&, absl::int128>::value,
+  static_assert(!std::is_assignable_v<TypeParam&, absl::int128>,
                 "TypeParam must not be assignable from absl::int128");
 }
 
@@ -602,28 +600,27 @@
 // These type traits done separately as TYPED_TEST requires typeinfo, and not
 // all platforms have this for __int128 even though they define the type.
 TEST(Int128, IntrinsicTypeTraitsTest) {
-  static_assert(std::is_constructible<absl::int128, __int128>::value,
+  static_assert(std::is_constructible_v<absl::int128, __int128>,
                 "absl::int128 must be constructible from __int128");
-  static_assert(std::is_assignable<absl::int128&, __int128>::value,
+  static_assert(std::is_assignable_v<absl::int128&, __int128>,
                 "absl::int128 must be assignable from __int128");
-  static_assert(!std::is_assignable<__int128&, absl::int128>::value,
+  static_assert(!std::is_assignable_v<__int128&, absl::int128>,
                 "__int128 must not be assignable from absl::int128");
 
-  static_assert(std::is_constructible<absl::int128, unsigned __int128>::value,
+  static_assert(std::is_constructible_v<absl::int128, unsigned __int128>,
                 "absl::int128 must be constructible from unsigned __int128");
-  static_assert(!std::is_assignable<absl::int128&, unsigned __int128>::value,
+  static_assert(!std::is_assignable_v<absl::int128&, unsigned __int128>,
                 "absl::int128 must be assignable from unsigned __int128");
-  static_assert(!std::is_assignable<unsigned __int128&, absl::int128>::value,
+  static_assert(!std::is_assignable_v<unsigned __int128&, absl::int128>,
                 "unsigned __int128 must not be assignable from absl::int128");
 }
 #endif  // ABSL_HAVE_INTRINSIC_INT128
 
 TEST(Int128, TrivialTraitsTest) {
-  static_assert(std::is_trivially_default_constructible<absl::int128>::value,
-                "");
-  static_assert(std::is_trivially_copy_constructible<absl::int128>::value, "");
-  static_assert(std::is_trivially_copy_assignable<absl::int128>::value, "");
-  static_assert(std::is_trivially_destructible<absl::int128>::value, "");
+  static_assert(std::is_trivially_default_constructible_v<absl::int128>, "");
+  static_assert(std::is_trivially_copy_constructible_v<absl::int128>, "");
+  static_assert(std::is_trivially_copy_assignable_v<absl::int128>, "");
+  static_assert(std::is_trivially_destructible_v<absl::int128>, "");
 }
 
 TEST(Int128, BoolConversionTest) {
diff --git a/absl/numeric/internal/bits.h b/absl/numeric/internal/bits.h
index ca2d277..82c577d 100644
--- a/absl/numeric/internal/bits.h
+++ b/absl/numeric/internal/bits.h
@@ -73,7 +73,7 @@
 template <class T>
 [[nodiscard]] ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateRight(
     T x, int s) noexcept {
-  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+  static_assert(std::is_unsigned_v<T>, "T must be unsigned");
   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                 "T must have a power-of-2 size");
 
@@ -104,7 +104,7 @@
 template <class T>
 [[nodiscard]] ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft(
     T x, int s) noexcept {
-  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+  static_assert(std::is_unsigned_v<T>, "T must be unsigned");
   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                 "T must have a power-of-2 size");
 
@@ -150,7 +150,7 @@
 template <class T>
 ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
 Popcount(T x) noexcept {
-  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+  static_assert(std::is_unsigned_v<T>, "T must be unsigned");
   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                 "T must have a power-of-2 size");
   static_assert(sizeof(x) <= sizeof(uint64_t), "T is too large");
@@ -266,7 +266,7 @@
 template <typename T>
 ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
 CountLeadingZeroes(T x) {
-  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+  static_assert(std::is_unsigned_v<T>, "T must be unsigned");
   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                 "T must have a power-of-2 size");
   static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
@@ -351,7 +351,7 @@
 template <class T>
 ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
 CountTrailingZeroes(T x) noexcept {
-  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+  static_assert(std::is_unsigned_v<T>, "T must be unsigned");
   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                 "T must have a power-of-2 size");
   static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
@@ -368,15 +368,17 @@
 // want to force it to wraparound so that bit_ceil of an invalid value are not
 // core constant expressions.
 template <class T>
-ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline std::
-    enable_if_t<std::is_unsigned<T>::value, T>
+ABSL_ATTRIBUTE_ALWAYS_INLINE
+    ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>,
+                                                        T>
     BitCeilPromotionHelper(T x, T promotion) {
   return (T{1} << (x + promotion)) >> promotion;
 }
 
 template <class T>
-ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline std::
-    enable_if_t<std::is_unsigned<T>::value, T>
+ABSL_ATTRIBUTE_ALWAYS_INLINE
+    ABSL_INTERNAL_CONSTEXPR_CLZ inline std::enable_if_t<std::is_unsigned_v<T>,
+                                                        T>
     BitCeilNonPowerOf2(T x) {
   // If T is narrower than unsigned, it undergoes promotion to unsigned when we
   // shift.  We calculate the number of bits added by the wider type.
diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h
index bedeca6..15311df 100644
--- a/absl/random/beta_distribution.h
+++ b/absl/random/beta_distribution.h
@@ -196,7 +196,7 @@
     // Whether alpha_ != a_, i.e. true iff alpha_ > beta_.
     bool inverted_{};
 
-    static_assert(std::is_floating_point<RealType>::value,
+    static_assert(std::is_floating_point_v<RealType>,
                   "Class-template absl::beta_distribution<> must be "
                   "parameterized using a floating-point type.");
   };
@@ -282,7 +282,7 @@
   using random_internal::GeneratePositiveTag;
   using random_internal::GenerateRealFromBits;
   using real_type =
-      std::conditional_t<std::is_same<RealType, float>::value, float, double>;
+      std::conditional_t<std::is_same_v<RealType, float>, float, double>;
 
   // Based on Joehnk, M. D. Erzeugung von betaverteilten und gammaverteilten
   // Zufallszahlen. Metrika 8.1 (1964): 5-15.
@@ -297,7 +297,7 @@
 
     // Direct method. std::pow is slow for float, so rely on the optimizer to
     // remove the std::pow() path for that case.
-    if (!std::is_same<float, result_type>::value) {
+    if (!std::is_same_v<float, result_type>) {
       x = std::pow(u, p.a_);
       y = std::pow(v, p.b_);
       z = x + y;
@@ -340,7 +340,7 @@
   using random_internal::GeneratePositiveTag;
   using random_internal::GenerateRealFromBits;
   using real_type =
-      std::conditional_t<std::is_same<RealType, float>::value, float, double>;
+      std::conditional_t<std::is_same_v<RealType, float>, float, double>;
 
   // Based on Cheng, Russell CH. Generating beta variates with nonintegral
   // shape parameters. Communications of the ACM 21.4 (1978): 317-322.
diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h
index bcbaf6a..df8675b 100644
--- a/absl/random/bit_gen_ref.h
+++ b/absl/random/bit_gen_ref.h
@@ -84,8 +84,8 @@
 
   template <typename URBGRef, typename URBG = absl::remove_cvref_t<URBGRef>,
             typename std::enable_if_t<
-                (!std::is_same<URBG, BitGenRef>::value &&
-                 !std::is_base_of<BitGenRef, URBG>::value &&
+                (!std::is_same_v<URBG, BitGenRef> &&
+                 !std::is_base_of_v<BitGenRef, URBG> &&
                  !HasConversionOperator<URBG>::value &&
                  random_internal::is_urbg<URBG>::value &&
                  !RandomMockingAccess::HasInvokeMock<URBG>::value)>* = nullptr>
@@ -96,8 +96,8 @@
 
   template <typename URBGRef, typename URBG = absl::remove_cvref_t<URBGRef>,
             typename std::enable_if_t<
-                (!std::is_same<URBG, BitGenRef>::value &&
-                 !std::is_base_of<BitGenRef, URBG>::value &&
+                (!std::is_same_v<URBG, BitGenRef> &&
+                 !std::is_base_of_v<BitGenRef, URBG> &&
                  !HasConversionOperator<URBG>::value &&
                  random_internal::is_urbg<URBG>::value &&
                  RandomMockingAccess::HasInvokeMock<URBG>::value)>* = nullptr>
diff --git a/absl/random/bit_gen_ref_test.cc b/absl/random/bit_gen_ref_test.cc
index d04ac3a..ae5c1db 100644
--- a/absl/random/bit_gen_ref_test.cc
+++ b/absl/random/bit_gen_ref_test.cc
@@ -125,7 +125,7 @@
 
 TEST(BitGenRefTest, IsConvertibleTest) {
   // Verify that MinStdRandBitGen is convertible to absl::BitGenRef.
-  EXPECT_TRUE((std::is_convertible<MinStdRand, absl::BitGenRef>::value));
+  EXPECT_TRUE((std::is_convertible_v<MinStdRand, absl::BitGenRef>));
 
   // Explicit construction should trigger the conversion.
   {
diff --git a/absl/random/discrete_distribution.h b/absl/random/discrete_distribution.h
index 854634d..35d42c8 100644
--- a/absl/random/discrete_distribution.h
+++ b/absl/random/discrete_distribution.h
@@ -105,7 +105,7 @@
     std::vector<double> p_;                     // normalized probabilities
     std::vector<std::pair<double, size_t>> q_;  // (acceptance, alternate) pairs
 
-    static_assert(std::is_integral<result_type>::value,
+    static_assert(std::is_integral_v<result_type>,
                   "Class-template absl::discrete_distribution<> must be "
                   "parameterized using an integral type.");
   };
diff --git a/absl/random/distributions.h b/absl/random/distributions.h
index 01dc978..cfe731e 100644
--- a/absl/random/distributions.h
+++ b/absl/random/distributions.h
@@ -117,7 +117,7 @@
 //   auto x = absl::Uniform<float>(bitgen, 0, 1);
 //
 template <typename R = void, typename TagType, typename URBG>
-typename std::enable_if_t<!std::is_same<R, void>::value, R>  //
+typename std::enable_if_t<!std::is_same_v<R, void>, R>  //
 Uniform(TagType tag,
         URBG&& urbg,  // NOLINT(runtime/references)
         R lo, R hi) {
@@ -137,7 +137,7 @@
 // Overload of `Uniform()` using the default closed-open interval of [lo, hi),
 // and returning values of type `T`
 template <typename R = void, typename URBG>
-typename std::enable_if_t<!std::is_same<R, void>::value, R>  //
+typename std::enable_if_t<!std::is_same_v<R, void>, R>  //
 Uniform(URBG&& urbg,  // NOLINT(runtime/references)
         R lo, R hi) {
   using gen_t = std::decay_t<URBG>;
@@ -159,8 +159,8 @@
 // correctly from the passed types.
 template <typename R = void, typename TagType, typename URBG, typename A,
           typename B>
-typename std::enable_if_t<std::is_same<R, void>::value,
-                           random_internal::uniform_inferred_return_t<A, B>>
+typename std::enable_if_t<std::is_same_v<R, void>,
+                          random_internal::uniform_inferred_return_t<A, B>>
 Uniform(TagType tag,
         URBG&& urbg,  // NOLINT(runtime/references)
         A lo, B hi) {
@@ -183,8 +183,8 @@
 // default closed-open interval of [lo, hi). Note that a compile-error will
 // result if the return type cannot be deduced correctly from the passed types.
 template <typename R = void, typename URBG, typename A, typename B>
-typename std::enable_if_t<std::is_same<R, void>::value,
-                           random_internal::uniform_inferred_return_t<A, B>>
+typename std::enable_if_t<std::is_same_v<R, void>,
+                          random_internal::uniform_inferred_return_t<A, B>>
 Uniform(URBG&& urbg,  // NOLINT(runtime/references)
         A lo, B hi) {
   using gen_t = std::decay_t<URBG>;
@@ -266,7 +266,7 @@
 RealType Beta(URBG&& urbg,  // NOLINT(runtime/references)
               RealType alpha, RealType beta) {
   static_assert(
-      std::is_floating_point<RealType>::value,
+      std::is_floating_point_v<RealType>,
       "Template-argument 'RealType' must be a floating-point type, in "
       "absl::Beta<RealType, URBG>(...)");
 
@@ -298,7 +298,7 @@
 RealType Exponential(URBG&& urbg,  // NOLINT(runtime/references)
                      RealType lambda = 1) {
   static_assert(
-      std::is_floating_point<RealType>::value,
+      std::is_floating_point_v<RealType>,
       "Template-argument 'RealType' must be a floating-point type, in "
       "absl::Exponential<RealType, URBG>(...)");
 
@@ -329,7 +329,7 @@
 RealType Gaussian(URBG&& urbg,  // NOLINT(runtime/references)
                   RealType mean = 0, RealType stddev = 1) {
   static_assert(
-      std::is_floating_point<RealType>::value,
+      std::is_floating_point_v<RealType>,
       "Template-argument 'RealType' must be a floating-point type, in "
       "absl::Gaussian<RealType, URBG>(...)");
 
diff --git a/absl/random/distributions_test.cc b/absl/random/distributions_test.cc
index 1fa3345..16c9e2e 100644
--- a/absl/random/distributions_test.cc
+++ b/absl/random/distributions_test.cc
@@ -80,18 +80,16 @@
 template <typename A, typename B, typename Expect>
 void CheckArgsInferType() {
   static_assert(
-      std::conjunction<
+      std::conjunction_v<
           std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
-          std::is_same<Expect,
-                       decltype(InferredUniformReturnT<B, A>(0))>>::value,
+          std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>,
       "");
   static_assert(
-      std::conjunction<
+      std::conjunction_v<
           std::is_same<Expect, decltype(InferredTaggedUniformReturnT<
                                         absl::IntervalOpenOpenTag, A, B>(0))>,
-          std::is_same<Expect,
-                       decltype(InferredTaggedUniformReturnT<
-                                absl::IntervalOpenOpenTag, B, A>(0))>>::value,
+          std::is_same<Expect, decltype(InferredTaggedUniformReturnT<
+                                        absl::IntervalOpenOpenTag, B, A>(0))>>,
       "");
 }
 
@@ -121,20 +119,20 @@
 template <typename A, typename B, typename Expect>
 void CheckArgsReturnExpectedType() {
   static_assert(
-      std::conjunction<
+      std::conjunction_v<
           std::is_same<Expect,
                        decltype(ExplicitUniformReturnT<A, B, Expect>(0))>,
-          std::is_same<Expect, decltype(ExplicitUniformReturnT<B, A, Expect>(
-                                   0))>>::value,
+          std::is_same<Expect,
+                       decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>,
       "");
   static_assert(
-      std::conjunction<
+      std::conjunction_v<
           std::is_same<Expect,
                        decltype(ExplicitTaggedUniformReturnT<
                                 absl::IntervalOpenOpenTag, A, B, Expect>(0))>,
-          std::is_same<Expect, decltype(ExplicitTaggedUniformReturnT<
-                                        absl::IntervalOpenOpenTag, B, A,
-                                        Expect>(0))>>::value,
+          std::is_same<Expect,
+                       decltype(ExplicitTaggedUniformReturnT<
+                                absl::IntervalOpenOpenTag, B, A, Expect>(0))>>,
       "");
 }
 
diff --git a/absl/random/exponential_distribution.h b/absl/random/exponential_distribution.h
index f0267b2..67ab866 100644
--- a/absl/random/exponential_distribution.h
+++ b/absl/random/exponential_distribution.h
@@ -64,7 +64,7 @@
     result_type neg_inv_lambda_;
 
     static_assert(
-        std::is_floating_point<RealType>::value,
+        std::is_floating_point_v<RealType>,
         "Class-template absl::exponential_distribution<> must be parameterized "
         "using a floating-point type.");
   };
@@ -124,7 +124,7 @@
   using random_internal::GenerateNegativeTag;
   using random_internal::GenerateRealFromBits;
   using real_type =
-      std::conditional_t<std::is_same<RealType, float>::value, float, double>;
+      std::conditional_t<std::is_same_v<RealType, float>, float, double>;
 
   const result_type u = GenerateRealFromBits<real_type, GenerateNegativeTag,
                                              false>(fast_u64_(g));  // U(-1, 0)
diff --git a/absl/random/exponential_distribution_test.cc b/absl/random/exponential_distribution_test.cc
index dd51fc3..71be99e 100644
--- a/absl/random/exponential_distribution_test.cc
+++ b/absl/random/exponential_distribution_test.cc
@@ -114,7 +114,7 @@
       if (sample > sample_max) sample_max = sample;
       if (sample < sample_min) sample_min = sample;
     }
-    if (!std::is_same<TypeParam, long double>::value) {
+    if (!std::is_same_v<TypeParam, long double>) {
       LOG(INFO) << "Range {" << lambda << "}: " << sample_min << ", "
                 << sample_max << ", lambda=" << lambda;
     }
diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h
index eb75bfe..d14de0b 100644
--- a/absl/random/gaussian_distribution.h
+++ b/absl/random/gaussian_distribution.h
@@ -116,7 +116,7 @@
     result_type stddev_;
 
     static_assert(
-        std::is_floating_point<RealType>::value,
+        std::is_floating_point_v<RealType>,
         "Class-template absl::gaussian_distribution<> must be parameterized "
         "using a floating-point type.");
   };
diff --git a/absl/random/gaussian_distribution_test.cc b/absl/random/gaussian_distribution_test.cc
index 091882e..4d076bb 100644
--- a/absl/random/gaussian_distribution_test.cc
+++ b/absl/random/gaussian_distribution_test.cc
@@ -115,7 +115,7 @@
           EXPECT_GE(sample, before.min()) << before;
           EXPECT_LE(sample, before.max()) << before;
         }
-        if (!std::is_same<TypeParam, long double>::value) {
+        if (!std::is_same_v<TypeParam, long double>) {
           LOG(INFO) << "Range{" << mean << ", " << stddev << "}: " << sample_min
                     << ", " << sample_max;
         }
diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h
index 1416aba..03ace5a 100644
--- a/absl/random/internal/distribution_caller.h
+++ b/absl/random/internal/distribution_caller.h
@@ -36,7 +36,7 @@
 // to intercept such calls.
 template <typename URBG>
 struct DistributionCaller {
-  static_assert(!std::is_pointer<URBG>::value,
+  static_assert(!std::is_pointer_v<URBG>,
                 "You must pass a reference, not a pointer.");
 
   using RandomMockingAccess = ::absl::RandomMockingAccess;
diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h
index fc35240..e016946 100644
--- a/absl/random/internal/generate_real.h
+++ b/absl/random/internal/generate_real.h
@@ -69,12 +69,11 @@
           bool IncludeZero = true>
 inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
   using real_type = RealType;
-  using uint_type = std::conditional_t<std::is_same<real_type, float>::value,
-                                        uint32_t, uint64_t>;
+  using uint_type =
+      std::conditional_t<std::is_same_v<real_type, float>, uint32_t, uint64_t>;
 
   static_assert(
-      (std::is_same<double, real_type>::value ||
-       std::is_same<float, real_type>::value),
+      (std::is_same_v<double, real_type> || std::is_same_v<float, real_type>),
       "GenerateRealFromBits must be parameterized by either float or double.");
 
   static_assert(sizeof(uint_type) == sizeof(real_type),
@@ -84,9 +83,9 @@
                  std::numeric_limits<real_type>::radix == 2),
                 "RealType representation is not IEEE 754 binary.");
 
-  static_assert((std::is_same<SignedTag, GeneratePositiveTag>::value ||
-                 std::is_same<SignedTag, GenerateNegativeTag>::value ||
-                 std::is_same<SignedTag, GenerateSignedTag>::value),
+  static_assert((std::is_same_v<SignedTag, GeneratePositiveTag> ||
+                 std::is_same_v<SignedTag, GenerateNegativeTag> ||
+                 std::is_same_v<SignedTag, GenerateSignedTag>),
                 "");
 
   static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
@@ -98,14 +97,14 @@
   // Determine the sign bit.
   // Depending on the SignedTag, this may use the left-most bit
   // or it may be a constant value.
-  uint_type sign = std::is_same<SignedTag, GenerateNegativeTag>::value
+  uint_type sign = std::is_same_v<SignedTag, GenerateNegativeTag>
                        ? (static_cast<uint_type>(1) << (kUintBits - 1))
                        : 0;
-  if (std::is_same<SignedTag, GenerateSignedTag>::value) {
-    if (std::is_same<uint_type, uint64_t>::value) {
+  if (std::is_same_v<SignedTag, GenerateSignedTag>) {
+    if (std::is_same_v<uint_type, uint64_t>) {
       sign = bits & uint64_t{0x8000000000000000};
     }
-    if (std::is_same<uint_type, uint32_t>::value) {
+    if (std::is_same_v<uint_type, uint32_t>) {
       const uint64_t tmp = bits & uint64_t{0x8000000000000000};
       sign = static_cast<uint32_t>(tmp >> 32);
     }
diff --git a/absl/random/internal/iostream_state_saver.h b/absl/random/internal/iostream_state_saver.h
index 5556b67..fcd45a1 100644
--- a/absl/random/internal/iostream_state_saver.h
+++ b/absl/random/internal/iostream_state_saver.h
@@ -95,8 +95,8 @@
 }
 
 template <typename T>
-typename std::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
-                           null_state_saver<T>>
+typename std::enable_if_t<!std::is_base_of_v<std::ios_base, T>,
+                          null_state_saver<T>>
 make_ostream_state_saver(T& is,  // NOLINT(runtime/references)
                          std::ios_base::fmtflags flags = std::ios_base::dec) {
   using result_type = null_state_saver<T>;
@@ -159,8 +159,8 @@
 }
 
 template <typename T>
-typename std::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
-                           null_state_saver<T>>
+typename std::enable_if_t<!std::is_base_of_v<std::ios_base, T>,
+                          null_state_saver<T>>
 make_istream_state_saver(T& is,  // NOLINT(runtime/references)
                          std::ios_base::fmtflags flags = std::ios_base::dec) {
   using result_type = null_state_saver<T>;
@@ -223,7 +223,7 @@
 
 template <typename FloatType, typename IStream>
 inline FloatType read_floating_point(IStream& is) {
-  static_assert(std::is_floating_point<FloatType>::value, "");
+  static_assert(std::is_floating_point_v<FloatType>, "");
   FloatType dest;
   is >> dest;
   // Parsing a double value may report a subnormal value as an error
diff --git a/absl/random/internal/iostream_state_saver_test.cc b/absl/random/internal/iostream_state_saver_test.cc
index 3c1db21..a9bf5fc 100644
--- a/absl/random/internal/iostream_state_saver_test.cc
+++ b/absl/random/internal/iostream_state_saver_test.cc
@@ -30,7 +30,7 @@
 using absl::random_internal::stream_precision_helper;
 
 template <typename T>
-typename std::enable_if_t<std::is_integral<T>::value, T>  //
+typename std::enable_if_t<std::is_integral_v<T>, T>  //
 StreamRoundTrip(T t) {
   std::stringstream ss;
   {
@@ -54,7 +54,7 @@
 }
 
 template <typename T>
-typename std::enable_if_t<std::is_floating_point<T>::value, T>  //
+typename std::enable_if_t<std::is_floating_point_v<T>, T>  //
 StreamRoundTrip(T t) {
   std::stringstream ss;
   {
diff --git a/absl/random/internal/mock_overload_set.h b/absl/random/internal/mock_overload_set.h
index a09f035..a3b15ee 100644
--- a/absl/random/internal/mock_overload_set.h
+++ b/absl/random/internal/mock_overload_set.h
@@ -42,7 +42,7 @@
 // The underlying KeyT must match the KeyT constructed by DistributionCaller.
 template <typename DistrT, typename ValidatorT, typename Ret, typename... Args>
 struct MockSingleOverload<DistrT, ValidatorT, Ret(MockingBitGen&, Args...)> {
-  static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
+  static_assert(std::is_same_v<typename DistrT::result_type, Ret>,
                 "Overload signature must have return type matching the "
                 "distribution result_type.");
   using KeyT = Ret(DistrT, std::tuple<Args...>);
@@ -51,7 +51,7 @@
   auto gmock_Call(MockURBG& gen, const ::testing::Matcher<Args>&... matchers)
       -> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT())
                       .gmock_Call(matchers...)) {
-    static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+    static_assert(std::is_base_of_v<MockingBitGen, MockURBG>,
                   "Mocking requires an absl::MockingBitGen");
     return MockHelpers::MockFor<KeyT>(gen, ValidatorT())
         .gmock_Call(matchers...);
@@ -62,7 +62,7 @@
           typename... Args>
 struct MockSingleOverload<DistrT, ValidatorT,
                           Ret(Arg, MockingBitGen&, Args...)> {
-  static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
+  static_assert(std::is_same_v<typename DistrT::result_type, Ret>,
                 "Overload signature must have return type matching the "
                 "distribution result_type.");
   using KeyT = Ret(DistrT, std::tuple<Arg, Args...>);
@@ -72,7 +72,7 @@
                   const ::testing::Matcher<Args>&... matchers)
       -> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT())
                       .gmock_Call(matcher, matchers...)) {
-    static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+    static_assert(std::is_base_of_v<MockingBitGen, MockURBG>,
                   "Mocking requires an absl::MockingBitGen");
     return MockHelpers::MockFor<KeyT>(gen, ValidatorT())
         .gmock_Call(matcher, matchers...);
diff --git a/absl/random/internal/nonsecure_base.h b/absl/random/internal/nonsecure_base.h
index 903dbd9..d1442f8 100644
--- a/absl/random/internal/nonsecure_base.h
+++ b/absl/random/internal/nonsecure_base.h
@@ -79,9 +79,9 @@
       // capability, however until Abseil's support requirements allow us to
       // assume C++20, limit checks to a few common cases.
       using TagType = std::conditional_t<
-          (std::is_pointer<RandomAccessIterator>::value ||
-           std::is_same<RandomAccessIterator,
-                        typename std::vector<U>::iterator>::value),
+          (std::is_pointer_v<RandomAccessIterator> ||
+           std::is_same_v<RandomAccessIterator,
+                          typename std::vector<U>::iterator>),
           ContiguousTag, BufferTag>;
 
       generate_impl(TagType{}, begin, end);
@@ -107,7 +107,7 @@
 
   // Constructor using a seed
   template <class SSeq, typename = typename std::enable_if_t<
-                            !std::is_same<SSeq, NonsecureURBGBase>::value>>
+                            !std::is_same_v<SSeq, NonsecureURBGBase>>>
   explicit NonsecureURBGBase(SSeq&& seq)
       : urbg_(ConstructURBG(std::forward<SSeq>(seq))) {}
 
diff --git a/absl/random/internal/nonsecure_base_test.cc b/absl/random/internal/nonsecure_base_test.cc
index 3795563..75f40bd 100644
--- a/absl/random/internal/nonsecure_base_test.cc
+++ b/absl/random/internal/nonsecure_base_test.cc
@@ -74,19 +74,19 @@
 
   using T = typename E::result_type;
 
-  static_assert(!std::is_copy_constructible<E>::value,
+  static_assert(!std::is_copy_constructible_v<E>,
                 "NonsecureURBGBase should not be copy constructible");
 
-  static_assert(!std::is_copy_assignable<E>::value,
+  static_assert(!std::is_copy_assignable_v<E>,
                 "NonsecureURBGBase should not be copy assignable");
 
-  static_assert(std::is_move_constructible<E>::value,
+  static_assert(std::is_move_constructible_v<E>,
                 "NonsecureURBGBase should be move constructible");
 
-  static_assert(std::is_move_assignable<E>::value,
+  static_assert(std::is_move_assignable_v<E>,
                 "NonsecureURBGBase should be move assignable");
 
-  static_assert(std::is_same<decltype(std::declval<E>()()), T>::value,
+  static_assert(std::is_same_v<decltype(std::declval<E>()()), T>,
                 "return type of operator() must be result_type");
 
   {
@@ -94,10 +94,10 @@
     Use(x);
     Use(y);
 
-    static_assert(std::is_same<decltype(x == y), bool>::value,
+    static_assert(std::is_same_v<decltype(x == y), bool>,
                   "return type of operator== must be bool");
 
-    static_assert(std::is_same<decltype(x != y), bool>::value,
+    static_assert(std::is_same_v<decltype(x != y), bool>,
                   "return type of operator== must be bool");
   }
 
diff --git a/absl/random/internal/pcg_engine.h b/absl/random/internal/pcg_engine.h
index 2f41d58..5184c86 100644
--- a/absl/random/internal/pcg_engine.h
+++ b/absl/random/internal/pcg_engine.h
@@ -39,12 +39,12 @@
 //
 template <typename Params, typename Mix>
 class pcg_engine {
-  static_assert(std::is_same<typename Params::state_type,
-                             typename Mix::state_type>::value,
-                "Class-template absl::pcg_engine must be parameterized by "
-                "Params and Mix with identical state_type");
+  static_assert(
+      std::is_same_v<typename Params::state_type, typename Mix::state_type>,
+      "Class-template absl::pcg_engine must be parameterized by "
+      "Params and Mix with identical state_type");
 
-  static_assert(std::is_unsigned<typename Mix::result_type>::value,
+  static_assert(std::is_unsigned_v<typename Mix::result_type>,
                 "Class-template absl::pcg_engine must be parameterized by "
                 "an unsigned Mix::result_type");
 
@@ -66,9 +66,8 @@
 
   explicit pcg_engine(uint64_t seed_value = 0) { seed(seed_value); }
 
-  template <class SeedSequence,
-            typename = typename std::enable_if_t<
-                !std::is_same<SeedSequence, pcg_engine>::value>>
+  template <class SeedSequence, typename = typename std::enable_if_t<
+                                    !std::is_same_v<SeedSequence, pcg_engine>>>
   explicit pcg_engine(SeedSequence&& seq) {
     seed(seq);
   }
@@ -90,8 +89,8 @@
   }
 
   template <class SeedSequence>
-  typename std::enable_if_t<
-      !std::is_convertible<SeedSequence, uint64_t>::value, void>
+  typename std::enable_if_t<!std::is_convertible_v<SeedSequence, uint64_t>,
+                            void>
   seed(SeedSequence&& seq) {
     reseed(seq);
   }
diff --git a/absl/random/internal/pcg_engine_test.cc b/absl/random/internal/pcg_engine_test.cc
index 211a849..1861fb6 100644
--- a/absl/random/internal/pcg_engine_test.cc
+++ b/absl/random/internal/pcg_engine_test.cc
@@ -167,19 +167,19 @@
   using E = engine_type;
   using T = typename E::result_type;
 
-  static_assert(std::is_copy_constructible<E>::value,
+  static_assert(std::is_copy_constructible_v<E>,
                 "engine_type must be copy constructible");
 
-  static_assert(std::is_copy_assignable<E>::value,
+  static_assert(std::is_copy_assignable_v<E>,
                 "engine_type must be copy assignable");
 
-  static_assert(std::is_move_constructible<E>::value,
+  static_assert(std::is_move_constructible_v<E>,
                 "engine_type must be move constructible");
 
-  static_assert(std::is_move_assignable<E>::value,
+  static_assert(std::is_move_assignable_v<E>,
                 "engine_type must be move assignable");
 
-  static_assert(std::is_same<decltype(std::declval<E>()()), T>::value,
+  static_assert(std::is_same_v<decltype(std::declval<E>()()), T>,
                 "return type of operator() must be result_type");
 
   // Names after definition of [rand.req.urbg] in C++ standard.
@@ -225,10 +225,10 @@
 
   e.discard(z);
 
-  static_assert(std::is_same<decltype(x == y), bool>::value,
+  static_assert(std::is_same_v<decltype(x == y), bool>,
                 "return type of operator== must be bool");
 
-  static_assert(std::is_same<decltype(x != y), bool>::value,
+  static_assert(std::is_same_v<decltype(x != y), bool>,
                 "return type of operator== must be bool");
 }
 
diff --git a/absl/random/internal/randen_engine.h b/absl/random/internal/randen_engine.h
index 4e4fef9..525d40a 100644
--- a/absl/random/internal/randen_engine.h
+++ b/absl/random/internal/randen_engine.h
@@ -47,7 +47,7 @@
  public:
   // C++11 URBG interface:
   using result_type = T;
-  static_assert(std::is_unsigned<result_type>::value,
+  static_assert(std::is_unsigned_v<result_type>,
                 "randen_engine template argument must be a built-in unsigned "
                 "integer type");
 
@@ -64,7 +64,7 @@
 
   template <class SeedSequence,
             typename = typename std::enable_if_t<
-                !std::is_same<SeedSequence, randen_engine>::value>>
+                !std::is_same_v<SeedSequence, randen_engine>>>
   explicit randen_engine(SeedSequence&& seq) {
     seed(seq);
   }
@@ -93,8 +93,7 @@
   }
 
   template <class SeedSequence>
-  typename std::enable_if_t<
-      !std::is_convertible<SeedSequence, result_type>::value>
+  typename std::enable_if_t<!std::is_convertible_v<SeedSequence, result_type>>
   seed(SeedSequence&& seq) {
     // Zeroes the state.
     seed();
diff --git a/absl/random/internal/randen_engine_test.cc b/absl/random/internal/randen_engine_test.cc
index 85c0a2b..9709cce 100644
--- a/absl/random/internal/randen_engine_test.cc
+++ b/absl/random/internal/randen_engine_test.cc
@@ -168,19 +168,19 @@
   using E = randen;
   using T = typename E::result_type;
 
-  static_assert(std::is_copy_constructible<E>::value,
+  static_assert(std::is_copy_constructible_v<E>,
                 "randen_engine must be copy constructible");
 
-  static_assert(std::is_copy_assignable<E>::value,
+  static_assert(std::is_copy_assignable_v<E>,
                 "randen_engine must be copy assignable");
 
-  static_assert(std::is_move_constructible<E>::value,
+  static_assert(std::is_move_constructible_v<E>,
                 "randen_engine must be move constructible");
 
-  static_assert(std::is_move_assignable<E>::value,
+  static_assert(std::is_move_assignable_v<E>,
                 "randen_engine must be move assignable");
 
-  static_assert(std::is_same<decltype(std::declval<E>()()), T>::value,
+  static_assert(std::is_same_v<decltype(std::declval<E>()()), T>,
                 "return type of operator() must be result_type");
 
   // Names after definition of [rand.req.urbg] in C++ standard.
@@ -226,10 +226,10 @@
 
   e.discard(z);
 
-  static_assert(std::is_same<decltype(x == y), bool>::value,
+  static_assert(std::is_same_v<decltype(x == y), bool>,
                 "return type of operator== must be bool");
 
-  static_assert(std::is_same<decltype(x != y), bool>::value,
+  static_assert(std::is_same_v<decltype(x != y), bool>,
                 "return type of operator== must be bool");
 }
 
diff --git a/absl/random/internal/randen_test.cc b/absl/random/internal/randen_test.cc
index cf94970..44bd907 100644
--- a/absl/random/internal/randen_test.cc
+++ b/absl/random/internal/randen_test.cc
@@ -25,16 +25,16 @@
 using absl::random_internal::Randen;
 
 TEST(RandenTest, CopyAndMove) {
-  static_assert(std::is_copy_constructible<Randen>::value,
+  static_assert(std::is_copy_constructible_v<Randen>,
                 "Randen must be copy constructible");
 
-  static_assert(std::is_copy_assignable<Randen>::value,
+  static_assert(std::is_copy_assignable_v<Randen>,
                 "Randen must be copy assignable");
 
-  static_assert(std::is_move_constructible<Randen>::value,
+  static_assert(std::is_move_constructible_v<Randen>,
                 "Randen must be move constructible");
 
-  static_assert(std::is_move_assignable<Randen>::value,
+  static_assert(std::is_move_assignable_v<Randen>,
                 "Randen must be move assignable");
 }
 
diff --git a/absl/random/internal/salted_seed_seq.h b/absl/random/internal/salted_seed_seq.h
index c6f1734..68296e8 100644
--- a/absl/random/internal/salted_seed_seq.h
+++ b/absl/random/internal/salted_seed_seq.h
@@ -73,10 +73,10 @@
     // to uint arrays. Such contiguous memory regions may be optimized,
     // which we detect here.
     using TagType = std::conditional_t<
-        (std::is_same<U, uint32_t>::value &&
-         (std::is_pointer<RandomAccessIterator>::value ||
-          std::is_same<RandomAccessIterator,
-                       typename std::vector<U>::iterator>::value)),
+        (std::is_same_v<U, uint32_t> &&
+         (std::is_pointer_v<RandomAccessIterator> ||
+          std::is_same_v<RandomAccessIterator,
+                         typename std::vector<U>::iterator>)),
         ContiguousAndUint32Tag, DefaultTag>;
     if (begin != end) {
       generate_impl(TagType{}, begin, end, std::distance(begin, end));
@@ -132,8 +132,8 @@
 
 template <typename T>
 struct is_salted_seed_seq<
-    T, std::enable_if_t<std::is_same<
-           T, SaltedSeedSeq<typename T::inner_sequence_type>>::value>>
+    T, std::enable_if_t<
+           std::is_same_v<T, SaltedSeedSeq<typename T::inner_sequence_type>>>>
     : public std::true_type {};
 
 // MakeSaltedSeedSeq returns a salted variant of the seed sequence.
diff --git a/absl/random/internal/traits.h b/absl/random/internal/traits.h
index e03c034..8bde0ce 100644
--- a/absl/random/internal/traits.h
+++ b/absl/random/internal/traits.h
@@ -35,16 +35,15 @@
 struct is_urbg : std::false_type {};
 
 template <typename URBG>
-struct is_urbg<URBG,
-               std::enable_if_t<
-                   std::is_same<typename URBG::result_type,
-                                std::decay_t<decltype((URBG::min)())>>::value>,
-               std::enable_if_t<
-                   std::is_same<typename URBG::result_type,
-                                std::decay_t<decltype((URBG::max)())>>::value>,
-               std::enable_if_t<std::is_same<
-                   typename URBG::result_type,
-                   std::decay_t<decltype(std::declval<URBG>()())>>::value>>
+struct is_urbg<
+    URBG,
+    std::enable_if_t<std::is_same_v<typename URBG::result_type,
+                                    std::decay_t<decltype((URBG::min)())>>>,
+    std::enable_if_t<std::is_same_v<typename URBG::result_type,
+                                    std::decay_t<decltype((URBG::max)())>>>,
+    std::enable_if_t<
+        std::is_same_v<typename URBG::result_type,
+                       std::decay_t<decltype(std::declval<URBG>()())>>>>
     : std::true_type {};
 
 // random_internal::is_widening_convertible<A, B>
diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h
index 1998aaa..aefbd00 100644
--- a/absl/random/internal/uniform_helper.h
+++ b/absl/random/internal/uniform_helper.h
@@ -76,8 +76,8 @@
 // Return-type for absl::Uniform() when the return-type is inferred.
 template <typename A, typename B>
 using uniform_inferred_return_t = std::enable_if_t<
-    std::disjunction<is_widening_convertible<A, B>,
-                     is_widening_convertible<B, A>>::value,
+    std::disjunction_v<is_widening_convertible<A, B>,
+                       is_widening_convertible<B, A>>,
     std::conditional_t<is_widening_convertible<A, B>::value, B, A>>;
 
 // The functions
@@ -98,10 +98,10 @@
 //
 template <typename IntType, typename Tag>
 typename std::enable_if_t<
-    std::conjunction<
+    std::conjunction_v<
         IsIntegral<IntType>,
         std::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
-                          std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+                         std::is_same<Tag, IntervalOpenOpenTag>>>,
     IntType>
 uniform_lower_bound(Tag, IntType a, IntType) {
   return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a;
@@ -109,10 +109,10 @@
 
 template <typename FloatType, typename Tag>
 typename std::enable_if_t<
-    std::conjunction<
+    std::conjunction_v<
         std::is_floating_point<FloatType>,
         std::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
-                          std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+                         std::is_same<Tag, IntervalOpenOpenTag>>>,
     FloatType>
 uniform_lower_bound(Tag, FloatType a, FloatType b) {
   return std::nextafter(a, b);
@@ -120,8 +120,8 @@
 
 template <typename NumType, typename Tag>
 typename std::enable_if_t<
-    std::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
-                      std::is_same<Tag, IntervalClosedOpenTag>>::value,
+    std::disjunction_v<std::is_same<Tag, IntervalClosedClosedTag>,
+                       std::is_same<Tag, IntervalClosedOpenTag>>,
     NumType>
 uniform_lower_bound(Tag, NumType a, NumType) {
   return a;
@@ -129,10 +129,10 @@
 
 template <typename IntType, typename Tag>
 typename std::enable_if_t<
-    std::conjunction<
+    std::conjunction_v<
         IsIntegral<IntType>,
         std::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
-                          std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+                         std::is_same<Tag, IntervalOpenOpenTag>>>,
     IntType>
 uniform_upper_bound(Tag, IntType, IntType b) {
   return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b;
@@ -140,10 +140,10 @@
 
 template <typename FloatType, typename Tag>
 typename std::enable_if_t<
-    std::conjunction<
+    std::conjunction_v<
         std::is_floating_point<FloatType>,
         std::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
-                          std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+                         std::is_same<Tag, IntervalOpenOpenTag>>>,
     FloatType>
 uniform_upper_bound(Tag, FloatType, FloatType b) {
   return b;
@@ -151,10 +151,10 @@
 
 template <typename IntType, typename Tag>
 typename std::enable_if_t<
-    std::conjunction<
+    std::conjunction_v<
         IsIntegral<IntType>,
         std::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
-                          std::is_same<Tag, IntervalOpenClosedTag>>>::value,
+                         std::is_same<Tag, IntervalOpenClosedTag>>>,
     IntType>
 uniform_upper_bound(Tag, IntType, IntType b) {
   return b;
@@ -162,10 +162,10 @@
 
 template <typename FloatType, typename Tag>
 typename std::enable_if_t<
-    std::conjunction<
+    std::conjunction_v<
         std::is_floating_point<FloatType>,
         std::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
-                          std::is_same<Tag, IntervalOpenClosedTag>>>::value,
+                         std::is_same<Tag, IntervalOpenClosedTag>>>,
     FloatType>
 uniform_upper_bound(Tag, FloatType, FloatType b) {
   return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
@@ -194,7 +194,7 @@
 // (0, 0] is not legal, but (0, 0+epsilon] is.
 //
 template <typename FloatType>
-std::enable_if_t<std::is_floating_point<FloatType>::value, bool>
+std::enable_if_t<std::is_floating_point_v<FloatType>, bool>
 is_uniform_range_valid(FloatType a, FloatType b) {
   return a <= b && std::isfinite(b - a);
 }
diff --git a/absl/random/internal/uniform_helper_test.cc b/absl/random/internal/uniform_helper_test.cc
index 5b20b0b..f03bf2c 100644
--- a/absl/random/internal/uniform_helper_test.cc
+++ b/absl/random/internal/uniform_helper_test.cc
@@ -215,10 +215,9 @@
 template <typename A, typename B, typename Expect>
 void CheckArgsInferType() {
   static_assert(
-      std::conjunction<
+      std::conjunction_v<
           std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
-          std::is_same<Expect,
-                       decltype(InferredUniformReturnT<B, A>(0))>>::value,
+          std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>,
       "");
 }
 
diff --git a/absl/random/internal/wide_multiply.h b/absl/random/internal/wide_multiply.h
index b125681..f2a5033 100644
--- a/absl/random/internal/wide_multiply.h
+++ b/absl/random/internal/wide_multiply.h
@@ -50,7 +50,7 @@
   }
   static input_type lo(result_type r) { return static_cast<input_type>(r); }
 
-  static_assert(std::is_unsigned<UIntType>::value,
+  static_assert(std::is_unsigned_v<UIntType>,
                 "Class-template wide_multiply<> argument must be unsigned.");
 };
 
diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h
index 6117e7c..2e3c606 100644
--- a/absl/random/mocking_bit_gen.h
+++ b/absl/random/mocking_bit_gen.h
@@ -175,14 +175,13 @@
                                               std::declval<ArgTupleT>()));
 
     using WrappedFnType = std::conditional_t<
-        std::is_same<SelfT, ::testing::NiceMock<MockingBitGen>>::value,
+        std::is_same_v<SelfT, ::testing::NiceMock<MockingBitGen>>,
         ::testing::NiceMock<MockFnType>,
         std::conditional_t<
-            std::is_same<SelfT, ::testing::NaggyMock<MockingBitGen>>::value,
+            std::is_same_v<SelfT, ::testing::NaggyMock<MockingBitGen>>,
             ::testing::NaggyMock<MockFnType>,
             std::conditional_t<
-                std::is_same<SelfT,
-                             ::testing::StrictMock<MockingBitGen>>::value,
+                std::is_same_v<SelfT, ::testing::StrictMock<MockingBitGen>>,
                 ::testing::StrictMock<MockFnType>, MockFnType>>>;
 
     using ImplT =
diff --git a/absl/random/uniform_int_distribution_test.cc b/absl/random/uniform_int_distribution_test.cc
index 8134ab6..98da12b 100644
--- a/absl/random/uniform_int_distribution_test.cc
+++ b/absl/random/uniform_int_distribution_test.cc
@@ -47,8 +47,8 @@
   using Limits = std::numeric_limits<TypeParam>;
   using param_type =
       typename absl::uniform_int_distribution<TypeParam>::param_type;
-  const TypeParam kMin = std::is_unsigned<TypeParam>::value ? 37 : -105;
-  const TypeParam kNegOneOrZero = std::is_unsigned<TypeParam>::value ? 0 : -1;
+  const TypeParam kMin = std::is_unsigned_v<TypeParam> ? 37 : -105;
+  const TypeParam kNegOneOrZero = std::is_unsigned_v<TypeParam> ? 0 : -1;
 
   constexpr int kCount = 1000;
   absl::InsecureBitGen gen;
@@ -180,7 +180,7 @@
   const int kThreshold =
       absl::random_internal::ChiSquareValue(kBuckets, 0.999999);
 
-  const TypeParam min = std::is_unsigned<TypeParam>::value ? 37 : -37;
+  const TypeParam min = std::is_unsigned_v<TypeParam> ? 37 : -37;
   const TypeParam max = min + kBuckets;
 
   // We use a fixed bit generator for distribution accuracy tests.  This allows
diff --git a/absl/random/uniform_real_distribution.h b/absl/random/uniform_real_distribution.h
index e5ea6f2..79cf793 100644
--- a/absl/random/uniform_real_distribution.h
+++ b/absl/random/uniform_real_distribution.h
@@ -98,7 +98,7 @@
     friend class uniform_real_distribution;
     result_type lo_, hi_, range_;
 
-    static_assert(std::is_floating_point<RealType>::value,
+    static_assert(std::is_floating_point_v<RealType>,
                   "Class-template absl::uniform_real_distribution<> must be "
                   "parameterized using a floating-point type.");
   };
@@ -159,7 +159,7 @@
   using random_internal::GeneratePositiveTag;
   using random_internal::GenerateRealFromBits;
   using real_type =
-      std::conditional_t<std::is_same<RealType, float>::value, float, double>;
+      std::conditional_t<std::is_same_v<RealType, float>, float, double>;
 
   while (true) {
     const result_type sample =
diff --git a/absl/random/uniform_real_distribution_test.cc b/absl/random/uniform_real_distribution_test.cc
index d8c91a4..5193b8c 100644
--- a/absl/random/uniform_real_distribution_test.cc
+++ b/absl/random/uniform_real_distribution_test.cc
@@ -180,7 +180,7 @@
       }
     }
 
-    if (!std::is_same<real_type, long double>::value) {
+    if (!std::is_same_v<real_type, long double>) {
       // static_cast<double>(long double) can overflow.
       LOG(INFO) << "Range: " << static_cast<double>(sample_min) << ", "
                 << static_cast<double>(sample_max);
diff --git a/absl/status/internal/statusor_internal.h b/absl/status/internal/statusor_internal.h
index de56519..c42891f 100644
--- a/absl/status/internal/statusor_internal.h
+++ b/absl/status/internal/statusor_internal.h
@@ -53,9 +53,9 @@
 
 template <typename T>
 struct IsEqualityComparable<
-    T, std::enable_if_t<std::is_convertible<
-           decltype(std::declval<T>() == std::declval<T>()),
-           bool>::value>> : std::true_type {};
+    T, std::enable_if_t<std::is_convertible_v<
+           decltype(std::declval<T>() == std::declval<T>()), bool>>>
+    : std::true_type {};
 
 // Detects whether `T` is constructible or convertible from `StatusOr<U>`.
 template <typename T, typename U>
@@ -84,7 +84,7 @@
 template <typename T, typename U>
 struct IsDirectInitializationAmbiguous
     : public std::conditional_t<
-          std::is_same<absl::remove_cvref_t<U>, U>::value, std::false_type,
+          std::is_same_v<absl::remove_cvref_t<U>, U>, std::false_type,
           IsDirectInitializationAmbiguous<T, absl::remove_cvref_t<U>>> {};
 
 template <typename T, typename V>
@@ -133,7 +133,7 @@
 template <typename T, typename U>
 struct IsForwardingAssignmentAmbiguous
     : public std::conditional_t<
-          std::is_same<absl::remove_cvref_t<U>, U>::value, std::false_type,
+          std::is_same_v<absl::remove_cvref_t<U>, U>, std::false_type,
           IsForwardingAssignmentAmbiguous<T, absl::remove_cvref_t<U>>> {};
 
 template <typename T, typename U>
@@ -330,9 +330,9 @@
     MakeStatus();
   }
 
-  template <typename U,
-            std::enable_if_t<std::is_constructible<absl::Status, U&&>::value,
-                              int> = 0>
+  template <
+      typename U,
+      std::enable_if_t<std::is_constructible_v<absl::Status, U&&>, int> = 0>
   explicit StatusOrData(U&& v) : status_(std::forward<U>(v)) {
     EnsureNotOk();
   }
@@ -527,7 +527,7 @@
 // operators in `StatusOr`. For example, `CopyCtorBase` will explicitly delete
 // the copy constructor when T is not copy constructible and `StatusOr` will
 // inherit that behavior implicitly.
-template <typename T, bool = std::is_copy_constructible<T>::value>
+template <typename T, bool = std::is_copy_constructible_v<T>>
 struct CopyCtorBase {
   CopyCtorBase() = default;
   CopyCtorBase(const CopyCtorBase&) = default;
@@ -545,7 +545,7 @@
   CopyCtorBase& operator=(CopyCtorBase&&) = default;
 };
 
-template <typename T, bool = std::is_move_constructible<T>::value>
+template <typename T, bool = std::is_move_constructible_v<T>>
 struct MoveCtorBase {
   MoveCtorBase() = default;
   MoveCtorBase(const MoveCtorBase&) = default;
@@ -563,8 +563,8 @@
   MoveCtorBase& operator=(MoveCtorBase&&) = default;
 };
 
-template <typename T, bool = (std::is_copy_constructible<T>::value &&
-                              std::is_copy_assignable<T>::value) ||
+template <typename T, bool = (std::is_copy_constructible_v<T> &&
+                              std::is_copy_assignable_v<T>) ||
                              std::is_reference_v<T>>
 struct CopyAssignBase {
   CopyAssignBase() = default;
@@ -583,8 +583,8 @@
   CopyAssignBase& operator=(CopyAssignBase&&) = default;
 };
 
-template <typename T, bool = (std::is_move_constructible<T>::value &&
-                              std::is_move_assignable<T>::value) ||
+template <typename T, bool = (std::is_move_constructible_v<T> &&
+                              std::is_move_assignable_v<T>) ||
                              std::is_reference_v<T>>
 struct MoveAssignBase {
   MoveAssignBase() = default;
diff --git a/absl/status/statusor.h b/absl/status/statusor.h
index a02a562..ed34bb8 100644
--- a/absl/status/statusor.h
+++ b/absl/status/statusor.h
@@ -622,11 +622,10 @@
     return this->data_;
   }
 
-  template <
-      typename U, typename... Args,
-      std::enable_if_t<
-          std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
-          int> = 0>
+  template <typename U, typename... Args,
+            std::enable_if_t<std::is_constructible_v<
+                                 T, std::initializer_list<U>&, Args&&...>,
+                             int> = 0>
   T& emplace(std::initializer_list<U> ilist,
              Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ok()) {
diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc
index fc558f6..2205acf 100644
--- a/absl/status/statusor_test.cc
+++ b/absl/status/statusor_test.cc
@@ -582,11 +582,11 @@
 
 TEST(StatusOr, ExplicitConvertingConstructor) {
   EXPECT_FALSE(
-      (std::is_convertible<const absl::StatusOr<A>&,
-                           absl::StatusOr<ExplicitConstructibleFromA>>::value));
+      (std::is_convertible_v<const absl::StatusOr<A>&,
+                             absl::StatusOr<ExplicitConstructibleFromA>>));
   EXPECT_FALSE(
-      (std::is_convertible<absl::StatusOr<A>&&,
-                           absl::StatusOr<ExplicitConstructibleFromA>>::value));
+      (std::is_convertible_v<absl::StatusOr<A>&&,
+                             absl::StatusOr<ExplicitConstructibleFromA>>));
   EXPECT_THAT(
       absl::StatusOr<ExplicitConstructibleFromA>(absl::StatusOr<A>(A{11})),
       IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 11),
@@ -618,9 +618,9 @@
       absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromBool>>(
           absl::StatusOr<bool>(false)),
       IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
-  EXPECT_FALSE((std::is_convertible<
-                absl::StatusOr<ConvertibleToBool>,
-                absl::StatusOr<ImplicitConstructibleFromBool>>::value));
+  EXPECT_FALSE(
+      (std::is_convertible_v<absl::StatusOr<ConvertibleToBool>,
+                             absl::StatusOr<ImplicitConstructibleFromBool>>));
 }
 
 TEST(StatusOr, BooleanConstructionWithImplicitCasts) {
@@ -782,18 +782,18 @@
 };
 
 TEST(StatusOr, CopyAndMoveAbility) {
-  EXPECT_TRUE(std::is_copy_constructible<Copyable>::value);
-  EXPECT_TRUE(std::is_copy_assignable<Copyable>::value);
-  EXPECT_TRUE(std::is_move_constructible<Copyable>::value);
-  EXPECT_TRUE(std::is_move_assignable<Copyable>::value);
-  EXPECT_FALSE(std::is_copy_constructible<MoveOnly>::value);
-  EXPECT_FALSE(std::is_copy_assignable<MoveOnly>::value);
-  EXPECT_TRUE(std::is_move_constructible<MoveOnly>::value);
-  EXPECT_TRUE(std::is_move_assignable<MoveOnly>::value);
-  EXPECT_FALSE(std::is_copy_constructible<NonMovable>::value);
-  EXPECT_FALSE(std::is_copy_assignable<NonMovable>::value);
-  EXPECT_FALSE(std::is_move_constructible<NonMovable>::value);
-  EXPECT_FALSE(std::is_move_assignable<NonMovable>::value);
+  EXPECT_TRUE(std::is_copy_constructible_v<Copyable>);
+  EXPECT_TRUE(std::is_copy_assignable_v<Copyable>);
+  EXPECT_TRUE(std::is_move_constructible_v<Copyable>);
+  EXPECT_TRUE(std::is_move_assignable_v<Copyable>);
+  EXPECT_FALSE(std::is_copy_constructible_v<MoveOnly>);
+  EXPECT_FALSE(std::is_copy_assignable_v<MoveOnly>);
+  EXPECT_TRUE(std::is_move_constructible_v<MoveOnly>);
+  EXPECT_TRUE(std::is_move_assignable_v<MoveOnly>);
+  EXPECT_FALSE(std::is_copy_constructible_v<NonMovable>);
+  EXPECT_FALSE(std::is_copy_assignable_v<NonMovable>);
+  EXPECT_FALSE(std::is_move_constructible_v<NonMovable>);
+  EXPECT_FALSE(std::is_move_assignable_v<NonMovable>);
 }
 
 TEST(StatusOr, StatusOrAnyCopyAndMoveConstructorTests) {
@@ -877,8 +877,8 @@
 }
 
 TEST(StatusOr, AbslAnyAssignment) {
-  EXPECT_FALSE((std::is_assignable<absl::StatusOr<std::any>,
-                                   absl::StatusOr<int>>::value));
+  EXPECT_FALSE(
+      (std::is_assignable_v<absl::StatusOr<std::any>, absl::StatusOr<int>>));
   absl::StatusOr<std::any> status_or;
   status_or = absl::InvalidArgumentError("foo");
   EXPECT_THAT(status_or, Not(IsOk()));
@@ -912,10 +912,10 @@
   struct B : public A {};
   struct C : private A {};
 
-  EXPECT_TRUE((std::is_constructible<absl::StatusOr<A*>, B*>::value));
-  EXPECT_TRUE((std::is_convertible<B*, absl::StatusOr<A*>>::value));
-  EXPECT_FALSE((std::is_constructible<absl::StatusOr<A*>, C*>::value));
-  EXPECT_FALSE((std::is_convertible<C*, absl::StatusOr<A*>>::value));
+  EXPECT_TRUE((std::is_constructible_v<absl::StatusOr<A*>, B*>));
+  EXPECT_TRUE((std::is_convertible_v<B*, absl::StatusOr<A*>>));
+  EXPECT_FALSE((std::is_constructible_v<absl::StatusOr<A*>, C*>));
+  EXPECT_FALSE((std::is_convertible_v<C*, absl::StatusOr<A*>>));
 }
 
 TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
@@ -1087,21 +1087,19 @@
   EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue2, true, false)));
 
   // U != T
-  EXPECT_TRUE(
-      (std::is_assignable<absl::StatusOr<MockValue>&,
-                          const FromConstructibleAssignableLvalue&>::value));
-  EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&,
-                                  FromConstructibleAssignableLvalue&&>::value));
+  EXPECT_TRUE((std::is_assignable_v<absl::StatusOr<MockValue>&,
+                                    const FromConstructibleAssignableLvalue&>));
+  EXPECT_TRUE((std::is_assignable_v<absl::StatusOr<MockValue>&,
+                                    FromConstructibleAssignableLvalue&&>));
   EXPECT_FALSE(
-      (std::is_assignable<absl::StatusOr<MockValue>&,
-                          const FromConstructibleAssignableRvalue&>::value));
-  EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&,
-                                  FromConstructibleAssignableRvalue&&>::value));
-  EXPECT_TRUE(
-      (std::is_assignable<absl::StatusOr<MockValue>&,
-                          const FromImplicitConstructibleOnly&>::value));
-  EXPECT_FALSE((std::is_assignable<absl::StatusOr<MockValue>&,
-                                   const FromAssignableOnly&>::value));
+      (std::is_assignable_v<absl::StatusOr<MockValue>&,
+                            const FromConstructibleAssignableRvalue&>));
+  EXPECT_TRUE((std::is_assignable_v<absl::StatusOr<MockValue>&,
+                                    FromConstructibleAssignableRvalue&&>));
+  EXPECT_TRUE((std::is_assignable_v<absl::StatusOr<MockValue>&,
+                                    const FromImplicitConstructibleOnly&>));
+  EXPECT_FALSE((std::is_assignable_v<absl::StatusOr<MockValue>&,
+                                     const FromAssignableOnly&>));
 
   absl::StatusOr<MockValue> from_lvalue(FromConstructibleAssignableLvalue{});
   EXPECT_FALSE(from_lvalue->from_rvalue);
@@ -1349,7 +1347,7 @@
 
 TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) {
   using EvilType = std::vector<std::unique_ptr<int>>;
-  static_assert(std::is_copy_constructible<EvilType>::value, "");
+  static_assert(std::is_copy_constructible_v<EvilType>, "");
   std::vector<::absl::StatusOr<EvilType>> v(5);
   v.reserve(v.capacity() + 10);
   v.resize(v.capacity() + 10);
@@ -1364,13 +1362,13 @@
   absl::StatusOr<const int> b(a);
 
   // Copy-assignment
-  EXPECT_FALSE(std::is_copy_assignable<absl::StatusOr<const int>>::value);
+  EXPECT_FALSE(std::is_copy_assignable_v<absl::StatusOr<const int>>);
 
   // Move-construction
   absl::StatusOr<const int> c(std::move(a));
 
   // Move-assignment
-  EXPECT_FALSE(std::is_move_assignable<absl::StatusOr<const int>>::value);
+  EXPECT_FALSE(std::is_move_assignable_v<absl::StatusOr<const int>>);
 }
 
 TEST(StatusOr, MapToStatusOrUniquePtr) {
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index d00f5a1..f722b3f 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -176,8 +176,7 @@
 class Cord {
  private:
   template <typename T>
-  using EnableIfString =
-      std::enable_if_t<std::is_same<T, std::string>::value, int>;
+  using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>, int>;
 
  public:
   // Cord::Cord() Constructors.
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index 7591758..5c773e7 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -1649,8 +1649,8 @@
   EXPECT_TRUE(a == a);
   // For pointer type (i.e. `const char*`), operator== compares the address
   // instead of the string, so `a == const char*("a")` isn't necessarily true.
-  EXPECT_TRUE(std::is_pointer<T1>::value || a == T1("a"));
-  EXPECT_TRUE(std::is_pointer<T2>::value || a == T2("a"));
+  EXPECT_TRUE(std::is_pointer_v<T1> || a == T1("a"));
+  EXPECT_TRUE(std::is_pointer_v<T2> || a == T2("a"));
   EXPECT_FALSE(a == b);
 
   EXPECT_TRUE(a != b);
@@ -2365,36 +2365,34 @@
 }
 
 TEST_P(CordTest, CordChunkIteratorTraits) {
-  static_assert(std::is_copy_constructible<absl::Cord::ChunkIterator>::value,
-                "");
-  static_assert(std::is_copy_assignable<absl::Cord::ChunkIterator>::value, "");
+  static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>, "");
+  static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>, "");
 
   // Move semantics to satisfy swappable via std::swap
-  static_assert(std::is_move_constructible<absl::Cord::ChunkIterator>::value,
-                "");
-  static_assert(std::is_move_assignable<absl::Cord::ChunkIterator>::value, "");
+  static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>, "");
+  static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>, "");
 
   static_assert(
-      std::is_same<
+      std::is_same_v<
           std::iterator_traits<absl::Cord::ChunkIterator>::iterator_category,
-          std::input_iterator_tag>::value,
+          std::input_iterator_tag>,
       "");
+  static_assert(std::is_same_v<
+                    std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
+                    absl::string_view>,
+                "");
   static_assert(
-      std::is_same<std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
-                   absl::string_view>::value,
-      "");
-  static_assert(
-      std::is_same<
+      std::is_same_v<
           std::iterator_traits<absl::Cord::ChunkIterator>::difference_type,
-          ptrdiff_t>::value,
+          ptrdiff_t>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<absl::Cord::ChunkIterator>::pointer,
-                   const absl::string_view*>::value,
+      std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::pointer,
+                     const absl::string_view*>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<absl::Cord::ChunkIterator>::reference,
-                   absl::string_view>::value,
+      std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::reference,
+                     absl::string_view>,
       "");
 }
 
@@ -2554,36 +2552,34 @@
 }
 
 TEST_P(CordTest, CharIteratorTraits) {
-  static_assert(std::is_copy_constructible<absl::Cord::CharIterator>::value,
-                "");
-  static_assert(std::is_copy_assignable<absl::Cord::CharIterator>::value, "");
+  static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>, "");
+  static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>, "");
 
   // Move semantics to satisfy swappable via std::swap
-  static_assert(std::is_move_constructible<absl::Cord::CharIterator>::value,
-                "");
-  static_assert(std::is_move_assignable<absl::Cord::CharIterator>::value, "");
+  static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>, "");
+  static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>, "");
 
   static_assert(
-      std::is_same<
+      std::is_same_v<
           std::iterator_traits<absl::Cord::CharIterator>::iterator_category,
-          std::input_iterator_tag>::value,
+          std::input_iterator_tag>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<absl::Cord::CharIterator>::value_type,
-                   char>::value,
+      std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::value_type,
+                     char>,
       "");
   static_assert(
-      std::is_same<
+      std::is_same_v<
           std::iterator_traits<absl::Cord::CharIterator>::difference_type,
-          ptrdiff_t>::value,
+          ptrdiff_t>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<absl::Cord::CharIterator>::pointer,
-                   const char*>::value,
+      std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::pointer,
+                     const char*>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<absl::Cord::CharIterator>::reference,
-                   const char&>::value,
+      std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::reference,
+                     const char&>,
       "");
 }
 
diff --git a/absl/strings/has_absl_stringify.h b/absl/strings/has_absl_stringify.h
index 9af0191..45843ae 100644
--- a/absl/strings/has_absl_stringify.h
+++ b/absl/strings/has_absl_stringify.h
@@ -54,9 +54,9 @@
 
 template <typename T>
 struct HasAbslStringify<
-    T, std::enable_if_t<std::is_void<decltype(AbslStringify(
+    T, std::enable_if_t<std::is_void_v<decltype(AbslStringify(
            std::declval<strings_internal::UnimplementedSink&>(),
-           std::declval<const T&>()))>::value>> : std::true_type {};
+           std::declval<const T&>()))>>> : std::true_type {};
 
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/strings/internal/cordz_sample_token_test.cc b/absl/strings/internal/cordz_sample_token_test.cc
index 487396b..22ef21c 100644
--- a/absl/strings/internal/cordz_sample_token_test.cc
+++ b/absl/strings/internal/cordz_sample_token_test.cc
@@ -44,34 +44,33 @@
 auto constexpr kTrackCordMethod = CordzUpdateTracker::kConstructorString;
 
 TEST(CordzSampleTokenTest, IteratorTraits) {
-  static_assert(std::is_copy_constructible<CordzSampleToken::Iterator>::value,
-                "");
-  static_assert(std::is_copy_assignable<CordzSampleToken::Iterator>::value, "");
-  static_assert(std::is_move_constructible<CordzSampleToken::Iterator>::value,
-                "");
-  static_assert(std::is_move_assignable<CordzSampleToken::Iterator>::value, "");
+  static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>, "");
+  static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>, "");
+  static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>, "");
+  static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>, "");
   static_assert(
-      std::is_same<
+      std::is_same_v<
           std::iterator_traits<CordzSampleToken::Iterator>::iterator_category,
-          std::input_iterator_tag>::value,
+          std::input_iterator_tag>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<CordzSampleToken::Iterator>::value_type,
-                   const CordzInfo&>::value,
+      std::is_same_v<
+          std::iterator_traits<CordzSampleToken::Iterator>::value_type,
+          const CordzInfo&>,
       "");
   static_assert(
-      std::is_same<
+      std::is_same_v<
           std::iterator_traits<CordzSampleToken::Iterator>::difference_type,
-          ptrdiff_t>::value,
+          ptrdiff_t>,
       "");
   static_assert(
-      std::is_same<std::iterator_traits<CordzSampleToken::Iterator>::pointer,
-                   const CordzInfo*>::value,
+      std::is_same_v<std::iterator_traits<CordzSampleToken::Iterator>::pointer,
+                     const CordzInfo*>,
       "");
-  static_assert(
-      std::is_same<std::iterator_traits<CordzSampleToken::Iterator>::reference,
-                   const CordzInfo&>::value,
-      "");
+  static_assert(std::is_same_v<
+                    std::iterator_traits<CordzSampleToken::Iterator>::reference,
+                    const CordzInfo&>,
+                "");
 }
 
 TEST(CordzSampleTokenTest, IteratorEmpty) {
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index 01e4e42..a51f7d7 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -95,7 +95,7 @@
   // Supports all integral types.
   template <typename T>
   void PrintAsDec(T v) {
-    static_assert(std::is_integral<T>::value, "");
+    static_assert(std::is_integral_v<T>, "");
     start_ = storage_;
     size_ = static_cast<size_t>(numbers_internal::FastIntToBuffer(v, storage_) -
                                 storage_);
@@ -356,8 +356,7 @@
   // FormatConversionChar is declared, but not defined.
   switch (static_cast<uint8_t>(conv.conversion_char())) {
     case static_cast<uint8_t>(FormatConversionCharInternal::c):
-      return (std::is_same<T, wchar_t>::value ||
-              (conv.length_mod() == LengthMod::l))
+      return (std::is_same_v<T, wchar_t> || (conv.length_mod() == LengthMod::l))
                  ? ConvertWCharTImpl(static_cast<wchar_t>(v), conv, sink)
                  : ConvertCharImpl(static_cast<char>(v), conv, sink);
 
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index e099b97..a48a76f 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -143,9 +143,9 @@
 template <typename T>
 auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv,
                        FormatSinkImpl* sink)
-    -> std::enable_if_t<std::is_enum<T>::value &&
-                            std::is_void<decltype(AbslStringify(
-                                std::declval<FormatSink&>(), v))>::value,
+    -> std::enable_if_t<std::is_enum_v<T> &&
+                            std::is_void_v<decltype(AbslStringify(
+                                std::declval<FormatSink&>(), v))>,
                         IntegralConvertResult> {
   if (conv.conversion_char() == FormatConversionCharInternal::v) {
     using FormatSinkT =
@@ -162,10 +162,9 @@
 template <typename T>
 auto FormatConvertImpl(const T& v, FormatConversionSpecImpl,
                        FormatSinkImpl* sink)
-    -> std::enable_if_t<!std::is_enum<T>::value &&
-                            !std::is_same<T, absl::Cord>::value &&
-                            std::is_void<decltype(AbslStringify(
-                                std::declval<FormatSink&>(), v))>::value,
+    -> std::enable_if_t<!std::is_enum_v<T> && !std::is_same_v<T, absl::Cord> &&
+                            std::is_void_v<decltype(AbslStringify(
+                                std::declval<FormatSink&>(), v))>,
                         ArgConvertResult<FormatConversionCharSetInternal::v>> {
   using FormatSinkT = std::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
   auto fs = sink->Wrap<FormatSinkT>();
@@ -247,9 +246,8 @@
                                          FormatConversionSpecImpl conv,
                                          FormatSinkImpl* sink);
 
-template <
-    class AbslCord,
-    std::enable_if_t<std::is_same<AbslCord, absl::Cord>::value>* = nullptr>
+template <class AbslCord,
+          std::enable_if_t<std::is_same_v<AbslCord, absl::Cord>>* = nullptr>
 StringConvertResult FormatConvertImpl(const AbslCord& value,
                                       FormatConversionSpecImpl conv,
                                       FormatSinkImpl* sink) {
@@ -341,7 +339,7 @@
 
 // This function needs to be a template due to ambiguity regarding type
 // conversions.
-template <typename T, std::enable_if_t<std::is_same<T, bool>::value, int> = 0>
+template <typename T, std::enable_if_t<std::is_same_v<T, bool>, int> = 0>
 IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv,
                                         FormatSinkImpl* sink) {
   if (conv.conversion_char() == FormatConversionCharInternal::v) {
@@ -354,7 +352,7 @@
 // We provide this function to help the checker, but it is never defined.
 // FormatArgImpl will use the underlying Convert functions instead.
 template <typename T>
-std::enable_if_t<std::is_enum<T>::value && !HasUserDefinedConvert<T>::value &&
+std::enable_if_t<std::is_enum_v<T> && !HasUserDefinedConvert<T>::value &&
                      !HasAbslStringify<T>::value,
                  IntegralConvertResult>
 FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
@@ -442,17 +440,16 @@
 
   template <typename T>
   struct store_by_value
-      : std::integral_constant<bool, (sizeof(T) <= kInlinedSpace) &&
-                                         (std::is_integral<T>::value ||
-                                          std::is_floating_point<T>::value ||
-                                          std::is_pointer<T>::value ||
-                                          std::is_same<VoidPtr, T>::value)> {};
+      : std::integral_constant<
+            bool, (sizeof(T) <= kInlinedSpace) &&
+                      (std::is_integral_v<T> || std::is_floating_point_v<T> ||
+                       std::is_pointer_v<T> || std::is_same_v<VoidPtr, T>)> {};
 
   enum StoragePolicy { ByPointer, ByVolatilePointer, ByValue };
   template <typename T>
   struct storage_policy
       : std::integral_constant<StoragePolicy,
-                               (std::is_volatile<T>::value
+                               (std::is_volatile_v<T>
                                     ? ByVolatilePointer
                                     : (store_by_value<T>::value ? ByValue
                                                                 : ByPointer))> {
@@ -472,20 +469,19 @@
         str_format_internal::HasUserDefinedConvert<T>::value ||
         HasAbslStringify<T>::value;
     using type = std::conditional_t<
-        !kHasUserDefined && std::is_convertible<T, const char*>::value,
-        const char*,
+        !kHasUserDefined && std::is_convertible_v<T, const char*>, const char*,
         std::conditional_t<
-            !kHasUserDefined && std::is_convertible<T, const wchar_t*>::value,
+            !kHasUserDefined && std::is_convertible_v<T, const wchar_t*>,
             const wchar_t*,
             std::conditional_t<!kHasUserDefined &&
-                                   std::is_convertible<T, VoidPtr>::value,
+                                   std::is_convertible_v<T, VoidPtr>,
                                VoidPtr, const T&>>>;
   };
   template <typename T>
   struct DecayType<
       T,
       std::enable_if_t<!str_format_internal::HasUserDefinedConvert<T>::value &&
-                       !HasAbslStringify<T>::value && std::is_enum<T>::value>> {
+                       !HasAbslStringify<T>::value && std::is_enum_v<T>>> {
     using type = decltype(+std::underlying_type_t<T>());
   };
 
@@ -494,7 +490,7 @@
   explicit FormatArgImpl(const T& value) {
     using D = typename DecayType<T>::type;
     static_assert(
-        std::is_same<D, const T&>::value || storage_policy<D>::value == ByValue,
+        std::is_same_v<D, const T&> || storage_policy<D>::value == ByValue,
         "Decayed types must be stored by value");
     Init(static_cast<D>(value));
   }
@@ -552,11 +548,11 @@
   template <typename T>
   static int ToIntVal(const T& val) {
     using CommonType =
-        std::conditional_t<std::is_signed<T>::value, int64_t, uint64_t>;
+        std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;
     if (static_cast<CommonType>(val) >
         static_cast<CommonType>((std::numeric_limits<int>::max)())) {
       return (std::numeric_limits<int>::max)();
-    } else if (std::is_signed<T>::value &&
+    } else if (std::is_signed_v<T> &&
                static_cast<CommonType>(val) <
                    static_cast<CommonType>((std::numeric_limits<int>::min)())) {
       return (std::numeric_limits<int>::min)();
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index d296e7e..1c3d1a3 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -120,7 +120,7 @@
 // An integral type of the same rank and signedness as `wchar_t`, that isn't
 // `wchar_t`.
 using IntegralTypeForWCharT =
-    std::conditional_t<std::is_signed<wchar_t>::value,
+    std::conditional_t<std::is_signed_v<wchar_t>,
                        // Some STLs are broken and return `wchar_t` from
                        // `std::make_[un]signed_t<wchar_t>` when the signedness
                        // matches. Work around by round-tripping through the
@@ -131,8 +131,8 @@
 // Given an integral type `T`, returns a type of the same rank and signedness
 // that is guaranteed to not be `wchar_t`.
 template <typename T>
-using MatchingIntegralType = std::conditional_t<std::is_same<T, wchar_t>::value,
-                                                IntegralTypeForWCharT, T>;
+using MatchingIntegralType =
+    std::conditional_t<std::is_same_v<T, wchar_t>, IntegralTypeForWCharT, T>;
 
 std::string EscCharImpl(int v) {
   char buf[64];
@@ -542,7 +542,7 @@
 
             const bool is_signed_conv = (conv_char == 'd' || conv_char == 'i');
             const bool is_unsigned_to_signed =
-                !std::is_signed<T>::value && is_signed_conv;
+                !std::is_signed_v<T> && is_signed_conv;
             // Don't consider sign-related flags '+' and ' ' when doing
             // unsigned to signed conversions.
             if (is_unsigned_to_signed &&
@@ -649,8 +649,7 @@
   // Special case: Formatting a wchar_t should behave like vsnprintf("%lc").
   // Technically vsnprintf can accept a wint_t in this case, but since we must
   // pass a wchar_t to FormatPack, the largest type we can use here is wchar_t.
-  using ArgType =
-      std::conditional_t<std::is_same<T, wchar_t>::value, wchar_t, int>;
+  using ArgType = std::conditional_t<std::is_same_v<T, wchar_t>, wchar_t, int>;
   static const T kMin =
       static_cast<remove_volatile_t>(std::numeric_limits<ArgType>::min());
   static const T kMax = GetMaxForConversion<T>();
diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc
index 30e7982..f69b8ef 100644
--- a/absl/strings/internal/str_format/float_conversion.cc
+++ b/absl/strings/internal/str_format/float_conversion.cc
@@ -1169,8 +1169,7 @@
 #if defined(__clang__) && (__clang_major__ < 9) && !defined(__SSE3__)
       // Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289
       // Casting from long double to uint64_t is miscompiled and drops bits.
-      (!std::is_same<Float, long double>::value ||
-       !std::is_same<Int, uint64_t>::value) &&
+      (!std::is_same_v<Float, long double> || !std::is_same_v<Int, uint64_t>) &&
 #endif
       std::numeric_limits<Float>::digits <= std::numeric_limits<Int>::digits;
 }
@@ -1178,8 +1177,7 @@
 template <typename Float>
 struct Decomposed {
   using MantissaType =
-      std::conditional_t<std::is_same<long double, Float>::value, uint128,
-                         uint64_t>;
+      std::conditional_t<std::is_same_v<long double, Float>, uint128, uint64_t>;
   static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8,
                 "");
   MantissaType mantissa;
diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h
index e802e31..1cec468 100644
--- a/absl/strings/internal/str_split_internal.h
+++ b/absl/strings/internal/str_split_internal.h
@@ -246,20 +246,22 @@
 struct ShouldUseLifetimeBound<
     StringType, Container,
     std::enable_if_t<
-        std::is_same<StringType, std::string>::value &&
-        std::is_same<typename Container::value_type, absl::string_view>::value>>
+        std::is_same_v<StringType, std::string> &&
+        std::is_same_v<typename Container::value_type, absl::string_view>>>
     : std::true_type {};
 
 template <typename StringType, typename First, typename Second>
-using ShouldUseLifetimeBoundForPair = std::integral_constant<
-    bool, std::is_same<StringType, std::string>::value &&
-              (std::is_same<First, absl::string_view>::value ||
-               std::is_same<Second, absl::string_view>::value)>;
+using ShouldUseLifetimeBoundForPair =
+    std::integral_constant<bool,
+                           std::is_same_v<StringType, std::string> &&
+                               (std::is_same_v<First, absl::string_view> ||
+                                std::is_same_v<Second, absl::string_view>)>;
 
 template <typename StringType, typename ElementType, std::size_t Size>
-using ShouldUseLifetimeBoundForArray = std::integral_constant<
-    bool, std::is_same<StringType, std::string>::value &&
-              std::is_same<ElementType, absl::string_view>::value>;
+using ShouldUseLifetimeBoundForArray =
+    std::integral_constant<bool,
+                           std::is_same_v<StringType, std::string> &&
+                               std::is_same_v<ElementType, absl::string_view>>;
 
 // This class implements the range that is returned by absl::StrSplit(). This
 // class has templated conversion operators that allow it to be implicitly
diff --git a/absl/strings/internal/string_constant_test.cc b/absl/strings/internal/string_constant_test.cc
index c8b3591..86914d6 100644
--- a/absl/strings/internal/string_constant_test.cc
+++ b/absl/strings/internal/string_constant_test.cc
@@ -33,12 +33,12 @@
   constexpr auto str = MakeStringConstant(Callable{});
   using T = decltype(str);
 
-  EXPECT_TRUE(std::is_empty<T>::value);
-  EXPECT_TRUE(std::is_trivial<T>::value);
-  EXPECT_TRUE(std::is_trivially_default_constructible<T>::value);
-  EXPECT_TRUE(std::is_trivially_copy_constructible<T>::value);
-  EXPECT_TRUE(std::is_trivially_move_constructible<T>::value);
-  EXPECT_TRUE(std::is_trivially_destructible<T>::value);
+  EXPECT_TRUE(std::is_empty_v<T>);
+  EXPECT_TRUE(std::is_trivial_v<T>);
+  EXPECT_TRUE(std::is_trivially_default_constructible_v<T>);
+  EXPECT_TRUE(std::is_trivially_copy_constructible_v<T>);
+  EXPECT_TRUE(std::is_trivially_move_constructible_v<T>);
+  EXPECT_TRUE(std::is_trivially_destructible_v<T>);
 }
 
 TEST(StringConstant, MakeFromCallable) {
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index b4f81a3..7e9c6bb 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -128,7 +128,7 @@
 
 template <typename int_type>
 constexpr bool is_signed() {
-  if constexpr (std::is_arithmetic<int_type>::value) {
+  if constexpr (std::is_arithmetic_v<int_type>) {
     // Use std::numeric_limits<T>::is_signed where it's defined to work.
     return std::numeric_limits<int_type>::is_signed;
   }
@@ -248,7 +248,7 @@
   static_assert(sizeof(*out) == 1 || sizeof(*out) == 2 || sizeof(*out) == 4 ||
                     sizeof(*out) == 8,
                 "SimpleAtoi works only with 8, 16, 32, or 64-bit integers.");
-  static_assert(!std::is_floating_point<int_type>::value,
+  static_assert(!std::is_floating_point_v<int_type>,
                 "Use SimpleAtof or SimpleAtod instead.");
   bool parsed;
   // These conditions are constexpr bools to suppress MSVC warning C4127.
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index 41f8c73..dd57a88 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -808,7 +808,7 @@
   std::string s;
   absl::strings_internal::OStringStream strm(&s);
   if (in_value >= 0) {
-    if constexpr (std::is_arithmetic<in_val_type>::value) {
+    if constexpr (std::is_arithmetic_v<in_val_type>) {
       absl::StrAppend(&s, absl::Hex(in_value));
     } else {
       // absl::Hex doesn't work with absl::(u)int128.
@@ -833,7 +833,7 @@
   std::string s;
   absl::strings_internal::OStringStream strm(&s);
   if (in_value >= 0) {
-    if constexpr (std::is_arithmetic<in_val_type>::value) {
+    if constexpr (std::is_arithmetic_v<in_val_type>) {
       absl::StrAppend(&s, absl::Hex(in_value));
     } else {
       // absl::Hex doesn't work with absl::(u)int128.
diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h
index 26ed9f8..d682cea 100644
--- a/absl/strings/str_cat.h
+++ b/absl/strings/str_cat.h
@@ -196,28 +196,24 @@
   char fill;
 
   template <typename Int>
-  explicit Hex(
-      Int v, PadSpec spec = absl::kNoPad,
-      std::enable_if_t<sizeof(Int) == 1 && !std::is_pointer<Int>::value, bool> =
-          true)
+  explicit Hex(Int v, PadSpec spec = absl::kNoPad,
+               std::enable_if_t<sizeof(Int) == 1 && !std::is_pointer_v<Int>,
+                                bool> = true)
       : Hex(spec, static_cast<uint8_t>(v)) {}
   template <typename Int>
-  explicit Hex(
-      Int v, PadSpec spec = absl::kNoPad,
-      std::enable_if_t<sizeof(Int) == 2 && !std::is_pointer<Int>::value, bool> =
-          true)
+  explicit Hex(Int v, PadSpec spec = absl::kNoPad,
+               std::enable_if_t<sizeof(Int) == 2 && !std::is_pointer_v<Int>,
+                                bool> = true)
       : Hex(spec, static_cast<uint16_t>(v)) {}
   template <typename Int>
-  explicit Hex(
-      Int v, PadSpec spec = absl::kNoPad,
-      std::enable_if_t<sizeof(Int) == 4 && !std::is_pointer<Int>::value, bool> =
-          true)
+  explicit Hex(Int v, PadSpec spec = absl::kNoPad,
+               std::enable_if_t<sizeof(Int) == 4 && !std::is_pointer_v<Int>,
+                                bool> = true)
       : Hex(spec, static_cast<uint32_t>(v)) {}
   template <typename Int>
-  explicit Hex(
-      Int v, PadSpec spec = absl::kNoPad,
-      std::enable_if_t<sizeof(Int) == 8 && !std::is_pointer<Int>::value, bool> =
-          true)
+  explicit Hex(Int v, PadSpec spec = absl::kNoPad,
+               std::enable_if_t<sizeof(Int) == 8 && !std::is_pointer_v<Int>,
+                                bool> = true)
       : Hex(spec, static_cast<uint64_t>(v)) {}
   template <typename Pointee>
   explicit Hex(Pointee* absl_nullable v, PadSpec spec = absl::kNoPad)
@@ -450,12 +446,12 @@
 
   // vector<bool>::reference and const_reference require special help to
   // convert to `AlphaNum` because it requires two user defined conversions.
-  template <typename T,
-            std::enable_if_t<
-                std::is_class<T>::value &&
-                (std::is_same<T, std::vector<bool>::reference>::value ||
-                 std::is_same<T, std::vector<bool>::const_reference>::value)>* =
-                nullptr>
+  template <
+      typename T,
+      std::enable_if_t<
+          std::is_class_v<T> &&
+          (std::is_same_v<T, std::vector<bool>::reference> ||
+           std::is_same_v<T, std::vector<bool>::const_reference>)>* = nullptr>
   AlphaNum(T e) : AlphaNum(static_cast<bool>(e)) {}  // NOLINT(runtime/explicit)
 
  private:
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h
index b7d446d..d02fe20 100644
--- a/absl/strings/str_format.h
+++ b/absl/strings/str_format.h
@@ -500,8 +500,8 @@
  public:
   // Implicitly convert from any type that provides the hook function as
   // described above.
-  template <typename T, typename = std::enable_if_t<std::is_constructible<
-                            str_format_internal::FormatRawSinkImpl, T*>::value>>
+  template <typename T, typename = std::enable_if_t<std::is_constructible_v<
+                            str_format_internal::FormatRawSinkImpl, T*>>>
   FormatRawSink(T* absl_nonnull raw)  // NOLINT
       : sink_(raw) {}
 
diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h
index d307615..dd9f7f4 100644
--- a/absl/strings/str_join.h
+++ b/absl/strings/str_join.h
@@ -247,9 +247,9 @@
   return strings_internal::JoinRange(range, separator, fmt);
 }
 
-template <typename T, typename Formatter,
-          typename = std::enable_if_t<
-              !std::is_convertible<T, absl::string_view>::value>>
+template <
+    typename T, typename Formatter,
+    typename = std::enable_if_t<!std::is_convertible_v<T, absl::string_view>>>
 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
                     Formatter&& fmt) {
   return strings_internal::JoinRange(il, separator, fmt);
@@ -278,7 +278,7 @@
 }
 
 template <typename T, typename = std::enable_if_t<
-                          !std::is_convertible<T, absl::string_view>::value>>
+                          !std::is_convertible_v<T, absl::string_view>>>
 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) {
   return strings_internal::JoinRange(il, separator);
 }
diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h
index 0856ddc..a0931a8 100644
--- a/absl/strings/str_split.h
+++ b/absl/strings/str_split.h
@@ -389,8 +389,8 @@
 
 template <typename T>
 using EnableSplitIfString =
-    std::enable_if_t<std::is_same<T, std::string>::value ||
-                         std::is_same<T, const std::string>::value,
+    std::enable_if_t<std::is_same_v<T, std::string> ||
+                         std::is_same_v<T, const std::string>,
                      int>;
 
 //------------------------------------------------------------------------------
diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h
index 2dbe334..626d52d 100644
--- a/absl/strings/substitute.h
+++ b/absl/strings/substitute.h
@@ -186,13 +186,12 @@
 
   // vector<bool>::reference and const_reference require special help to convert
   // to `Arg` because it requires two user defined conversions.
-  template <
-      typename T,
-      std::enable_if_t<
-          std::is_class<T>::value &&
-              (std::is_same<T, std::vector<bool>::reference>::value ||
-               std::is_same<T, std::vector<bool>::const_reference>::value),
-          bool> = true>
+  template <typename T,
+            std::enable_if_t<
+                std::is_class_v<T> &&
+                    (std::is_same_v<T, std::vector<bool>::reference> ||
+                     std::is_same_v<T, std::vector<bool>::const_reference>),
+                bool> = true>
   Arg(T value)  // NOLINT(google-explicit-constructor)
       : Arg(static_cast<bool>(value)) {}
 
diff --git a/absl/synchronization/internal/win32_waiter.cc b/absl/synchronization/internal/win32_waiter.cc
index b2fe402..eade1ca 100644
--- a/absl/synchronization/internal/win32_waiter.cc
+++ b/absl/synchronization/internal/win32_waiter.cc
@@ -52,14 +52,14 @@
 
   // The SRWLOCK and CONDITION_VARIABLE types must be trivially constructible
   // and destructible because we never call their constructors or destructors.
-  static_assert(std::is_trivially_constructible<SRWLOCK>::value,
+  static_assert(std::is_trivially_constructible_v<SRWLOCK>,
                 "The `SRWLOCK` type must be trivially constructible");
   static_assert(
-      std::is_trivially_constructible<CONDITION_VARIABLE>::value,
+      std::is_trivially_constructible_v<CONDITION_VARIABLE>,
       "The `CONDITION_VARIABLE` type must be trivially constructible");
-  static_assert(std::is_trivially_destructible<SRWLOCK>::value,
+  static_assert(std::is_trivially_destructible_v<SRWLOCK>,
                 "The `SRWLOCK` type must be trivially destructible");
-  static_assert(std::is_trivially_destructible<CONDITION_VARIABLE>::value,
+  static_assert(std::is_trivially_destructible_v<CONDITION_VARIABLE>,
                 "The `CONDITION_VARIABLE` type must be trivially destructible");
 };
 
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc
index 7b13eec..5663cf6 100644
--- a/absl/synchronization/mutex_test.cc
+++ b/absl/synchronization/mutex_test.cc
@@ -925,11 +925,11 @@
   EXPECT_FALSE(absl::Condition(TemplateEquals43, &const_x).Eval());
 
   // Parameter non-const, argument const is not well-formed.
-  EXPECT_FALSE((std::is_constructible<absl::Condition, decltype(Equals42),
-                                      decltype(&const_x)>::value));
+  EXPECT_FALSE((std::is_constructible_v<absl::Condition, decltype(Equals42),
+                                        decltype(&const_x)>));
   // Validate use of is_constructible by contrasting to a well-formed case.
-  EXPECT_TRUE((std::is_constructible<absl::Condition, decltype(ConstEquals42),
-                                     decltype(&const_x)>::value));
+  EXPECT_TRUE((std::is_constructible_v<absl::Condition, decltype(ConstEquals42),
+                                       decltype(&const_x)>));
 }
 
 // Example base and derived class for use in predicates and test below. Not a
@@ -973,15 +973,15 @@
 
   // Parameter derived, argument base is not well-formed.
   bool (*derived_pred)(const Derived *) = [](const Derived *) { return true; };
-  EXPECT_FALSE((std::is_constructible<absl::Condition, decltype(derived_pred),
-                                      Base *>::value));
-  EXPECT_FALSE((std::is_constructible<absl::Condition, decltype(derived_pred),
-                                      const Base *>::value));
+  EXPECT_FALSE((
+      std::is_constructible_v<absl::Condition, decltype(derived_pred), Base*>));
+  EXPECT_FALSE((std::is_constructible_v<absl::Condition, decltype(derived_pred),
+                                        const Base*>));
   // Validate use of is_constructible by contrasting to well-formed cases.
-  EXPECT_TRUE((std::is_constructible<absl::Condition, decltype(derived_pred),
-                                     Derived *>::value));
-  EXPECT_TRUE((std::is_constructible<absl::Condition, decltype(derived_pred),
-                                     const Derived *>::value));
+  EXPECT_TRUE((std::is_constructible_v<absl::Condition, decltype(derived_pred),
+                                       Derived*>));
+  EXPECT_TRUE((std::is_constructible_v<absl::Condition, decltype(derived_pred),
+                                       const Derived*>));
 }
 
 struct Constable {
diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc
index a0cb29c..59c04d3 100644
--- a/absl/time/civil_time_test.cc
+++ b/absl/time/civil_time_test.cc
@@ -217,32 +217,25 @@
   EXPECT_EQ(month, year);
 
   // Ensures unsafe conversions are not allowed.
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilSecond, absl::CivilMinute>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilSecond, absl::CivilHour>::value));
-  EXPECT_FALSE((std::is_convertible<absl::CivilSecond, absl::CivilDay>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilSecond, absl::CivilMonth>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilSecond, absl::CivilYear>::value));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilSecond, absl::CivilMinute>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilSecond, absl::CivilHour>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilSecond, absl::CivilDay>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilSecond, absl::CivilMonth>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilSecond, absl::CivilYear>));
 
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilMinute, absl::CivilHour>::value));
-  EXPECT_FALSE((std::is_convertible<absl::CivilMinute, absl::CivilDay>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilMinute, absl::CivilMonth>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<absl::CivilMinute, absl::CivilYear>::value));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilMinute, absl::CivilHour>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilMinute, absl::CivilDay>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilMinute, absl::CivilMonth>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilMinute, absl::CivilYear>));
 
-  EXPECT_FALSE((std::is_convertible<absl::CivilHour, absl::CivilDay>::value));
-  EXPECT_FALSE((std::is_convertible<absl::CivilHour, absl::CivilMonth>::value));
-  EXPECT_FALSE((std::is_convertible<absl::CivilHour, absl::CivilYear>::value));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilHour, absl::CivilDay>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilHour, absl::CivilMonth>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilHour, absl::CivilYear>));
 
-  EXPECT_FALSE((std::is_convertible<absl::CivilDay, absl::CivilMonth>::value));
-  EXPECT_FALSE((std::is_convertible<absl::CivilDay, absl::CivilYear>::value));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilDay, absl::CivilMonth>));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilDay, absl::CivilYear>));
 
-  EXPECT_FALSE((std::is_convertible<absl::CivilMonth, absl::CivilYear>::value));
+  EXPECT_FALSE((std::is_convertible_v<absl::CivilMonth, absl::CivilYear>));
 }
 
 TEST(CivilTime, ExplicitCrossAlignment) {
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc
index dc14665..f56df40 100644
--- a/absl/time/duration_test.cc
+++ b/absl/time/duration_test.cc
@@ -74,7 +74,7 @@
 }
 
 TEST(Duration, ConstExpr) {
-  static_assert(std::is_trivially_destructible<absl::Duration>::value,
+  static_assert(std::is_trivially_destructible_v<absl::Duration>,
                 "Duration is documented as being trivially destructible");
   constexpr absl::Duration d0 = absl::ZeroDuration();
   static_assert(d0 == absl::ZeroDuration(), "ZeroDuration()");
diff --git a/absl/time/time.h b/absl/time/time.h
index 532aab2..03cf67a 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -135,9 +135,9 @@
                                                            std::ratio<3600>);
 template <typename T>
 using EnableIfIntegral =
-    std::enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value, int>;
+    std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>, int>;
 template <typename T>
-using EnableIfFloat = std::enable_if_t<std::is_floating_point<T>::value, int>;
+using EnableIfFloat = std::enable_if_t<std::is_floating_point_v<T>, int>;
 }  // namespace time_internal
 
 // Duration
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 6714a27..35b1f0e 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -92,7 +92,7 @@
 }
 
 TEST(Time, ConstExpr) {
-  static_assert(std::is_trivially_destructible<absl::Time>::value,
+  static_assert(std::is_trivially_destructible_v<absl::Time>,
                 "Time is documented as being trivially destructible");
   constexpr absl::Time t0 = absl::UnixEpoch();
   static_assert(t0 == absl::UnixEpoch(), "UnixEpoch");
diff --git a/absl/types/any_span.h b/absl/types/any_span.h
index cf0f4ed..bca47bc 100644
--- a/absl/types/any_span.h
+++ b/absl/types/any_span.h
@@ -288,8 +288,8 @@
 class Range {
  public:
   static_assert(
-      std::is_same<typename std::iterator_traits<Iter>::iterator_category,
-                   std::random_access_iterator_tag>::value,
+      std::is_same_v<typename std::iterator_traits<Iter>::iterator_category,
+                     std::random_access_iterator_tag>,
       "Iter must be a random access iterator.");
 
   Range(Iter begin, Iter end) {
@@ -339,10 +339,10 @@
   class IteratorBase;
 
   template <typename U>
-  using EnableIfMutable = std::enable_if_t<!std::is_const<T>::value, U>;
+  using EnableIfMutable = std::enable_if_t<!std::is_const_v<T>, U>;
 
   template <typename U>
-  using EnableIfConst = std::enable_if_t<std::is_const<T>::value, U>;
+  using EnableIfConst = std::enable_if_t<std::is_const_v<T>, U>;
 
   static std::true_type CreatesATemporaryImpl(std::decay_t<T>&&);
   static std::false_type CreatesATemporaryImpl(const T&);
@@ -373,8 +373,8 @@
 
   template <typename Element>
   using EnableIfDifferentElementType =
-      std::enable_if_t<!std::is_same<T, Element>::value &&
-                       !std::is_same<T, const Element>::value>;
+      std::enable_if_t<!std::is_same_v<T, Element> &&
+                       !std::is_same_v<T, const Element>>;
 
   template <typename Transform>
   using EnableIfTransformIsByCopy =
diff --git a/absl/types/any_span_test.cc b/absl/types/any_span_test.cc
index b4f9a82..e5960c6 100644
--- a/absl/types/any_span_test.cc
+++ b/absl/types/any_span_test.cc
@@ -777,9 +777,9 @@
   using T = typename TestFixture::template MaybeConst<std::string>;
   // Note: we could use is_trivially_copyable, but it is not implemented in
   // Crosstool v18 which is the current version at the time of writing.
-  EXPECT_TRUE(std::is_trivially_copy_constructible<AnySpan<T>>::value);
-  EXPECT_TRUE(std::is_trivially_copy_assignable<AnySpan<T>>::value);
-  EXPECT_TRUE(std::is_trivially_destructible<AnySpan<T>>::value);
+  EXPECT_TRUE(std::is_trivially_copy_constructible_v<AnySpan<T>>);
+  EXPECT_TRUE(std::is_trivially_copy_assignable_v<AnySpan<T>>);
+  EXPECT_TRUE(std::is_trivially_destructible_v<AnySpan<T>>);
 }
 
 TYPED_TEST(AnySpanTest, IsConstructible) {
@@ -788,16 +788,16 @@
   using VectorT =
       typename TestFixture::template MaybeConst<std::vector<std::string>>;
   using VectorU = typename TestFixture::template MaybeConst<std::vector<int>>;
-  EXPECT_FALSE((std::is_constructible<AnySpan<T>, T>::value));
-  EXPECT_FALSE((std::is_constructible<AnySpan<T>, T*>::value));
-  EXPECT_FALSE((std::is_constructible<AnySpan<T>, U>::value));
-  EXPECT_FALSE((std::is_constructible<AnySpan<T>, U(&)[5]>::value));
-  EXPECT_FALSE((std::is_constructible<AnySpan<T>, U*, std::size_t>::value));
-  EXPECT_FALSE((std::is_constructible<AnySpan<T>, VectorU&>::value));
+  EXPECT_FALSE((std::is_constructible_v<AnySpan<T>, T>));
+  EXPECT_FALSE((std::is_constructible_v<AnySpan<T>, T*>));
+  EXPECT_FALSE((std::is_constructible_v<AnySpan<T>, U>));
+  EXPECT_FALSE((std::is_constructible_v<AnySpan<T>, U(&)[5]>));
+  EXPECT_FALSE((std::is_constructible_v<AnySpan<T>, U*, std::size_t>));
+  EXPECT_FALSE((std::is_constructible_v<AnySpan<T>, VectorU&>));
 
-  EXPECT_TRUE((std::is_constructible<AnySpan<T>, VectorT&>::value));
-  EXPECT_TRUE((std::is_constructible<AnySpan<T>, T(&)[5]>::value));
-  EXPECT_TRUE((std::is_constructible<AnySpan<T>, T*, std::size_t>::value));
+  EXPECT_TRUE((std::is_constructible_v<AnySpan<T>, VectorT&>));
+  EXPECT_TRUE((std::is_constructible_v<AnySpan<T>, T(&)[5]>));
+  EXPECT_TRUE((std::is_constructible_v<AnySpan<T>, T*, std::size_t>));
 }
 
 //
diff --git a/absl/types/compare.h b/absl/types/compare.h
index 55dd277..be59d92 100644
--- a/absl/types/compare.h
+++ b/absl/types/compare.h
@@ -91,10 +91,9 @@
   // has type `int`. Literal `0` arguments will be implicitly converted to
   // `std::nullptr_t` and accepted by the above constructor, while other `int`
   // arguments will fail to be converted and cause compilation failure.
-  template <typename T,
-            typename = std::enable_if_t<
-                std::is_same<T, std::nullptr_t>::value ||
-                (std::is_integral<T>::value && !std::is_same<T, int>::value)>>
+  template <typename T, typename = std::enable_if_t<
+                            std::is_same_v<T, std::nullptr_t> ||
+                            (std::is_integral_v<T> && !std::is_same_v<T, int>)>>
   OnlyLiteralZero(T) {  // NOLINT
     static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
   }
@@ -449,7 +448,7 @@
 // or three-way comparator.
 // SFINAE prevents implicit conversions to bool (such as from int).
 template <typename BoolT,
-          std::enable_if_t<std::is_same<bool, BoolT>::value, int> = 0>
+          std::enable_if_t<std::is_same_v<bool, BoolT>, int> = 0>
 constexpr bool compare_result_as_less_than(const BoolT r) {
   return r;
 }
@@ -466,8 +465,7 @@
 // Helper functions to do a three-way comparison of two keys given a boolean or
 // three-way comparator.
 // SFINAE prevents implicit conversions to int (such as from bool).
-template <typename Int,
-          std::enable_if_t<std::is_same<int, Int>::value, int> = 0>
+template <typename Int, std::enable_if_t<std::is_same_v<int, Int>, int> = 0>
 constexpr absl::weak_ordering compare_result_as_ordering(const Int c) {
   return c < 0    ? absl::weak_ordering::less
          : c == 0 ? absl::weak_ordering::equivalent
@@ -478,20 +476,20 @@
   return c;
 }
 
-template <typename Compare, typename K, typename LK,
-          std::enable_if_t<
-              !std::is_same<
-                  bool, absl::result_of_t<Compare(const K&, const LK&)>>::value,
-              int> = 0>
+template <
+    typename Compare, typename K, typename LK,
+    std::enable_if_t<
+        !std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>,
+        int> = 0>
 constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
                                                       const K& x, const LK& y) {
   return compare_result_as_ordering(compare(x, y));
 }
-template <typename Compare, typename K, typename LK,
-          std::enable_if_t<
-              std::is_same<
-                  bool, absl::result_of_t<Compare(const K&, const LK&)>>::value,
-              int> = 0>
+template <
+    typename Compare, typename K, typename LK,
+    std::enable_if_t<
+        std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>,
+        int> = 0>
 constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
                                                       const K& x, const LK& y) {
   return compare(x, y)   ? absl::weak_ordering::less
diff --git a/absl/types/internal/any_span.h b/absl/types/internal/any_span.h
index fccd1be..cd0e4c4 100644
--- a/absl/types/internal/any_span.h
+++ b/absl/types/internal/any_span.h
@@ -261,7 +261,7 @@
 
   // Handle mutable -> const conversion.
   template <typename LazyT = T,
-            typename = std::enable_if_t<std::is_const<LazyT>::value>>
+            typename = std::enable_if_t<std::is_const_v<LazyT>>>
   explicit Getter(const Getter<std::remove_const_t<T>>& other) {
     using MutableT = std::remove_const_t<T>;
     if (other.fun == &ArrayTag<MutableT>) {
@@ -450,7 +450,7 @@
 Getter<T> MakeContainerGetter(
     Container& container,  // NOLINT(runtime/references)
     const Transform& transform) {
-  static_assert(std::is_reference<decltype(container[0])>::value,
+  static_assert(std::is_reference_v<decltype(container[0])>,
                 "AnySpan only works with containers that return a reference "
                 "(no vector<bool>, or containers that return by value).");
   return MakeContainerGetterImpl<T>(DataIsValid<Container>(), container,
@@ -466,7 +466,7 @@
 
 template <typename T>
 bool EqualImpl(AnySpan<T> a, AnySpan<T> b) {
-  static_assert(std::is_const<T>::value, "");
+  static_assert(std::is_const_v<T>, "");
   return std::equal(a.begin(), a.end(), b.begin(), b.end());
 }
 
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h
index 0812619..148c957 100644
--- a/absl/types/internal/span.h
+++ b/absl/types/internal/span.h
@@ -82,11 +82,11 @@
 using ElementT = typename ElementType<C>::type;
 
 template <typename T>
-using EnableIfMutable = std::enable_if_t<!std::is_const<T>::value, int>;
+using EnableIfMutable = std::enable_if_t<!std::is_const_v<T>, int>;
 
 template <template <typename> class SpanT, typename T>
 constexpr bool EqualImpl(SpanT<T> a, SpanT<T> b) {
-  static_assert(std::is_const<T>::value, "");
+  static_assert(std::is_const_v<T>, "");
   return std::equal(a.begin(), a.end(), b.begin(), b.end());
 }
 
@@ -94,13 +94,12 @@
 constexpr 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, "");
+  static_assert(std::is_const_v<T>, "");
   return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
 }
 
 template <typename From, typename To>
-using EnableIfConvertibleTo =
-    std::enable_if_t<std::is_convertible<From, To>::value>;
+using EnableIfConvertibleTo = std::enable_if_t<std::is_convertible_v<From, To>>;
 
 // IsView is true for types where the return type of .data() is the same for
 // mutable and const instances. This isn't foolproof, but it's only used to
@@ -121,7 +120,7 @@
   using MutData = decltype(span_internal::GetData(std::declval<Container&>()));
 
  public:
-  static constexpr bool value = std::is_same<ConstData, MutData>::value;
+  static constexpr bool value = std::is_same_v<ConstData, MutData>;
 };
 
 // These enablers result in 'int' so they can be used as typenames or defaults
diff --git a/absl/types/span.h b/absl/types/span.h
index 0f78f5e..3b291a9 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -195,11 +195,11 @@
 
   // Used to SFINAE-enable a function when the slice elements are const.
   template <typename U>
-  using EnableIfValueIsConst = std::enable_if_t<std::is_const<T>::value, U>;
+  using EnableIfValueIsConst = std::enable_if_t<std::is_const_v<T>, U>;
 
   // Used to SFINAE-enable a function when the slice elements are mutable.
   template <typename U>
-  using EnableIfValueIsMutable = std::enable_if_t<!std::is_const<T>::value, U>;
+  using EnableIfValueIsMutable = std::enable_if_t<!std::is_const_v<T>, U>;
 
  public:
   using element_type = T;
diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc
index 21b49ed..5a8b82e 100644
--- a/absl/types/span_test.cc
+++ b/absl/types/span_test.cc
@@ -94,13 +94,11 @@
   absl::Span<int> s(a);
   EXPECT_THAT(s, SpanIs(a, 3));
 
-  EXPECT_TRUE((std::is_constructible<absl::Span<const int>, int[3]>::value));
-  EXPECT_TRUE(
-      (std::is_constructible<absl::Span<const int>, const int[3]>::value));
-  EXPECT_FALSE((std::is_constructible<absl::Span<int>, const int[3]>::value));
-  EXPECT_TRUE((std::is_convertible<int[3], absl::Span<const int>>::value));
-  EXPECT_TRUE(
-      (std::is_convertible<const int[3], absl::Span<const int>>::value));
+  EXPECT_TRUE((std::is_constructible_v<absl::Span<const int>, int[3]>));
+  EXPECT_TRUE((std::is_constructible_v<absl::Span<const int>, const int[3]>));
+  EXPECT_FALSE((std::is_constructible_v<absl::Span<int>, const int[3]>));
+  EXPECT_TRUE((std::is_convertible_v<int[3], absl::Span<const int>>));
+  EXPECT_TRUE((std::is_convertible_v<const int[3], absl::Span<const int>>));
 }
 
 template <typename T>
@@ -125,9 +123,8 @@
   EXPECT_THAT(const_from_span, SpanIs(s_filled));
 
   EXPECT_TRUE(
-      (std::is_convertible<std::vector<int>&, absl::Span<const int>>::value));
-  EXPECT_TRUE(
-      (std::is_convertible<absl::Span<int>&, absl::Span<const int>>::value));
+      (std::is_convertible_v<std::vector<int>&, absl::Span<const int>>));
+  EXPECT_TRUE((std::is_convertible_v<absl::Span<int>&, absl::Span<const int>>));
 
   TakesGenericSpan(absl::Span<int>(filled));
 }
@@ -159,22 +156,20 @@
   absl::Span<const char> s_const_abc = abc;
   EXPECT_THAT(s_const_abc, SpanIs(abc));
 
-  EXPECT_FALSE((std::is_constructible<absl::Span<int>, std::string>::value));
-  EXPECT_FALSE(
-      (std::is_constructible<absl::Span<const int>, std::string>::value));
-  EXPECT_TRUE(
-      (std::is_convertible<std::string, absl::Span<const char>>::value));
+  EXPECT_FALSE((std::is_constructible_v<absl::Span<int>, std::string>));
+  EXPECT_FALSE((std::is_constructible_v<absl::Span<const int>, std::string>));
+  EXPECT_TRUE((std::is_convertible_v<std::string, absl::Span<const char>>));
 }
 
 TEST(IntSpan, FromConstPointer) {
-  EXPECT_TRUE((std::is_constructible<absl::Span<const int* const>,
-                                     std::vector<int*>>::value));
-  EXPECT_TRUE((std::is_constructible<absl::Span<const int* const>,
-                                     std::vector<const int*>>::value));
-  EXPECT_FALSE((
-      std::is_constructible<absl::Span<const int*>, std::vector<int*>>::value));
-  EXPECT_FALSE((
-      std::is_constructible<absl::Span<int*>, std::vector<const int*>>::value));
+  EXPECT_TRUE((std::is_constructible_v<absl::Span<const int* const>,
+                                       std::vector<int*>>));
+  EXPECT_TRUE((std::is_constructible_v<absl::Span<const int* const>,
+                                       std::vector<const int*>>));
+  EXPECT_FALSE(
+      (std::is_constructible_v<absl::Span<const int*>, std::vector<int*>>));
+  EXPECT_FALSE(
+      (std::is_constructible_v<absl::Span<int*>, std::vector<const int*>>));
 }
 
 struct TypeWithMisleadingData {
@@ -191,9 +186,9 @@
 
 TEST(IntSpan, EvilTypes) {
   EXPECT_FALSE(
-      (std::is_constructible<absl::Span<int>, TypeWithMisleadingData&>::value));
+      (std::is_constructible_v<absl::Span<int>, TypeWithMisleadingData&>));
   EXPECT_FALSE(
-      (std::is_constructible<absl::Span<int>, TypeWithMisleadingSize&>::value));
+      (std::is_constructible_v<absl::Span<int>, TypeWithMisleadingSize&>));
 }
 
 struct Base {
@@ -204,10 +199,10 @@
 struct Derived : Base {};
 
 TEST(IntSpan, SpanOfDerived) {
-  EXPECT_TRUE((std::is_constructible<absl::Span<int>, Base&>::value));
-  EXPECT_TRUE((std::is_constructible<absl::Span<int>, Derived&>::value));
+  EXPECT_TRUE((std::is_constructible_v<absl::Span<int>, Base&>));
+  EXPECT_TRUE((std::is_constructible_v<absl::Span<int>, Derived&>));
   EXPECT_FALSE(
-      (std::is_constructible<absl::Span<Base>, std::vector<Derived>>::value));
+      (std::is_constructible_v<absl::Span<Base>, std::vector<Derived>>));
 }
 
 void TestInitializerList(absl::Span<const int> s, const std::vector<int>& v) {
@@ -219,10 +214,10 @@
   TestInitializerList({1}, {1});
   TestInitializerList({1, 2, 3}, {1, 2, 3});
 
-  EXPECT_FALSE((std::is_constructible<absl::Span<int>,
-                                      std::initializer_list<int>>::value));
-  EXPECT_FALSE((
-      std::is_convertible<absl::Span<int>, std::initializer_list<int>>::value));
+  EXPECT_FALSE(
+      (std::is_constructible_v<absl::Span<int>, std::initializer_list<int>>));
+  EXPECT_FALSE(
+      (std::is_convertible_v<absl::Span<int>, std::initializer_list<int>>));
 }
 
 TEST(IntSpan, Data) {
@@ -668,16 +663,15 @@
 TEST(IntSpan, ExposesContainerTypesAndConsts) {
   absl::Span<int> slice;
   CheckType<absl::Span<int>::iterator>(slice.begin());
-  EXPECT_TRUE((std::is_convertible<decltype(slice.begin()),
-                                   absl::Span<int>::const_iterator>::value));
+  EXPECT_TRUE((std::is_convertible_v<decltype(slice.begin()),
+                                     absl::Span<int>::const_iterator>));
   CheckType<absl::Span<int>::const_iterator>(slice.cbegin());
-  EXPECT_TRUE((std::is_convertible<decltype(slice.end()),
-                                   absl::Span<int>::const_iterator>::value));
+  EXPECT_TRUE((std::is_convertible_v<decltype(slice.end()),
+                                     absl::Span<int>::const_iterator>));
   CheckType<absl::Span<int>::const_iterator>(slice.cend());
   CheckType<absl::Span<int>::reverse_iterator>(slice.rend());
-  EXPECT_TRUE(
-      (std::is_convertible<decltype(slice.rend()),
-                           absl::Span<int>::const_reverse_iterator>::value));
+  EXPECT_TRUE((std::is_convertible_v<decltype(slice.rend()),
+                                     absl::Span<int>::const_reverse_iterator>));
   CheckType<absl::Span<int>::const_reverse_iterator>(slice.crend());
   testing::StaticAssertTypeEq<int, absl::Span<int>::value_type>();
   testing::StaticAssertTypeEq<int, absl::Span<const int>::value_type>();