The environment I'm working in requires that all allocation is done through a special set of malloc
/calloc
functions and that a user ID is provided when allocating. The environment has no implementation of exceptions, so errors are signaled by returning NULL
.
For this reason, I have tried to write a couple of C++ functions which make it easier to create and destroy C++ objects:
namespace details {
template<typename T>
typename enable_if<is_pod<T>::value, T>::type *
create(uint32_t module_id) {
// use module_id
return (T *)calloc(1, sizeof(T));
}
template<typename T, typename ...Args>
typename enable_if<!is_pod<T>::value, T>::type *
create(uint32_t module_id, Args&&... args) {
// use module_id
T *p = (T *)calloc(1, sizeof(T));
if (p)
new (p) T(forward<Args>(args)...);
return p;
}
template<typename T>
void destroy(typename enable_if<is_pod<T>::value, T>::type *t) {
if (t)
free(t);
}
template<typename T>
void destroy(typename enable_if<!is_pod<T>::value, T>::type *t) {
if (!t)
return;
t->~T();
free(t);
}
};
template<typename T, typename ...Args>
T *create(uint32_t module_id, Args&&... args) {
return details::create<T>(module_id, forward<Args>(args)...);
}
template<typename T>
void destroy(T *t) {
details::destroy<T>(t);
}
Can this be done smarter? And are there any cases where my create
/destroy
functions are not handling as one would expect?
operator new
,operator delete
, and their array counterparts right? The advantage of that would be that they also work when objects are created outside of code you directly contril, such as standard containers. – Christopher Creutzig Dec 1 '13 at 22:00