Commit b6a1039b by Abseil Team Committed by Copybara-Service

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
parent 32e0395f
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment