Files CCore/inc/NewDelete.h CCore/src/NewDelete.cpp
This set of tools assists in the custom memory allocation/deallocation during an object creation. It is working with a custom memory allocator initialization class. Such class looks like:
class CustomAllocInit { .... public: class AllocType : NoCopy { .... public: explicit AllocType(CustomAllocInit init); ~AllocType(); void * alloc(ulen len); // throw exception on failure void free(void *mem,ulen len); }; };
You may also use a simpler way:
class CustomAllocInit { .... public: using AllocType = CustomAllocInit ; void * alloc(ulen len); void free(void *mem,ulen len); };
I.e. the class CustomAllocInit is a lightweight copyable class. It defines the inner type AllocType, responsible for the actual memory allocation/deallocation. The method alloc() throws an exception in case of failure. The type of exception is not restricted. Otherwise it must return an aligned memory block pointer of the required length. The method free() is called to release the allocated memory block. The first argument is the memory block pointer, the second is the length. The first argument is always non-null, the second equals the argument, which was passed to the alloc() during the original memory allocation.
To create an object using this custom memory allocator use the function New().
template <class T,class AllocInit,class ... SS>
T * New(AllocInit init,SS && ... ss);
The first argument is a memory allocator initialization object. The rest are used in an object constructor. If the object constructor throw an exception, the allocated memory is freed.
To destroy the object, the function Delete() is used.
template <class T,class AllocInit>
void Delete(AllocInit init,T *obj);
For this function you must provide the original object pointer.
There is a polymorphic variant of Delete.
template <class T,class AllocInit>
void Delete_dynamic(AllocInit init,T *obj);
This function may be used with the pointer to some base class of the original object. You must declare the destructor to the base class virtual and provide the virtual method getSpace():
class Base { public: .... virtual ~Base(); virtual Space getSpace(); }; class Derived : public Base { public: .... virtual ~Derived(); virtual Space getSpace() { return Space(this,sizeof (*this)); } };
Then you can use Delete_dynamic with the pointer to the base class:
Derived *derived=New<Derived>(alloc_init,....); Base *base=derived; Delete_dynamic(alloc_init,base);
The class CustomAllocGuard is used in the New() implementation.
template <class AllocInit>
class CustomAllocGuard : NoCopy
{
using AllocType = typename AllocInit::AllocType ;
AllocType alloc;
ulen len;
void *mem;
public:
CustomAllocGuard(AllocInit init,ulen len_)
: alloc(init)
{
len=len_;
mem=alloc.alloc(len);
}
~CustomAllocGuard()
{
if( mem ) alloc.free(mem,len);
}
Place<void> getPlace() { return PlaceAt(mem); }
void disarm() { mem=0; }
};
Constructor creates an AllocType object and uses it to allocate a memory.
Destructor frees the memory, if the object is not "disarmed".
disarm() disarms the object.
getPlace() is the place of the allocated memory block.
You can use the following class to get memory from the default heap.
struct DefaultHeapAlloc
{
DefaultHeapAlloc() {}
using AllocType = DefaultHeapAlloc ;
void * alloc(ulen len) { return MemAlloc(len); }
void free(void *ptr,ulen) { MemFree(ptr); }
};