gcc versions before 5.0 lack some type traits defined in C++11. Since in
this instance we use the trait to prevent misuses of certain functions
to statically assert at build time and not to generate different code
based on this property, it is preferable to simply set value to true and
allow the code to compile. Anyone using a contemporary compiler will
catch the error.
I have not replaced the type trait checks with macros using gcc-specific
checks (__has_trivial_copy(), for example) since their semantics diverge
subtly from the standard and their use could introduce bugs.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Id57cc1cff67847c725f75eb3404443732de1c531
template <typename T>
struct can_malloc
{
template <typename T>
struct can_malloc
{
+ /*
+ * gcc versions before 5.0 lack some type traits defined in C++11.
+ * Since in this instance we use the trait to prevent misuses
+ * of malloc (and statically assert) and not to generate different
+ * code based on this property, simply set value to true and allow
+ * the code to compile. Anyone using a contemporary compiler will
+ * catch the error.
+ */
+#if __GNUG__ && __GNUC__ < 5
+ static constexpr bool value = true;
+#else
static constexpr bool value = std::is_trivially_constructible<T>::value;
static constexpr bool value = std::is_trivially_constructible<T>::value;
template<typename T>
struct can_free
{
template<typename T>
struct can_free
{
+ /*
+ * gcc versions before 5.0 lack some type traits defined in C++11.
+ * Since in this instance we use the trait to prevent misuses
+ * of free (and statically assert) and not to generate different
+ * code based on this property, simply set value to true and allow
+ * the code to compile. Anyone using a contemporary compiler will
+ * catch the error.
+ */
+#if __GNUG__ && __GNUC__ < 5
+ static constexpr bool value = true;
+#else
static constexpr bool value = std::is_trivially_destructible<T>::value || std::is_void<T>::value;
static constexpr bool value = std::is_trivially_destructible<T>::value || std::is_void<T>::value;
};
template<typename T, typename = typename std::enable_if<!can_free<T>::value>::type>
};
template<typename T, typename = typename std::enable_if<!can_free<T>::value>::type>
template<typename T>
struct can_memcpy
{
template<typename T>
struct can_memcpy
{
+ /*
+ * gcc versions before 5.0 lack some type traits defined in C++11.
+ * Since in this instance we use the trait to prevent misuses
+ * of memcpy (and statically assert) and not to generate different
+ * code based on this property, simply set value to true and allow
+ * the code to compile. Anyone using a contemporary compiler will
+ * catch the error.
+ */
+#if __GNUG__ && __GNUC__ < 5
+ static constexpr bool value = true;
+#else
static constexpr bool value = std::is_trivially_copyable<T>::value;
static constexpr bool value = std::is_trivially_copyable<T>::value;
};
template <typename T, typename U,
};
template <typename T, typename U,
template<typename T>
struct can_memmove
{
template<typename T>
struct can_memmove
{
+ /*
+ * gcc versions before 5.0 lack some type traits defined in C++11.
+ * Since in this instance we use the trait to prevent misuses
+ * of memmove (and statically assert) and not to generate different
+ * code based on this property, simply set value to true and allow
+ * the code to compile. Anyone using a contemporary compiler will
+ * catch the error.
+ */
+#if __GNUG__ && __GNUC__ < 5
+ static constexpr bool value = true;
+#else
static constexpr bool value = std::is_trivially_copyable<T>::value;
static constexpr bool value = std::is_trivially_copyable<T>::value;
};
template <typename T, typename U,
};
template <typename T, typename U,