00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef TA_POOL_H
00013 #define TA_POOL_H
00014
00015 #ifndef TA_DEBUG_H
00016 #include "Debug.h"
00017 #endif // TA_DEBUG_H
00018
00019 #ifndef TA_COMMON_H
00020 #include "Common.h"
00021 #endif // TA_COMMON_H
00022
00023 #ifndef TA_TYPES_H
00024 #include "Types.h"
00025 #endif // TA_TYPES_H
00026
00027 namespace TA
00028 {
00029
00030 template <class Type, bool k_bDynamic = false>
00031 class TACOMMON_CLASS Pool
00032 {
00033 private:
00034 struct Item;
00035
00036 public:
00037 class ActiveList
00038 {
00039 public:
00040 class Iterator
00041 {
00042 public:
00043 Iterator() { m_pItem = 0; }
00044 ~Iterator() { }
00045 Iterator(Type* pItem) { Initialise((Item*)pItem); }
00046 Iterator(const Iterator& that) { m_pItem = that.m_pItem; }
00047 void Finalise() { m_pItem = 0; }
00048 void operator ++() { if (m_pItem) m_pItem = m_pItem->pNext; }
00049 void operator --()
00050 {
00051 Item* pNewItem = (Item*)((u32)(u8*)m_pItem->ppPrev - ((u32)(u8*)&m_pItem->pNext - (u32)(u8*)m_pItem));
00052 TA_ASSERT(pNewItem->pNext == m_pItem);
00053 m_pItem = pNewItem;
00054 }
00055 Iterator& operator = (const Iterator& that) { m_pItem = that.m_pItem; return *this; }
00056 bool operator == (const Iterator& that) const { return m_pItem == that.m_pItem; }
00057 Type& operator *() { return m_pItem->data; }
00058 bool AtEnd() { return m_pItem == 0; }
00059 private:
00060 friend class ActiveList;
00061 Iterator(Item* pItem) { Initialise(pItem); }
00062 void Initialise(Item* pItem) { m_pItem = pItem; }
00063 void AddAfter(Type* pItem)
00064 {
00065 TA_ASSERT_MSG(m_pItem, "Pool::Iterator::AddAfter. The iterator is off the end of the array");
00066 Item* pPoolItem = (Item*)(pItem);
00067 TA_ASSERT(pPoolItem);
00068 TA_ASSERT(pPoolItem->pNext == 0);
00069 TA_ASSERT(pPoolItem->ppPrev == 0);
00070
00071 pPoolItem->pNext = m_pItem->pNext;
00072 if (pPoolItem->pNext)
00073 pPoolItem->pNext->ppPrev = &pPoolItem->pNext;
00074
00075 m_pItem->pNext = pPoolItem;
00076 pPoolItem->ppPrev = &m_pItem->pNext;
00077 }
00078 void AddBefore(Type* pItem)
00079 {
00080 TA_ASSERT_MSG(m_pItem, "Pool::Iterator::AddBefore. The iterator is off the end of the array");
00081 Item* pPoolItem = (Item*)(pItem);
00082 TA_ASSERT(pPoolItem);
00083 TA_ASSERT(pPoolItem->pNext == 0);
00084 TA_ASSERT(pPoolItem->ppPrev == 0);
00085
00086 pPoolItem->pNext = m_pItem;
00087 pPoolItem->ppPrev = m_pItem->ppPrev;
00088 *m_pItem->ppPrev = pPoolItem;
00089 m_pItem->ppPrev = &pPoolItem->pNext;
00090 }
00091 Item* m_pItem;
00092 };
00093
00094
00095
00096 ActiveList() { m_pStart = 0; }
00097
00098
00099
00100 void Finalise()
00101 {
00102 #ifdef _DEBUG
00103 while (m_pStart)
00104 {
00105 Item* pItem = m_pStart;
00106 pItem->pNext = 0;
00107 pItem->ppPrev = 0;
00108 m_pStart = m_pStart->pNext;
00109 }
00110 #else // _DEBUG
00111 m_pStart = 0;
00112 #endif // _DEBUG
00113 }
00114
00115
00116
00117 Iterator GetIterator() { return Iterator(m_pStart); }
00118
00119
00120
00121 void Add(Type* pItem)
00122 {
00123
00124 Item* pPoolItem = (Item*)(pItem);
00125 TA_ASSERT(pPoolItem);
00126 TA_ASSERT(pPoolItem->pNext == 0);
00127 TA_ASSERT(pPoolItem->ppPrev == 0);
00128
00129 pPoolItem->pNext = m_pStart;
00130 if (pPoolItem->pNext)
00131 pPoolItem->pNext->ppPrev = &pPoolItem->pNext;
00132 m_pStart = pPoolItem;
00133 pPoolItem->ppPrev = &m_pStart;
00134 }
00135
00136
00137
00138
00139
00140
00141 void AddToEnd(Type* pItem)
00142 {
00143 Item* pPoolItem = (Item*)(pItem);
00144 TA_ASSERT(pPoolItem);
00145 TA_ASSERT(pPoolItem->pNext == 0);
00146 TA_ASSERT(pPoolItem->ppPrev == 0);
00147 Item* pTmpItem = m_pStart;
00148 Item** ppPrev = &m_pStart;
00149 while (pTmpItem)
00150 {
00151 ppPrev = &pTmpItem->pNext;
00152 pTmpItem = pTmpItem->pNext;
00153 }
00154 TA_ASSERT((*ppPrev) == 0);
00155 (*ppPrev) = pPoolItem;
00156 pPoolItem->ppPrev = ppPrev;
00157 pPoolItem->pNext = 0;
00158 }
00159
00160
00161
00162 void AddAfter(Type* pItem, Iterator it)
00163 {
00164 it.AddAfter(pItem);
00165
00166
00167 }
00168
00169
00170
00171 void AddBefore(Type* pItem, Iterator it)
00172 {
00173 it.AddBefore(pItem);
00174
00175
00176 }
00177
00178
00179
00180 void Remove(Type* pItem)
00181 {
00182
00183 Item* pPoolItem = (Item*)(pItem);
00184 TA_ASSERT(pPoolItem);
00185 TA_ASSERT(pPoolItem->ppPrev);
00186 #ifdef _DEBUG
00187 if (g_bDebugHeavy)
00188 {
00189
00190 bool bFound = false;
00191 Item* pTestItem = m_pStart;
00192 while (pTestItem)
00193 {
00194 if (pTestItem == pPoolItem)
00195 {
00196 bFound = true;
00197 break;
00198 }
00199 pTestItem = pTestItem->pNext;
00200 }
00201 TA_ASSERT(bFound);
00202 }
00203 #endif // _DEBUG
00204
00205 *pPoolItem->ppPrev = pPoolItem->pNext;
00206 if (pPoolItem->pNext)
00207 pPoolItem->pNext->ppPrev = pPoolItem->ppPrev;
00208
00209 #ifdef _DEBUG
00210 pPoolItem->pNext = 0;
00211 pPoolItem->ppPrev = 0;
00212 #endif // _DEBUG
00213 }
00214
00215
00216
00217 void SwapWith(ActiveList& activeList)
00218 {
00219 Item* pTmp = activeList.m_pStart;
00220 activeList.m_pStart = m_pStart;
00221 m_pStart = pTmp;
00222 if (m_pStart)
00223 m_pStart->ppPrev = &m_pStart;
00224 if (activeList.m_pStart)
00225 activeList.m_pStart->ppPrev = &activeList.m_pStart;
00226 }
00227
00228
00229
00230 void TestList()
00231 {
00232 #ifdef _DEBUG
00233 Item* pTestItem = m_pStart;
00234 while (pTestItem)
00235 {
00236 if (pTestItem->pNext)
00237 TA_ASSERT(pTestItem->pNext->ppPrev == &pTestItem->pNext);
00238 TA_ASSERT((*pTestItem->ppPrev) == pTestItem);
00239 pTestItem = pTestItem->pNext;
00240 }
00241 #endif // _DEBUG
00242 }
00243
00244
00245
00246 bool IsInList(const Type* pItem)
00247 {
00248 const Item* pPoolItem = (Item*)(pItem);
00249 Item* pTestItem = m_pStart;
00250 while (pTestItem)
00251 {
00252 if (pTestItem == pPoolItem)
00253 {
00254 return true;
00255 }
00256 pTestItem = pTestItem->pNext;
00257 }
00258 return false;
00259 }
00260
00261
00262
00263
00264
00265 static void TAC_CALL StaticRemove(Type* pItem)
00266 {
00267
00268 Item* pPoolItem = (Item*)(pItem);
00269 TA_ASSERT(pPoolItem);
00270 TA_ASSERT(pPoolItem->ppPrev);
00271 *pPoolItem->ppPrev = pPoolItem->pNext;
00272 if (pPoolItem->pNext)
00273 pPoolItem->pNext->ppPrev = pPoolItem->ppPrev;
00274
00275 #ifdef _DEBUG
00276 pPoolItem->pNext = 0;
00277 pPoolItem->ppPrev = 0;
00278 #endif // _DEBUG
00279 }
00280
00281
00282
00283
00284 int GetSize()
00285 {
00286 int nSize = 0;
00287 for (Iterator it = GetIterator(); !it.AtEnd(); ++it)
00288 nSize++;
00289 return nSize;
00290 }
00291
00292
00293
00294 void Merge(ActiveList& activeList)
00295 {
00296 if (m_pStart)
00297 {
00298 Item* pEnd = m_pStart;
00299 while (pEnd->pNext)
00300 pEnd = pEnd->pNext;
00301 pEnd->pNext = activeList.m_pStart;
00302 pEnd->pNext->ppPrev = &pEnd->pNext;
00303 }
00304 else
00305 {
00306 m_pStart = activeList.m_pStart;
00307 if (m_pStart && m_pStart->pNext)
00308 m_pStart->pNext->ppPrev = &m_pStart;
00309 }
00310 activeList.m_pStart = 0;
00311 }
00312
00313 Item* GetHead() { return m_pStart; }
00314 bool IsEmpty() { return m_pStart == 0; }
00315
00316 private:
00317 Item* m_pStart;
00318 };
00319
00320
00321 class ActiveListHeadAndTail
00322 {
00323 public:
00324 class Iterator
00325 {
00326 public:
00327 Iterator() { m_pItem = 0; }
00328 ~Iterator() { }
00329 Iterator(Type* pItem) { Initialise((Item*)pItem); }
00330 Iterator(const Iterator& that) { m_pItem = that.m_pItem; }
00331 void Finalise() { m_pItem = 0; }
00332 void operator ++() { if (m_pItem) m_pItem = m_pItem->pNext; }
00333 void operator --()
00334 {
00335 Item* pNewItem = (Item*)((u32)(u8*)m_pItem->ppPrev - ((u32)(u8*)&m_pItem->pNext - (u32)(u8*)m_pItem));
00336 TA_ASSERT(pNewItem->pNext == m_pItem);
00337 m_pItem = pNewItem;
00338 }
00339 Iterator& operator = (const Iterator& that) { m_pItem = that.m_pItem; return *this; }
00340 bool operator == (const Iterator& that) const { return m_pItem == that.m_pItem; }
00341 Type& operator *() { return m_pItem->data; }
00342 bool AtEnd() { return m_pItem == 0; }
00343 private:
00344 friend class ActiveListHeadAndTail;
00345 Iterator(Item* pItem) { Initialise(pItem); }
00346 void Initialise(Item* pItem) { m_pItem = pItem; }
00347 void AddAfter(Type* pItem)
00348 {
00349 TA_ASSERT_MSG(m_pItem, "Pool::Iterator::AddAfter. The iterator is off the end of the array");
00350 Item* pPoolItem = (Item*)(pItem);
00351 TA_ASSERT(pPoolItem);
00352 TA_ASSERT(pPoolItem->pNext == 0);
00353 TA_ASSERT(pPoolItem->ppPrev == 0);
00354
00355 pPoolItem->pNext = m_pItem->pNext;
00356 if (pPoolItem->pNext)
00357 pPoolItem->pNext->ppPrev = &pPoolItem->pNext;
00358
00359 m_pItem->pNext = pPoolItem;
00360 pPoolItem->ppPrev = &m_pItem->pNext;
00361 }
00362 void AddBefore(Type* pItem)
00363 {
00364 TA_ASSERT_MSG(m_pItem, "Pool::Iterator::AddBefore. The iterator is off the end of the array");
00365 Item* pPoolItem = (Item*)(pItem);
00366 TA_ASSERT(pPoolItem);
00367 TA_ASSERT(pPoolItem->pNext == 0);
00368 TA_ASSERT(pPoolItem->ppPrev == 0);
00369
00370 pPoolItem->pNext = m_pItem;
00371 pPoolItem->ppPrev = m_pItem->ppPrev;
00372 *m_pItem->ppPrev = pPoolItem;
00373 m_pItem->ppPrev = &pPoolItem->pNext;
00374 }
00375 Item* m_pItem;
00376 };
00377
00378
00379
00380 ActiveListHeadAndTail() { m_pStart = 0; m_pEnd = 0; }
00381
00382
00383
00384 void Finalise()
00385 {
00386 #ifdef _DEBUG
00387 while (m_pStart)
00388 {
00389 Item* pItem = m_pStart;
00390 pItem->pNext = 0;
00391 pItem->ppPrev = 0;
00392 m_pStart = m_pStart->pNext;
00393 }
00394 #else // _DEBUG
00395 m_pStart = 0;
00396 #endif // _DEBUG
00397 m_pEnd = 0;
00398 }
00399
00400
00401
00402 Iterator GetIterator() { return Iterator(m_pStart); }
00403
00404
00405
00406 void Add(Type* pItem)
00407 {
00408
00409 Item* pPoolItem = (Item*)(pItem);
00410 TA_ASSERT(pPoolItem);
00411 TA_ASSERT(pPoolItem->pNext == 0);
00412 TA_ASSERT(pPoolItem->ppPrev == 0);
00413
00414 pPoolItem->pNext = m_pStart;
00415 if (pPoolItem->pNext)
00416 pPoolItem->pNext->ppPrev = &pPoolItem->pNext;
00417 m_pStart = pPoolItem;
00418 pPoolItem->ppPrev = &m_pStart;
00419 if (m_pEnd == 0)
00420 m_pEnd = pPoolItem;
00421 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00422 }
00423
00424
00425
00426
00427
00428
00429 void AddToEnd(Type* pItem)
00430 {
00431 Item* pPoolItem = (Item*)(pItem);
00432 TA_ASSERT(pPoolItem);
00433 TA_ASSERT(pPoolItem->pNext == 0);
00434 TA_ASSERT(pPoolItem->ppPrev == 0);
00435
00436 if (m_pEnd)
00437 {
00438 pPoolItem->pNext = m_pEnd->pNext;
00439 if (pPoolItem->pNext)
00440 pPoolItem->pNext->ppPrev = &pPoolItem->pNext;
00441
00442 m_pEnd->pNext = pPoolItem;
00443 pPoolItem->ppPrev = &m_pEnd->pNext;
00444
00445 m_pEnd = pPoolItem;
00446 }
00447 else
00448 {
00449 TA_ASSERT(m_pStart == 0);
00450 m_pStart = pPoolItem;
00451 pPoolItem->pNext = 0;
00452 pPoolItem->ppPrev = &m_pStart;
00453 m_pEnd = pPoolItem;
00454 }
00455 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00456 }
00457
00458
00459
00460 void AddAfter(Type* pItem, Iterator it)
00461 {
00462 if (m_pEnd == it.m_pItem)
00463 m_pEnd = (Item*)(pItem);
00464 it.AddAfter(pItem);
00465
00466
00467 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00468 }
00469
00470
00471
00472 void AddBefore(Type* pItem, Iterator it)
00473 {
00474 it.AddBefore(pItem);
00475
00476
00477 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00478 }
00479
00480
00481
00482 void Remove(Type* pItem)
00483 {
00484 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00485
00486 Item* pPoolItem = (Item*)(pItem);
00487 TA_ASSERT(pPoolItem);
00488 TA_ASSERT(pPoolItem->ppPrev);
00489 #ifdef _DEBUG
00490 if (g_bDebugHeavy)
00491 {
00492
00493 bool bFound = false;
00494 Item* pTestItem = m_pStart;
00495 while (pTestItem)
00496 {
00497 if (pTestItem == pPoolItem)
00498 {
00499 bFound = true;
00500 break;
00501 }
00502 pTestItem = pTestItem->pNext;
00503 }
00504 TA_ASSERT(bFound);
00505 }
00506 #endif // _DEBUG
00507
00508 if (m_pEnd == pPoolItem)
00509 {
00510 if (m_pStart == pPoolItem)
00511 {
00512 m_pEnd = 0;
00513 }
00514 else
00515 {
00516 Item* pNewItem =
00517 (Item*)((uSize)(u8*)m_pEnd->ppPrev - ((uSize)(u8*)&m_pEnd->pNext - (uSize)(u8*)m_pEnd));
00518 TA_ASSERT(pNewItem->pNext == m_pEnd);
00519 m_pEnd = pNewItem;
00520 }
00521 }
00522
00523 *pPoolItem->ppPrev = pPoolItem->pNext;
00524 if (pPoolItem->pNext)
00525 pPoolItem->pNext->ppPrev = pPoolItem->ppPrev;
00526
00527 #ifdef _DEBUG
00528 pPoolItem->pNext = 0;
00529 pPoolItem->ppPrev = 0;
00530 #endif // _DEBUG
00531 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00532 }
00533
00534
00535
00536 void SwapWith(ActiveListHeadAndTail& activeList)
00537 {
00538 Item* pTmp = activeList.m_pStart;
00539 activeList.m_pStart = m_pStart;
00540 m_pStart = pTmp;
00541 if (m_pStart)
00542 m_pStart->ppPrev = &m_pStart;
00543 if (activeList.m_pStart)
00544 activeList.m_pStart->ppPrev = &activeList.m_pStart;
00545 pTmp = activeList.m_pEnd;
00546 activeList.m_pEnd = m_pEnd;
00547 m_pEnd = pTmp;
00548 TA_ASSERT((m_pEnd && m_pStart) || (!m_pEnd && !m_pStart));
00549 TA_ASSERT((activeList.m_pEnd && activeList.m_pStart) || (!activeList.m_pEnd && !activeList.m_pStart));
00550 }
00551
00552
00553
00554 void TestList()
00555 {
00556 #ifdef _DEBUG
00557 Item* pTestItem = m_pStart;
00558 while (pTestItem)
00559 {
00560 if (pTestItem->pNext)
00561 TA_ASSERT(pTestItem->pNext->ppPrev == &pTestItem->pNext);
00562 TA_ASSERT((*pTestItem->ppPrev) == pTestItem);
00563 pTestItem = pTestItem->pNext;
00564 }
00565 #endif // _DEBUG
00566 }
00567
00568
00569
00570 bool IsInList(Type* pItem)
00571 {
00572 Item* pPoolItem = (Item*)(pItem);
00573 Item* pTestItem = m_pStart;
00574 while (pTestItem)
00575 {
00576 if (pTestItem == pPoolItem)
00577 {
00578 return true;
00579 }
00580 pTestItem = pTestItem->pNext;
00581 }
00582 return false;
00583 }
00584
00585
00586
00587
00588 int GetSize()
00589 {
00590 int nSize = 0;
00591 for (Iterator it = GetIterator(); !it.AtEnd(); ++it)
00592 nSize++;
00593 return nSize;
00594 }
00595
00596 Item* GetHead() { return m_pStart; }
00597 Item* GetTail() { return m_pEnd; }
00598 bool IsEmpty() { return m_pStart == 0; }
00599
00600 private:
00601 Item* m_pStart;
00602 Item* m_pEnd;
00603 };
00604
00605 Pool();
00606 ~Pool();
00607 void Initialise(int nSize);
00608 void Finalise();
00609
00610 bool IsInitialised();
00611
00612 Type* Alloc();
00613 void Free(Type* pItem);
00614 void FreeAllItemsInActiveList(ActiveList& activeList);
00615 int GetNumItemsFree();
00616 bool FreeItemAvailable();
00617 int GetSize();
00618
00619 private:
00620 friend class ActiveList;
00621
00622 struct Item
00623 {
00624 Type data;
00625 Item* pNext;
00626 Item** ppPrev;
00627 };
00628
00629 struct MemBlock
00630 {
00631 Item* pItemList;
00632 MemBlock* pNext;
00633 };
00634
00635
00636 int m_nSize;
00637 MemBlock m_memory;
00638 ActiveList m_freeList;
00639 };
00640
00641 }
00642
00643 #include "Pool.inl"
00644
00645 #endif // TA_POOL_H
© Copyright 2004-2006 TRUE AXIS PTY LTD Australia. All rights reserved.