#ifndef GC_H #define GC_H #include const int INCREMENTATION_NB_ID = 20; class ID { public: explicit ID(int iID=0); int GetIDValue(); bool GetInUse(); void SetInUse(bool b); private: int m_iID; bool m_bInUse; }; ID::ID(int iID) { m_bInUse = false; m_iID = iID; } int ID::GetIDValue() { return m_iID; } bool ID::GetInUse() { return m_bInUse; } void ID::SetInUse(bool b) { m_bInUse = b; } class IDGenerator { public: IDGenerator(unsigned int iIncrementationNbID = INCREMENTATION_NB_ID); unsigned int GetMaxNbID(); unsigned int GetNbCheckedOutID(); unsigned int CheckOutID(); bool CheckInID(unsigned int iID); private: unsigned int m_iIncrementationNbID; unsigned int m_iMaxNbID; unsigned int m_iNbCheckedOutID; unsigned int m_iMinFreeID; unsigned int m_iNextMinFreeID; std::vector m_IDS; bool CanBeResizedDown(); void SetNextAvailableIDs(); void SetNextAvailableIDs(unsigned int iCheckedInID); }; IDGenerator::IDGenerator(unsigned int iIncrementationNbID) { m_iNbCheckedOutID = 0; m_iMaxNbID = 0; m_iIncrementationNbID = iIncrementationNbID; m_iMinFreeID = 0; m_iNextMinFreeID = 1; } unsigned int IDGenerator::GetMaxNbID() { return m_iMaxNbID; } unsigned int IDGenerator::GetNbCheckedOutID() { return m_iNbCheckedOutID; } unsigned int IDGenerator::CheckOutID() { int iTempID = m_iMinFreeID; if (m_iNbCheckedOutID == m_iMaxNbID) { m_IDS.push_back(ID(m_iMaxNbID)); m_iMaxNbID++; } m_iNbCheckedOutID++; m_IDS[iTempID].SetInUse(true); SetNextAvailableIDs(); return m_IDS[iTempID].GetIDValue(); } bool IDGenerator::CheckInID(unsigned int iID) { bool bResult = true; if (iID >= m_IDS.size() || !m_IDS[iID].GetInUse()) { bResult = false; } else { m_IDS[iID].SetInUse(false); m_iNbCheckedOutID--; if ((int)m_iNbCheckedOutID <= (int)m_iMaxNbID - (int)m_iIncrementationNbID*2) { if (CanBeResizedDown()) { m_IDS.resize(m_iMaxNbID - m_iIncrementationNbID); m_iMaxNbID -= m_iIncrementationNbID; } } SetNextAvailableIDs(iID); } return bResult; } bool IDGenerator::CanBeResizedDown() { unsigned int i; bool bCanBeResized = true; for (i=m_iMaxNbID - m_iIncrementationNbID; i class Allocator { public: Allocator(); Allocator(const T& Object); Allocator(T* ptrObject); ~Allocator(); T* GetPointer(); private: T* m_Data; }; template Allocator::Allocator() { m_Data = new T; } template Allocator::Allocator(const T& Object) { m_Data = new T(Object); } template Allocator::Allocator(T* ptrObject) { m_Data = ptrObject; } template Allocator::~Allocator() { delete m_Data; m_Data = NULL; } template T* Allocator::GetPointer() { return m_Data; } template class GC { public: GC(); GC(const T& Object); GC(T* ptrObject); GC(const GC &oGC); ~GC(); GC operator= (const GC &oGC); GC operator= (const T& Object); GC operator= (T* ptrObject); operator T(); void operator& (); T& operator* (); T* operator-> (); void Free(); private: int m_iID; static IDGenerator m_IDGen; static std::vector m_References; Allocator* m_Data; void InitTasks(); }; template IDGenerator GC::m_IDGen = IDGenerator(); template std::vector GC::m_References; template GC::GC() { InitTasks(); m_Data = new Allocator; } template GC::GC(const T& Object) { InitTasks(); m_Data = new Allocator(Object); } template GC::GC(T* ptrObject) { InitTasks(); m_Data = new Allocator(ptrObject); } template GC::GC(const GC &oGC) { m_iID = oGC.m_iID; m_Data = oGC.m_Data; m_References[m_iID]++; } template GC::~GC() { if (m_References[m_iID] == 1) { m_IDGen.CheckInID(m_iID); if (m_Data != NULL) { delete m_Data; m_Data = NULL; } } else { m_References[m_iID]--; } } template GC::operator T() { return *m_Data->GetPointer(); } template GC GC::operator= (const GC &oGC) { if (this != &oGC) { if (m_References[m_iID] == 1) { m_IDGen.CheckInID(m_iID); delete m_Data; } else { m_References[m_iID]--; } m_iID = oGC.m_iID; m_Data = oGC.m_Data; m_References[m_iID]++; } return *this; } template GC GC::operator= (const T& Object) { *m_Data->GetPointer() = Object; return *this; } template GC GC::operator= (T* ptrObject) { m_Data = new Allocator(ptrObject); return *this; } template T* GC::operator-> () { return m_Data->GetPointer(); } template void GC::operator &() { } template T& GC::operator *() { return *m_Data->GetPointer(); } template void GC::Free() { delete m_Data; m_Data = NULL; m_IDGen.CheckInID(m_iID); } template void GC::InitTasks() { m_iID = m_IDGen.CheckOutID(); if (m_References.size() != m_IDGen.GetMaxNbID()) { m_References.resize(m_IDGen.GetMaxNbID()); } m_References[m_iID] = 1; } #endif