mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
type_traits: provide a better fallback for is_trivially_relocatable.
We can do a lot better than always saying "no" on platforms without the __is_trivially_relocatable builtin. This will allow using this type trait from the move constructors of InlinedVector in a future CL, without needing to open code the fallback logic. PiperOrigin-RevId: 519281125 Change-Id: I0d55f019331966f58074850d6f77c7eab49f2c53
This commit is contained in:
committed by
Copybara-Service
parent
32e0395f38
commit
b6a1039bfc
@@ -497,12 +497,20 @@ using swap_internal::StdSwapIsUnconstrained;
|
||||
// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable
|
||||
//
|
||||
#if ABSL_HAVE_BUILTIN(__is_trivially_relocatable)
|
||||
// If the compiler offers a builtin that tells us the answer, we can use that.
|
||||
// This covers all of the cases in the fallback below, plus types that opt in
|
||||
// using e.g. [[clang::trivial_abi]].
|
||||
template <class T>
|
||||
struct is_trivially_relocatable
|
||||
: std::integral_constant<bool, __is_trivially_relocatable(T)> {};
|
||||
#else
|
||||
// Otherwise we use a fallback that detects only those types we can feasibly
|
||||
// detect. Any time that has trivial move-construction and destruction
|
||||
// operations is by definition trivally relocatable.
|
||||
template <class T>
|
||||
struct is_trivially_relocatable : std::integral_constant<bool, false> {};
|
||||
struct is_trivially_relocatable
|
||||
: absl::conjunction<absl::is_trivially_move_constructible<T>,
|
||||
absl::is_trivially_destructible<T>> {};
|
||||
#endif
|
||||
|
||||
// absl::is_constant_evaluated()
|
||||
|
||||
@@ -743,6 +743,23 @@ TEST(TypeTraitsTest, IsNothrowSwappable) {
|
||||
EXPECT_TRUE(IsNothrowSwappable<adl_namespace::SpecialNoexceptSwap>::value);
|
||||
}
|
||||
|
||||
TEST(TriviallyRelocatable, PrimitiveTypes) {
|
||||
static_assert(absl::is_trivially_relocatable<int>::value, "");
|
||||
static_assert(absl::is_trivially_relocatable<char>::value, "");
|
||||
static_assert(absl::is_trivially_relocatable<void*>::value, "");
|
||||
}
|
||||
|
||||
// User-defined types can be trivially relocatable as long as they don't have a
|
||||
// user-provided move constructor or destructor.
|
||||
TEST(TriviallyRelocatable, UserDefinedTriviallyReconstructible) {
|
||||
struct S {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
static_assert(absl::is_trivially_relocatable<S>::value, "");
|
||||
}
|
||||
|
||||
// A user-provided move constructor disqualifies a type from being trivially
|
||||
// relocatable.
|
||||
TEST(TriviallyRelocatable, UserProvidedMoveConstructor) {
|
||||
|
||||
Reference in New Issue
Block a user