Export of internal Abseil changes.
-- 71756e7176d15d52a4ee66cc25c088aedbca78f4 by Abseil Team <absl-team@google.com>: internal change PiperOrigin-RevId: 203131836 -- 2e80b965b590fd6459f45413215690980eb50960 by Matt Calabrese <calabrese@google.com>: Tighten type requirements for use of absl::bit_cast. Ideally, the constraints should depend on std::is_trivally_copyable, but a combination of supported configurations and lack of intrinsic support for bit_cast makes this not currently feasible. In a future change we should introduce more proper preprocessor branching and workarounds to better emulate the trait. PiperOrigin-RevId: 202950382 GitOrigin-RevId: 71756e7176d15d52a4ee66cc25c088aedbca78f4 Change-Id: If58840d1e4d801817be85cbf99a475c31fa94fe0
This commit is contained in:
parent
134496a31d
commit
8f612ebb15
2 changed files with 52 additions and 1 deletions
|
@ -25,12 +25,36 @@
|
|||
#define ABSL_BASE_CASTS_H_
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/internal/identity.h"
|
||||
#include "absl/base/macros.h"
|
||||
|
||||
namespace absl {
|
||||
|
||||
namespace internal_casts {
|
||||
|
||||
// NOTE: Not a fully compliant implementation of `std::is_trivially_copyable`.
|
||||
// TODO(calabrese) Branch on implementations that directly provide
|
||||
// `std::is_trivially_copyable`, create a more rigorous workaround, and publicly
|
||||
// expose in meta/type_traits.
|
||||
template <class T>
|
||||
struct is_trivially_copyable
|
||||
: std::integral_constant<
|
||||
bool, std::is_destructible<T>::value&& __has_trivial_destructor(T) &&
|
||||
__has_trivial_copy(T) && __has_trivial_assign(T)> {};
|
||||
|
||||
template <class Dest, class Source>
|
||||
struct is_bitcastable
|
||||
: std::integral_constant<bool,
|
||||
sizeof(Dest) == sizeof(Source) &&
|
||||
is_trivially_copyable<Source>::value &&
|
||||
is_trivially_copyable<Dest>::value &&
|
||||
std::is_default_constructible<Dest>::value> {};
|
||||
|
||||
} // namespace internal_casts
|
||||
|
||||
// implicit_cast()
|
||||
//
|
||||
// Performs an implicit conversion between types following the language
|
||||
|
@ -125,7 +149,32 @@ inline To implicit_cast(typename absl::internal::identity_t<To> to) {
|
|||
// and reading its bits back using a different type. A `bit_cast()` avoids this
|
||||
// issue by implementing its casts using `memcpy()`, which avoids introducing
|
||||
// this undefined behavior.
|
||||
template <typename Dest, typename Source>
|
||||
//
|
||||
// NOTE: The requirements here are more strict than the bit_cast of standard
|
||||
// proposal p0476 due to the need for workarounds and lack of intrinsics.
|
||||
// Specifically, this implementation also requires `Dest` to be
|
||||
// default-constructible.
|
||||
template <
|
||||
typename Dest, typename Source,
|
||||
typename std::enable_if<internal_casts::is_bitcastable<Dest, Source>::value,
|
||||
int>::type = 0>
|
||||
inline Dest bit_cast(const Source& source) {
|
||||
Dest dest;
|
||||
memcpy(static_cast<void*>(std::addressof(dest)),
|
||||
static_cast<const void*>(std::addressof(source)), sizeof(dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
// 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<Dest, Source>::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.");
|
||||
|
|
|
@ -369,4 +369,6 @@ struct IsHashEnabled
|
|||
} // namespace type_traits_internal
|
||||
|
||||
} // namespace absl
|
||||
|
||||
|
||||
#endif // ABSL_META_TYPE_TRAITS_H_
|
||||
|
|
Loading…
Reference in a new issue