From 820cd9ee904158c1395d4198bd568145715537aa Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock Date: Mon, 29 Sep 2025 12:00:28 -0700 Subject: [PATCH] type_traits: Add type_identity and type_traits_t backfills https://en.cppreference.com/w/cpp/types/type_identity.html PiperOrigin-RevId: 812886166 Change-Id: I159cf4e4bdbe2ac801768ff6c996c2d2a3d47a71 --- CMake/AbseilDll.cmake | 1 - absl/base/BUILD.bazel | 1 - absl/base/CMakeLists.txt | 1 - absl/base/casts.h | 3 +- absl/base/internal/identity.h | 39 ------------------------ absl/container/internal/inlined_vector.h | 3 +- absl/meta/type_traits.h | 22 +++++++++++++ absl/meta/type_traits_test.cc | 11 +++++++ absl/synchronization/BUILD.bazel | 1 + absl/synchronization/CMakeLists.txt | 1 + absl/synchronization/mutex.h | 16 +++++----- 11 files changed, 45 insertions(+), 54 deletions(-) delete mode 100644 absl/base/internal/identity.h diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index 55bd0542..ac23f254 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -20,7 +20,6 @@ set(ABSL_INTERNAL_DLL_FILES "base/internal/endian.h" "base/internal/errno_saver.h" "base/internal/hide_ptr.h" - "base/internal/identity.h" "base/internal/iterator_traits.h" "base/internal/low_level_alloc.cc" "base/internal/low_level_alloc.h" diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index c68883ea..87551224 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -244,7 +244,6 @@ cc_library( name = "base_internal", hdrs = [ "internal/hide_ptr.h", - "internal/identity.h", "internal/scheduling_mode.h", ], copts = ABSL_DEFAULT_COPTS, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 9dca9896..f90b6b0b 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -240,7 +240,6 @@ absl_cc_library( base_internal HDRS "internal/hide_ptr.h" - "internal/identity.h" "internal/scheduling_mode.h" COPTS ${ABSL_DEFAULT_COPTS} diff --git a/absl/base/casts.h b/absl/base/casts.h index e0b11bbe..fc4ec6a7 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h @@ -33,7 +33,6 @@ #include // For std::bit_cast. #endif // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L -#include "absl/base/internal/identity.h" #include "absl/base/macros.h" #include "absl/meta/type_traits.h" @@ -90,7 +89,7 @@ ABSL_NAMESPACE_BEGIN // // Such implicit cast chaining may be useful within template logic. template -constexpr To implicit_cast(typename absl::internal::type_identity_t to) { +constexpr To implicit_cast(typename absl::type_identity_t to) { return to; } diff --git a/absl/base/internal/identity.h b/absl/base/internal/identity.h deleted file mode 100644 index 365207b7..00000000 --- a/absl/base/internal/identity.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef ABSL_BASE_INTERNAL_IDENTITY_H_ -#define ABSL_BASE_INTERNAL_IDENTITY_H_ - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace internal { - -// This is a back-fill of C++20's `std::type_identity`. -template -struct type_identity { - typedef T type; -}; - -// This is a back-fill of C++20's `std::type_identity_t`. -template -using type_identity_t = typename type_identity::type; - -} // namespace internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_BASE_INTERNAL_IDENTITY_H_ diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index b0d3f077..85e8960e 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -27,7 +27,6 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" -#include "absl/base/internal/identity.h" #include "absl/base/macros.h" #include "absl/container/internal/compressed_tuple.h" #include "absl/memory/memory.h" @@ -127,7 +126,7 @@ struct MallocAdapter { }; template -void ConstructElements(absl::internal::type_identity_t& allocator, +void ConstructElements(absl::type_identity_t& allocator, Pointer construct_first, ValueAdapter& values, SizeType construct_size) { for (SizeType i = 0; i < construct_size; ++i) { diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index e2f4600f..59eb38ba 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -169,6 +169,28 @@ template using remove_cvref_t = typename remove_cvref::type; #endif +#if defined(__cpp_lib_type_identity) && __cpp_lib_type_identity >= 201806L +template +using type_identity = std::type_identity; + +template +using type_identity_t = std::type_identity_t; +#else +// type_identity +// +// Back-fill of C++20's `std::type_identity`. +template +struct type_identity { + typedef T type; +}; + +// type_identity_t +// +// Back-fill of C++20's `std::type_identity_t`. +template +using type_identity_t = typename type_identity::type; +#endif + namespace type_traits_internal { #if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \ diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index 81422903..9a8262d8 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -137,6 +137,17 @@ TEST(TypeTraitsTest, TestRemoveCVRef) { int[2]>::value)); } +TEST(TypeTraitsTest, TestTypeIdentity) { + EXPECT_TRUE((std::is_same_v::type, int>)); + EXPECT_TRUE((std::is_same_v, int>)); + EXPECT_TRUE((std::is_same_v::type, int&>)); + EXPECT_TRUE((std::is_same_v, int&>)); + + EXPECT_FALSE( + (std::is_same_v::type, int32_t>)); + EXPECT_FALSE((std::is_same_v, int32_t>)); +} + struct TypeA {}; struct TypeB {}; struct TypeC {}; diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 9a1aa833..9c6b31a2 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -148,6 +148,7 @@ cc_library( "//absl/base:tracing_internal", "//absl/debugging:stacktrace", "//absl/debugging:symbolize", + "//absl/meta:type_traits", "//absl/time", ] + select({ "//conditions:default": [], diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index ad45515c..9c4a0b1f 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -109,6 +109,7 @@ absl_cc_library( absl::core_headers absl::dynamic_annotations absl::malloc_internal + absl::meta absl::nullability absl::raw_logging_internal absl::stacktrace diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 20624860..10fafcb4 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -65,12 +65,12 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/const_init.h" -#include "absl/base/internal/identity.h" #include "absl/base/internal/thread_identity.h" #include "absl/base/internal/tsan_mutex_interface.h" #include "absl/base/macros.h" #include "absl/base/nullability.h" #include "absl/base/thread_annotations.h" +#include "absl/meta/type_traits.h" #include "absl/synchronization/internal/kernel_timeout.h" #include "absl/synchronization/internal/per_thread_sem.h" #include "absl/time/time.h" @@ -794,7 +794,7 @@ class Condition { template Condition( bool (*absl_nonnull func)(T* absl_nullability_unknown), - typename absl::internal::type_identity::type* absl_nullability_unknown + typename absl::type_identity::type* absl_nullability_unknown arg); // Templated version for invoking a method that returns a `bool`. @@ -802,19 +802,19 @@ class Condition { // `Condition(object, &Class::Method)` constructs a `Condition` that evaluates // `object->Method()`. // - // Implementation Note: `absl::internal::type_identity` is used to allow + // Implementation Note: `absl::type_identity` is used to allow // methods to come from base classes. A simpler signature like // `Condition(T*, bool (T::*)())` does not suffice. template Condition( T* absl_nonnull object, - bool (absl::internal::type_identity::type::* absl_nonnull method)()); + bool (absl::type_identity::type::* absl_nonnull method)()); // Same as above, for const members template Condition( const T* absl_nonnull object, - bool (absl::internal::type_identity::type::* absl_nonnull method)() + bool (absl::type_identity::type::* absl_nonnull method)() const); // A Condition that returns the value of `*cond` @@ -1183,7 +1183,7 @@ inline Condition::Condition( template inline Condition::Condition( bool (*absl_nonnull func)(T* absl_nullability_unknown), - typename absl::internal::type_identity::type* absl_nullability_unknown + typename absl::type_identity::type* absl_nullability_unknown arg) // Just delegate to the overload above. : Condition(func, arg) {} @@ -1191,7 +1191,7 @@ inline Condition::Condition( template inline Condition::Condition( T* absl_nonnull object, - bool (absl::internal::type_identity::type::* absl_nonnull method)()) + bool (absl::type_identity::type::* absl_nonnull method)()) : eval_(&CastAndCallMethod), arg_(object) { static_assert(sizeof(&method) <= sizeof(callback_), "An overlarge method pointer was passed to Condition."); @@ -1201,7 +1201,7 @@ inline Condition::Condition( template inline Condition::Condition( const T* absl_nonnull object, - bool (absl::internal::type_identity::type::* absl_nonnull method)() + bool (absl::type_identity::type::* absl_nonnull method)() const) : eval_(&CastAndCallMethod), arg_(reinterpret_cast(const_cast(object))) {