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
This commit is contained in:
Jesse Rosenstock
2025-09-29 12:00:28 -07:00
committed by Copybara-Service
parent b2574e9da3
commit 820cd9ee90
11 changed files with 45 additions and 54 deletions

View File

@@ -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"

View File

@@ -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,

View File

@@ -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}

View File

@@ -33,7 +33,6 @@
#include <bit> // 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 <typename To>
constexpr To implicit_cast(typename absl::internal::type_identity_t<To> to) {
constexpr To implicit_cast(typename absl::type_identity_t<To> to) {
return to;
}

View File

@@ -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 <typename T>
struct type_identity {
typedef T type;
};
// This is a back-fill of C++20's `std::type_identity_t`.
template <typename T>
using type_identity_t = typename type_identity<T>::type;
} // namespace internal
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_BASE_INTERNAL_IDENTITY_H_

View File

@@ -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 <typename A, typename ValueAdapter>
void ConstructElements(absl::internal::type_identity_t<A>& allocator,
void ConstructElements(absl::type_identity_t<A>& allocator,
Pointer<A> construct_first, ValueAdapter& values,
SizeType<A> construct_size) {
for (SizeType<A> i = 0; i < construct_size; ++i) {

View File

@@ -169,6 +169,28 @@ template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;
#endif
#if defined(__cpp_lib_type_identity) && __cpp_lib_type_identity >= 201806L
template <typename T>
using type_identity = std::type_identity<T>;
template <typename T>
using type_identity_t = std::type_identity_t<T>;
#else
// type_identity
//
// Back-fill of C++20's `std::type_identity`.
template <typename T>
struct type_identity {
typedef T type;
};
// type_identity_t
//
// Back-fill of C++20's `std::type_identity_t`.
template <typename T>
using type_identity_t = typename type_identity<T>::type;
#endif
namespace type_traits_internal {
#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \

View File

@@ -137,6 +137,17 @@ TEST(TypeTraitsTest, TestRemoveCVRef) {
int[2]>::value));
}
TEST(TypeTraitsTest, TestTypeIdentity) {
EXPECT_TRUE((std::is_same_v<typename absl::type_identity<int>::type, int>));
EXPECT_TRUE((std::is_same_v<absl::type_identity_t<int>, int>));
EXPECT_TRUE((std::is_same_v<typename absl::type_identity<int&>::type, int&>));
EXPECT_TRUE((std::is_same_v<absl::type_identity_t<int&>, int&>));
EXPECT_FALSE(
(std::is_same_v<typename absl::type_identity<int64_t>::type, int32_t>));
EXPECT_FALSE((std::is_same_v<absl::type_identity_t<int64_t>, int32_t>));
}
struct TypeA {};
struct TypeB {};
struct TypeC {};

View File

@@ -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": [],

View File

@@ -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

View File

@@ -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 <typename T, typename = void>
Condition(
bool (*absl_nonnull func)(T* absl_nullability_unknown),
typename absl::internal::type_identity<T>::type* absl_nullability_unknown
typename absl::type_identity<T>::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 <typename T>
Condition(
T* absl_nonnull object,
bool (absl::internal::type_identity<T>::type::* absl_nonnull method)());
bool (absl::type_identity<T>::type::* absl_nonnull method)());
// Same as above, for const members
template <typename T>
Condition(
const T* absl_nonnull object,
bool (absl::internal::type_identity<T>::type::* absl_nonnull method)()
bool (absl::type_identity<T>::type::* absl_nonnull method)()
const);
// A Condition that returns the value of `*cond`
@@ -1183,7 +1183,7 @@ inline Condition::Condition(
template <typename T, typename>
inline Condition::Condition(
bool (*absl_nonnull func)(T* absl_nullability_unknown),
typename absl::internal::type_identity<T>::type* absl_nullability_unknown
typename absl::type_identity<T>::type* absl_nullability_unknown
arg)
// Just delegate to the overload above.
: Condition(func, arg) {}
@@ -1191,7 +1191,7 @@ inline Condition::Condition(
template <typename T>
inline Condition::Condition(
T* absl_nonnull object,
bool (absl::internal::type_identity<T>::type::* absl_nonnull method)())
bool (absl::type_identity<T>::type::* absl_nonnull method)())
: eval_(&CastAndCallMethod<T, decltype(method)>), arg_(object) {
static_assert(sizeof(&method) <= sizeof(callback_),
"An overlarge method pointer was passed to Condition.");
@@ -1201,7 +1201,7 @@ inline Condition::Condition(
template <typename T>
inline Condition::Condition(
const T* absl_nonnull object,
bool (absl::internal::type_identity<T>::type::* absl_nonnull method)()
bool (absl::type_identity<T>::type::* absl_nonnull method)()
const)
: eval_(&CastAndCallMethod<const T, decltype(method)>),
arg_(reinterpret_cast<void*>(const_cast<T*>(object))) {