diff --git a/AK/StdLibExtraDetails.h b/AK/StdLibExtraDetails.h index 67fcd50eeeb..9ac64a2a404 100644 --- a/AK/StdLibExtraDetails.h +++ b/AK/StdLibExtraDetails.h @@ -551,6 +551,9 @@ inline constexpr bool IsMoveAssignable = IsAssignable, Add template inline constexpr bool IsTriviallyMoveAssignable = IsTriviallyAssignable, AddRvalueReference>; +template +inline constexpr bool IsTriviallyRelocatable = IsTriviallyMoveConstructible && IsTriviallyDestructible; + template typename U> inline constexpr bool IsSpecializationOf = false; @@ -716,6 +719,7 @@ using AK::Detail::IsTriviallyCopyConstructible; using AK::Detail::IsTriviallyDestructible; using AK::Detail::IsTriviallyMoveAssignable; using AK::Detail::IsTriviallyMoveConstructible; +using AK::Detail::IsTriviallyRelocatable; using AK::Detail::IsUnion; using AK::Detail::IsUnsigned; using AK::Detail::IsVoid; diff --git a/Tests/AK/TestTypeTraits.cpp b/Tests/AK/TestTypeTraits.cpp index 4e2c438deee..315c4c05c06 100644 --- a/Tests/AK/TestTypeTraits.cpp +++ b/Tests/AK/TestTypeTraits.cpp @@ -243,6 +243,32 @@ TEST_CASE(IsDestructible) EXPECT_TRAIT_FALSE(IsTriviallyDestructible, C); } +TEST_CASE(IsTriviallyRelocatable) +{ + EXPECT_TRAIT_TRUE(IsTriviallyRelocatable, int, float, char, Empty); + EXPECT_TRAIT_TRUE(IsTriviallyRelocatable, int*, Empty*); + + struct TriviallyRelocatable { + }; + EXPECT_TRAIT_TRUE(IsTriviallyRelocatable, TriviallyRelocatable); + + struct NonTriviallyRelocatable { + NonTriviallyRelocatable(NonTriviallyRelocatable&&) { } + ~NonTriviallyRelocatable() { } + }; + EXPECT_TRAIT_FALSE(IsTriviallyRelocatable, NonTriviallyRelocatable); + + struct NonTrivialMove { + NonTrivialMove(NonTrivialMove&&) { } + }; + EXPECT_TRAIT_FALSE(IsTriviallyRelocatable, NonTrivialMove); + + struct NonTrivialDestructor { + ~NonTrivialDestructor() { } + }; + EXPECT_TRAIT_FALSE(IsTriviallyRelocatable, NonTrivialDestructor); +} + TEST_CASE(CommonType) { using TCommon0 = CommonType;