From d859fafe1ab9edc9c04ca262d9993be82c757881 Mon Sep 17 00:00:00 2001 From: Evan Brown Date: Tue, 20 Sep 2022 13:12:25 -0700 Subject: Change the macro ABSL_IS_TRIVIALLY_RELOCATABLE into a type trait - absl::is_trivially_relocatable - and move it from optimization.h to type_traits.h. Example of how to change to the new type trait: ``` #include "absl/base/attributes.h" if (ABSL_IS_TRIVIALLY_RELOCATABLE(T)) { DoSomething(); } ``` to ``` #include "absl/meta/type_traits.h" if (absl::is_trivially_relocatable::value) { DoSomething(); } ``` Note that optimization.h is also built in C mode so we can't put a type trait there. PiperOrigin-RevId: 475633715 Change-Id: I2bc85f3f6711d1280049fd01eb97c497d2d0d929 --- absl/base/optimization.h | 24 ------------------------ absl/base/optimization_test.cc | 19 ------------------- absl/meta/BUILD.bazel | 1 + absl/meta/CMakeLists.txt | 1 + absl/meta/type_traits.h | 28 ++++++++++++++++++++++++++++ absl/meta/type_traits_test.cc | 19 +++++++++++++++++++ 6 files changed, 49 insertions(+), 43 deletions(-) (limited to 'absl') diff --git a/absl/base/optimization.h b/absl/base/optimization.h index 57999a18..db5cc097 100644 --- a/absl/base/optimization.h +++ b/absl/base/optimization.h @@ -249,28 +249,4 @@ #define ABSL_INTERNAL_UNIQUE_SMALL_NAME() #endif -// ABSL_IS_TRIVIALLY_RELOCATABLE(type) -// Detects whether a type is "trivially relocatable" -- meaning it can be -// relocated without invoking the constructor/destructor, using a form of move -// elision. -// -// Example: -// -// if constexpr (ABSL_IS_TRIVIALLY_RELOCATABLE(T)) { -// memcpy(new_location, old_location, sizeof(T)); -// } else { -// new(new_location) T(std::move(*old_location)); -// old_location->~T(); -// } -// -// Upstream documentation: -// -// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable -// -#if ABSL_HAVE_BUILTIN(__is_trivially_relocatable) -#define ABSL_IS_TRIVIALLY_RELOCATABLE(type) __is_trivially_relocatable(type) -#else -#define ABSL_IS_TRIVIALLY_RELOCATABLE(type) false -#endif - #endif // ABSL_BASE_OPTIMIZATION_H_ diff --git a/absl/base/optimization_test.cc b/absl/base/optimization_test.cc index 5f7a8f4c..e83369f3 100644 --- a/absl/base/optimization_test.cc +++ b/absl/base/optimization_test.cc @@ -15,7 +15,6 @@ #include "absl/base/optimization.h" #include "gtest/gtest.h" -#include "absl/base/attributes.h" #include "absl/types/optional.h" namespace { @@ -127,22 +126,4 @@ TEST(PredictTest, ExplicitBoolConversion) { if (ABSL_PREDICT_FALSE(is_false)) ADD_FAILURE(); } -TEST(TrivallyRelocatable, Sanity) { -#if !defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) || \ - !ABSL_HAVE_BUILTIN(__is_trivially_relocatable) - GTEST_SKIP() << "No trivial ABI support."; -#endif - - struct Trivial {}; - struct NonTrivial { - NonTrivial(const NonTrivial&) {} - }; - struct ABSL_ATTRIBUTE_TRIVIAL_ABI TrivialAbi { - TrivialAbi(const TrivialAbi&) {} - }; - EXPECT_TRUE(ABSL_IS_TRIVIALLY_RELOCATABLE(Trivial)); - EXPECT_FALSE(ABSL_IS_TRIVIALLY_RELOCATABLE(NonTrivial)); - EXPECT_TRUE(ABSL_IS_TRIVIALLY_RELOCATABLE(TrivialAbi)); -} - } // namespace diff --git a/absl/meta/BUILD.bazel b/absl/meta/BUILD.bazel index fb379251..4478ccf7 100644 --- a/absl/meta/BUILD.bazel +++ b/absl/meta/BUILD.bazel @@ -42,6 +42,7 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":type_traits", + "//absl/base:core_headers", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt index 9de4bd37..f16f17bd 100644 --- a/absl/meta/CMakeLists.txt +++ b/absl/meta/CMakeLists.txt @@ -34,6 +34,7 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::core_headers absl::type_traits GTest::gmock_main ) diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 46b76906..6e6001fe 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -813,6 +813,34 @@ using swap_internal::Swap; using swap_internal::StdSwapIsUnconstrained; } // namespace type_traits_internal + +// absl::is_trivially_relocatable +// Detects whether a type is "trivially relocatable" -- meaning it can be +// relocated without invoking the constructor/destructor, using a form of move +// elision. +// +// Example: +// +// if constexpr (absl::is_trivially_relocatable::value) { +// memcpy(new_location, old_location, sizeof(T)); +// } else { +// new(new_location) T(std::move(*old_location)); +// old_location->~T(); +// } +// +// Upstream documentation: +// +// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable +// +#if ABSL_HAVE_BUILTIN(__is_trivially_relocatable) +template +struct is_trivially_relocatable + : std::integral_constant {}; +#else +template +struct is_trivially_relocatable : std::integral_constant {}; +#endif + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index fe96554d..d08d9ad9 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -21,6 +21,7 @@ #include #include "gtest/gtest.h" +#include "absl/base/attributes.h" namespace { @@ -1394,4 +1395,22 @@ TEST(TypeTraitsTest, IsNothrowSwappable) { EXPECT_TRUE(IsNothrowSwappable::value); } +TEST(TrivallyRelocatable, Sanity) { +#if !defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) || \ + !ABSL_HAVE_BUILTIN(__is_trivially_relocatable) + GTEST_SKIP() << "No trivial ABI support."; +#endif + + struct Trivial {}; + struct NonTrivial { + NonTrivial(const NonTrivial&) {} // NOLINT + }; + struct ABSL_ATTRIBUTE_TRIVIAL_ABI TrivialAbi { + TrivialAbi(const TrivialAbi&) {} // NOLINT + }; + EXPECT_TRUE(absl::is_trivially_relocatable::value); + EXPECT_FALSE(absl::is_trivially_relocatable::value); + EXPECT_TRUE(absl::is_trivially_relocatable::value); +} + } // namespace -- cgit v1.2.3