mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
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:
committed by
Copybara-Service
parent
b2574e9da3
commit
820cd9ee90
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) || \
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
@@ -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": [],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
Reference in New Issue
Block a user