#define LLVM_ADT_POINTERINTPAIR_H
#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstdint>
#include <limits>
}
};
+// Specialize is_trivially_copyable to avoid limitation of llvm::is_trivially_copyable
+// when compiled with gcc 4.9.
+template <typename PointerTy, unsigned IntBits, typename IntType,
+ typename PtrTraits,
+ typename Info>
+struct is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>> : std::true_type {
+#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
+ static_assert(std::is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>::value,
+ "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
+#endif
+};
+
+
template <typename PointerT, unsigned IntBits, typename PtrTraits>
struct PointerIntPairInfo {
static_assert(PtrTraits::NumLowBitsAvailable <
union trivial_helper {
T t;
};
+
} // end namespace detail
/// An implementation of `std::is_trivially_copy_constructible` since we have
template <typename T>
struct is_trivially_move_constructible<T &&> : std::true_type {};
+
+template <typename T>
+struct is_copy_assignable {
+ template<class F>
+ static auto get(F*) -> decltype(std::declval<T &>() = std::declval<const T &>(), std::true_type{});
+ static std::false_type get(...);
+ static constexpr bool value = decltype(get((T*)nullptr))::value;
+};
+
+template <typename T>
+struct is_move_assignable {
+ template<class F>
+ static auto get(F*) -> decltype(std::declval<T &>() = std::declval<T &&>(), std::true_type{});
+ static std::false_type get(...);
+ static constexpr bool value = decltype(get((T*)nullptr))::value;
+};
+
+
// An implementation of `std::is_trivially_copyable` since STL version
// is not equally supported by all compilers, especially GCC 4.9.
// Uniform implementation of this trait is important for ABI compatibility
// copy assign
static constexpr bool has_trivial_copy_assign =
- std::is_copy_assignable<detail::trivial_helper<T>>::value;
+ is_copy_assignable<detail::trivial_helper<T>>::value;
static constexpr bool has_deleted_copy_assign =
- !std::is_copy_assignable<T>::value;
+ !is_copy_assignable<T>::value;
// move assign
static constexpr bool has_trivial_move_assign =
- std::is_move_assignable<detail::trivial_helper<T>>::value;
+ is_move_assignable<detail::trivial_helper<T>>::value;
static constexpr bool has_deleted_move_assign =
- !std::is_move_assignable<T>::value;
+ !is_move_assignable<T>::value;
// destructor
static constexpr bool has_trivial_destructor =
(has_deleted_copy_assign || has_trivial_copy_assign) &&
(has_deleted_copy_constructor || has_trivial_copy_constructor);
-#if (__has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5))
- static_assert(value == std::is_trivially_copyable<T>::value, "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
+#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
+ static_assert(value == std::is_trivially_copyable<T>::value,
+ "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
#endif
};
+template <typename T>
+class is_trivially_copyable<T*> : public std::true_type {
+};
} // end namespace llvm