+void *zmalloc_internal(size_t size)
+{
+ return calloc(1, size);
+}
+
+template <typename T>
+struct can_malloc
+{
+ static constexpr bool value = std::is_trivially_constructible<T>::value;
+};
+
+/*
+ * Malloc and zero-initialize an object of type T, asserting that T can be
+ * safely malloc-ed (is trivially constructible).
+ */
+template<typename T>
+T *zmalloc()
+{
+ static_assert (can_malloc<T>::value, "type can be malloc'ed");
+ return (T *) zmalloc_internal(sizeof(T));
+}
+
+/*
+ * Malloc and zero-initialize a buffer of size `size`, asserting that type T
+ * can be safely malloc-ed (is trivially constructible).
+ */
+template<typename T>
+T *zmalloc(size_t size)
+{
+ static_assert (can_malloc<T>::value, "type can be malloc'ed");
+ LTTNG_ASSERT(size >= sizeof(T));
+ return (T *) zmalloc_internal(size);
+}
+
+/*
+ * Malloc and zero-initialize an array of `nmemb` elements of type T,
+ * asserting that T can be safely malloc-ed (is trivially constructible).
+ */
+template<typename T>
+T *calloc(size_t nmemb)
+{
+ static_assert (can_malloc<T>::value, "type can be malloc'ed");
+ return (T *) zmalloc_internal(nmemb * sizeof(T));
+}
+
+/*
+ * Malloc an object of type T, asserting that T can be safely malloc-ed (is
+ * trivially constructible).
+ */
+template<typename T>
+T *malloc()