#ifndef GLRGUARD
#define GLRGUARD
/**
*
* Class glrGuard is the base class for classes that represent the nodes of
* derivation forest (glrNode class) and the vertices of graph stack (glrStateVertex class).
* But generally it can be used anywhere. It provides simple semiautomatic garbagge collector.
* It stores in each object number of pointers to it. If you make a copy of pointer to the
* glrGuard -- type object, you should call it's shackle() function which increases
* the stored number of pointers. If you forgot some pointer to the glrGuard -- type object,
* you should call it's release() function before it, which decreases the stored number of pointers and
* if it become 0, it calls it's own destructor. Therefore objects with the glrGuard base class
* should be never deleted directly (by the delete opearator but by calling their release()
* function. Of course they should never be alocated on stack.
*
* Important! glrGuard class has virtual destructor, which makes nothing. If you want
* to get cascade deleting, when one object with glrGuard base class stores pointers
* to other objects with glrGuard base class you should simpy call the release()
* function of all remembered object in your own overrided virtual destructor of the first object.
*
*/
class glrGuard {
private:
int numOfPointers;
public:
/**
*
* Function getNumOfPointers() returns the number of pointers which points to the object.
* It is here particularly for debug reasons.
*
*/
const int &getNumOfPointers() const { return numOfPointers; }
/**
*
* The release() function decereases the counter of pointers to this object and
* deletes object if the counter becomes 0. Call this function before
* you forgot pointer to an object with base class glrGuard.
* Objects with base class glrGuard
* should be always dealocated using their release() function.
*
*/
void release() {
#ifdef DEBUGEXCEPTIONS
if(numOfPointers<=0){
throw glrPointerCounterUnderflowException(numOfPointers);
}
#endif
--numOfPointers;
if (!numOfPointers) delete this;
}
/**
*
* Function shackle() increases stored counter of pointers to this object.
* You should call it when you make a copy of the pointer to this object.
*
*/
void shackle() { ++numOfPointers; } ;
/**
*
* Constructor initializes the pointers counter to 1 -- you have not to call the shackle()
* after creating a new object with the glrGuard base class.
*
*/
glrGuard() { numOfPointers=1; } ;
/**
*
* The destructor makes nothing. You should override it in your own glrGuard -- derived class
* and call the release() function in it to all remembered glrGuard -- derived objects
* to get the cascading delete if needed. The destructors of the glrGuard -- derived classes should be
* always vitrual.
*
*/
virtual ~glrGuard() {
#ifdef DEBUGEXCEPTIONS
if (numOfPointers) throw glrInvalidDeleteException(numOfPointers);
#endif
};
};
#endif