From 63d26fad49463561c2427a45aab283938ade10d9 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 31 Jan 2022 09:50:11 -0800 Subject: Export of internal Abseil changes -- c475e8ac1ea163248415e7d4bdc05e3c47dd8f3d by Derek Mauro : Replace absl::bit_cast with std::bit_cast in C++20 Remove the deprecated implementation that is less-strict than the standard, and also relies on undefined behavior PiperOrigin-RevId: 425391711 -- dc97c996aed85161f0e490baafd3ed851e8bea9d by Abseil Team : Add enum example for ABSL_DEPRECATED() PiperOrigin-RevId: 425311634 GitOrigin-RevId: c475e8ac1ea163248415e7d4bdc05e3c47dd8f3d Change-Id: Id8f159b37fe3f3cace6ab7bce08daf9888c44bcf --- absl/base/attributes.h | 4 +++ absl/base/casts.h | 78 +++++++++++++++++++------------------------------- 2 files changed, 33 insertions(+), 49 deletions(-) diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 4ab6fa27..91aabffe 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -656,6 +656,10 @@ // ABSL_DEPRECATED("Use DoThat() instead") // void DoThis(); // +// enum FooEnum { +// kBar ABSL_DEPRECATED("Use kBaz instead"), +// }; +// // Every usage of a deprecated entity will trigger a warning when compiled with // clang's `-Wdeprecated-declarations` option. This option is turned off by // default, but the warnings will be reported by clang-tidy. diff --git a/absl/base/casts.h b/absl/base/casts.h index bf100efa..b99adb06 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h @@ -29,6 +29,10 @@ #include #include +#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L +#include // 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" @@ -36,23 +40,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN -namespace internal_casts { - -template -struct is_bitcastable - : std::integral_constant< - bool, - sizeof(Dest) == sizeof(Source) && - type_traits_internal::is_trivially_copyable::value && - type_traits_internal::is_trivially_copyable::value -#if !ABSL_HAVE_BUILTIN(__builtin_bit_cast) - && std::is_default_constructible::value -#endif - > { -}; - -} // namespace internal_casts - // implicit_cast() // // Performs an implicit conversion between types following the language @@ -123,7 +110,7 @@ constexpr To implicit_cast(typename absl::internal::identity_t to) { // floating point value: // // float f = 3.14159265358979; -// int i = bit_cast(f); +// int i = bit_cast(f); // // i = 0x40490fdb // // Reinterpreting and accessing a value directly as a different type (as shown @@ -151,48 +138,41 @@ constexpr To implicit_cast(typename absl::internal::identity_t to) { // introducing this undefined behavior (since the original value is never // accessed in the wrong way). // -// NOTE: The requirements here are more strict than the bit_cast of standard -// proposal P0476 when __builtin_bit_cast is not available. -// Specifically, this implementation also requires `Dest` to be -// default-constructible. -template < - typename Dest, typename Source, - typename std::enable_if::value, - int>::type = 0> +// The requirements of `absl::bit_cast` are more strict than that of +// `std::bit_cast` unless compiler support is available. Specifically, without +// compiler support, this implementation also requires `Dest` to be +// default-constructible. In C++20, `absl::bit_cast` is replaced by +// `std::bit_cast`. +#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L + +using std::bit_cast; + +#else // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L + +template ::value && + type_traits_internal::is_trivially_copyable::value +#if !ABSL_HAVE_BUILTIN(__builtin_bit_cast) + && std::is_default_constructible::value +#endif // !ABSL_HAVE_BUILTIN(__builtin_bit_cast) + , + int>::type = 0> #if ABSL_HAVE_BUILTIN(__builtin_bit_cast) inline constexpr Dest bit_cast(const Source& source) { return __builtin_bit_cast(Dest, source); } -#else +#else // ABSL_HAVE_BUILTIN(__builtin_bit_cast) inline Dest bit_cast(const Source& source) { Dest dest; memcpy(static_cast(std::addressof(dest)), static_cast(std::addressof(source)), sizeof(dest)); return dest; } -#endif - -// NOTE: This overload is only picked if the requirements of bit_cast are -// not met. It is therefore UB, but is provided temporarily as previous -// versions of this function template were unchecked. Do not use this in -// new code. -template < - typename Dest, typename Source, - typename std::enable_if< - !internal_casts::is_bitcastable::value, - int>::type = 0> -ABSL_DEPRECATED( - "absl::bit_cast type requirements were violated. Update the types " - "being used such that they are the same size and are both " - "TriviallyCopyable.") -inline Dest bit_cast(const Source& source) { - static_assert(sizeof(Dest) == sizeof(Source), - "Source and destination types should have equal sizes."); +#endif // ABSL_HAVE_BUILTIN(__builtin_bit_cast) - Dest dest; - memcpy(&dest, &source, sizeof(dest)); - return dest; -} +#endif // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L ABSL_NAMESPACE_END } // namespace absl -- cgit v1.2.3