Files CCore/inc/TaskMemStack.h CCore/src/TaskMemStack.cpp
TaskMemStack can be used to allocate a temporary work area in a stack-based manner. Each task has own task memory stack.
void * TryTaskMemStackAlloc(ulen len) noexcept; // len!=0 void * TaskMemStackAlloc(ulen len); // len!=0 void TaskMemStackFree(void *mem); // mem!=0
TryTaskMemStackAlloc() tries to allocate a memory from the task memory stack. The length of the memory block is given by the non-null argument, the block is aligned. Null is returned in case of error. If a TaskMemStack object is not active for the current task a error is reported.
TaskMemStackAlloc() does the same, but throws an exception in case of error.
TaskMemStackFree() frees a previously allocated memory block, mem is not null. Memory blocks must be freed in the strict reverse order as they was allocated. I.e. mem must be the address of the last memory block allocated.
Before using these functions you must activate a TaskMemStack object.
TaskMemStackAllocGuard is an allocation guard class for the task memory stack.
class TaskMemStackAllocGuard : NoCopy
{
void *mem;
public:
explicit TaskMemStackAllocGuard(ulen size_of); // size_of!=0
TaskMemStackAllocGuard(ulen count,ulen size_of); // count!=0, size_of!=0
~TaskMemStackAllocGuard();
operator void * () const { return mem; }
void * disarm() { return Replace_null(mem); }
};
The first constructor allocates a task memory stack block of the size_of length, the argument must be non-null.
The second constructor allocates a task memory stack block for count items of the size_of length, both arguments must be non-null.
Destructor deallocates the memory if the object is not disarmed.
The address of the allocated memory block can be obtained by the casting operator.
disarm() disarms the guard and returns the address of the allocated memory block.
TaskMemStack object is responsible for allocation/deallocation operations. You don't need to use it directly. Instead, you create an object of this class in some task as an automatic variable. In scope of this object you may use task memory stack allocation/deallocation functions.
class TaskMemStack : NoCopy
{
....
public:
explicit TaskMemStack(ulen reserve=4_KByte);
~TaskMemStack();
void * alloc(ulen len); // len!=0
void free(void *mem); // mem!=0
static TaskMemStack * GetObject();
};
The only argument of the constructor is the length of the first big block of memory. By default it is 4 KBytes.
StackObject creates an object using the task memory stack.
template <class T>
class StackObject : NoCopy
{
T *ptr;
public:
// constructors
template <class ... SS>
explicit StackObject(SS && ... ss);
~StackObject();
// object ptr
T * getPtr() const { return ptr; }
T & operator * () const { return *ptr; }
T * operator -> () const { return ptr; }
};
Constructor creates an object forwarding arguments to the object constructor.
Destructor destroys the object.
The class implements the reduced Object Pointer Interface to provide access to the object.
StackArray is similar to the SimpleArray class. The only difference: it takes the memory from the task memory stack. And this class is not swappable and movable. You should use this class to create automatic variables when you need a temporary work array of objects.
template <class T,class Algo>
class StackArray : NoCopy
{
T *ptr;
ulen len;
public:
// constructors
explicit StackArray(ulen len=0);
~StackArray();
// range access
T * getPtr() { return ptr; }
const T * getPtr() const { return ptr; }
const T * getPtr_const() const { return ptr; }
ulen getLen() const { return len; }
// index access
T & operator [] (ulen index);
const T & operator [] (ulen index) const;
T & at(ulen index);
const T & at(ulen index) const;
// apply
template <class FuncInit>
void apply(FuncInit func_init);
template <class FuncInit>
void apply(FuncInit func_init) const;
template <class FuncInit>
void apply_const(FuncInit func_init) const;
template <class FuncInit>
void applyReverse(FuncInit func_init);
template <class FuncInit>
void applyReverse(FuncInit func_init) const;
template <class FuncInit>
void applyReverse_const(FuncInit func_init) const;
};