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;
+#endif
};
/*
*/
template<typename T>
-struct is_pod_or_void
+struct can_free
{
- static constexpr bool value = std::is_pod<T>::value || std::is_void<T>::value;
+ /*
+ * 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;
+#endif
};
-template<typename T, typename = typename std::enable_if<!is_pod_or_void<T>::value>::type>
+template<typename T, typename = typename std::enable_if<!can_free<T>::value>::type>
void free(T *p) = delete;
+template<typename T>
+struct can_memset
+{
+ static constexpr bool value = std::is_pod<T>::value || std::is_void<T>::value;
+};
+
+template <typename T, typename = typename std::enable_if<!can_memset<T>::value>::type>
+void *memset(T *s, int c, size_t n) = delete;
+
+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;
+#endif
+};
+
+template <typename T, typename U,
+ typename = typename std::enable_if<!can_memcpy<T>::value>::type,
+ typename = typename std::enable_if<!can_memcpy<U>::value>::type>
+void *memcpy(T *d, const U *s, size_t n) = delete;
+
+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;
+#endif
+};
+
+template <typename T, typename U,
+ typename = typename std::enable_if<!can_memmove<T>::value>::type,
+ typename = typename std::enable_if<!can_memmove<U>::value>::type>
+void *memmove(T *d, const U *s, size_t n) = delete;
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0])))
#endif