template class ItemAlloc { public: struct DataItem { DataItem* next; void* reserve[3]; T data[kPageItems]; }; public: ItemAlloc() :m_pages(0), first(nullptr), freefirst(nullptr), m_items(0), m_maxitems(0) { allocPage(); } public: void* allocPage() { m_pages++; DataItem* tmp = (DataItem *)new char[sizeof(DataItem)]; //initial for (int i = 0; i < kPageItems - 1; i++) { *(void**)(tmp->data+i) = tmp->data+(i + 1); } *(void**)&tmp->data[kPageItems - 1] = freefirst; tmp->next = first; first = tmp; freefirst = &tmp->data[0]; return tmp; } ~ItemAlloc() { if (!first)return; DataItem* p = first; DataItem* next = first->next; while (p) { ::free(p); if (!next)break; p = next; next = p->next; } } T* alloc() { if (!freefirst)allocPage(); T* p = freefirst; freefirst = (T*)*(void**)p; m_items++; if(m_items > m_maxitems) m_maxitems++; m_ttlitems++; return p; } void destroy(T* p) { if(p)p->~T(); free(p); } void free(void* p ) { m_items--; *(void**)p = freefirst; freefirst = (T*)p; } public: DataItem* first; T* freefirst; public: int m_pages; int m_items; int m_maxitems; int m_ttlitems; };