aboutsummaryrefslogtreecommitdiffhomepage
path: root/absl/meta/type_traits.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/meta/type_traits.h')
-rw-r--r--absl/meta/type_traits.h45
1 files changed, 37 insertions, 8 deletions
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index d57a879..8cd5f04 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -41,10 +41,20 @@
#include "absl/base/config.h"
+// MSVC constructibility traits do not detect destructor properties and so our
+// implementations should not use them as a source-of-truth.
+#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)
+#define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1
+#endif
+
namespace absl {
// Defined and documented later on in this file.
template <typename T>
+struct is_trivially_destructible;
+
+// Defined and documented later on in this file.
+template <typename T>
struct is_trivially_move_assignable;
namespace type_traits_internal {
@@ -66,6 +76,20 @@ union SingleMemberUnion {
#endif // defined(_MSC_VER) && !defined(__GNUC__)
template <class T>
+struct IsTriviallyMoveConstructibleObject
+ : std::integral_constant<
+ bool, std::is_move_constructible<
+ type_traits_internal::SingleMemberUnion<T>>::value &&
+ absl::is_trivially_destructible<T>::value> {};
+
+template <class T>
+struct IsTriviallyCopyConstructibleObject
+ : std::integral_constant<
+ bool, std::is_copy_constructible<
+ type_traits_internal::SingleMemberUnion<T>>::value &&
+ absl::is_trivially_destructible<T>::value> {};
+
+template <class T>
struct IsTriviallyMoveAssignableReference : std::false_type {};
template <class T>
@@ -323,7 +347,9 @@ struct is_trivially_default_constructible
: std::integral_constant<bool, __has_trivial_constructor(T) &&
std::is_default_constructible<T>::value &&
is_trivially_destructible<T>::value> {
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
+ !defined( \
+ ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
private:
static constexpr bool compliant =
std::is_trivially_default_constructible<T>::value ==
@@ -354,10 +380,11 @@ template <typename T>
struct is_trivially_move_constructible
: std::conditional<
std::is_object<T>::value && !std::is_array<T>::value,
- std::is_move_constructible<
- type_traits_internal::SingleMemberUnion<T>>,
+ type_traits_internal::IsTriviallyMoveConstructibleObject<T>,
std::is_reference<T>>::type::type {
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
+ !defined( \
+ ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
private:
static constexpr bool compliant =
std::is_trivially_move_constructible<T>::value ==
@@ -388,10 +415,11 @@ template <typename T>
struct is_trivially_copy_constructible
: std::conditional<
std::is_object<T>::value && !std::is_array<T>::value,
- std::is_copy_constructible<
- type_traits_internal::SingleMemberUnion<T>>,
+ type_traits_internal::IsTriviallyCopyConstructibleObject<T>,
std::is_lvalue_reference<T>>::type::type {
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
+ !defined( \
+ ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
private:
static constexpr bool compliant =
std::is_trivially_copy_constructible<T>::value ==
@@ -423,7 +451,8 @@ struct is_trivially_copy_constructible
template <typename T>
struct is_trivially_move_assignable
: std::conditional<
- std::is_object<T>::value && !std::is_array<T>::value,
+ std::is_object<T>::value && !std::is_array<T>::value &&
+ std::is_move_assignable<T>::value,
std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
type {