00001 #ifndef __TPointerCollection__
00002 #define __TPointerCollection__
00003
00004
00005
00006 #include "../Basics/CCountedObject.hpp"
00007 #include "TPointerDeleter.hpp"
00008 using Exponent::Basics::CCountedObject;
00009 using Exponent::Collections::TPointerDeleter;
00010 using Exponent::Collections::TObjectDeleter;
00011 using Exponent::Collections::TObjectNuller;
00012
00013
00014
00015
00016 namespace Exponent
00017 {
00018 namespace Collections
00019 {
00093 template<class TypeName> class TPointerCollection : public CCountedObject
00094 {
00096 EXPONENT_CLASS_DECLARATION;
00099
00100
00101 public:
00102
00103
00104
00105 static TObjectDeleter<TypeName> TPOINTER_COLLECTION_DEFAULT_DELETER;
00106 static TObjectNuller<TypeName> TPOINTER_COLLECTION_DEFAULT_NULLER;
00108
00109
00110 const static long TPOINTERCOLLECTION_DEFAULT_GROW_SIZE = 32;
00111 const static long TPOINTERCOLLECTION_FAILED_TO_FIND_POINTER = -1;
00113
00114
00128 typedef int (_cdecl *qsortCompare)(const void*, const void*);
00129
00130
00131
00136 TPointerCollection(TPointerDeleter<TypeName> *pointerDeleter = &TPOINTER_COLLECTION_DEFAULT_DELETER);
00137
00141 virtual ~TPointerCollection();
00142
00143
00144
00149 TypeName *operator [] (const long index);
00150
00151
00152
00158 TypeName *elementAtIndex(const long index);
00159
00165 const TypeName *constElementAtIndex(const long index) const;
00166
00171 void addElement(TypeName *pointer);
00172
00178 void addElementAtIndex(const long index, TypeName *pointer);
00179
00184 void deletePointerAtIndex(const long index);
00185
00192 TypeName *removeElementAtIndexWithoutDeletion(const long index);
00193
00194
00195
00201 void swapIndexes(const long index1, const long index2);
00202
00207 void reorder(const bool resize = true);
00208
00209
00210
00216 long getIndexOfPointer(const TypeName *pointer);
00217
00223 bool isPointerInArray(const TypeName *pointer);
00224
00229 long getArraySize() const;
00230
00235 long getInsertIndex() const;
00236
00240 void clearArray();
00241
00246 bool isArrayEmpty() const;
00247
00252 void setGrowSize(const long growSize = TPOINTERCOLLECTION_DEFAULT_GROW_SIZE);
00253
00258 long getNumberOfElementsUntilNextGrow();
00259
00260
00261
00266 void registerPointerDeleter(TPointerDeleter<TypeName> *pointerDeleter = &TPOINTER_COLLECTION_DEFAULT_DELETER) { m_pointerDeletionHandler = pointerDeleter; }
00267
00268
00269
00274 TypeName **getMutableInternalBuffer() { return m_array; }
00275
00280 void sortArray(qsortCompare compareFunction);
00281
00282
00283
00284 protected:
00285
00286
00287
00291 void initialise();
00292
00296 void expand();
00297
00301 void freePointers();
00302
00303
00304
00305 TypeName **m_array;
00306 TPointerDeleter<TypeName> *m_pointerDeletionHandler;
00307 long m_arraySize;
00308 long m_growSize;
00309 long m_insertIndex;
00311
00312
00313 };
00314
00319 EXPONENT_TEMPLATE_CLASS_IMPLEMENTATION(TPointerCollection<TypeName>, TypeName, CCountedObject);
00320
00321 template<class TypeName> TObjectDeleter<TypeName> TPointerCollection<TypeName>::TPOINTER_COLLECTION_DEFAULT_DELETER;
00322 template<class TypeName> TObjectNuller<TypeName> TPointerCollection<TypeName>::TPOINTER_COLLECTION_DEFAULT_NULLER;
00323
00324
00325 template<class TypeName> TPointerCollection<TypeName>::TPointerCollection(TPointerDeleter<TypeName> *pointerDeleter)
00326 : m_array(NULL)
00327 , m_pointerDeletionHandler(NULL)
00328 , m_arraySize(0)
00329 , m_growSize(0)
00330 , m_insertIndex(0)
00331 {
00332 EXPONENT_CLASS_CONSTRUCTION(TPointerCollection<TypeName>);
00333
00334
00335 this->registerPointerDeleter(pointerDeleter);
00336
00337
00338 this->setGrowSize();
00339
00340
00341 m_arraySize = 0;
00342 m_insertIndex = 0;
00343 NULL_POINTER(m_array);
00344 }
00345
00346
00347 template<class TypeName> TPointerCollection<TypeName>::~TPointerCollection()
00348 {
00349 EXPONENT_CLASS_DESTRUCTION(TPointerCollection<TypeName>);
00350 this->freePointers();
00351 }
00352
00353
00354 template<class TypeName> TypeName *TPointerCollection<TypeName>::operator [] (const long index)
00355 {
00356 return this->elementAtIndex(index);
00357 }
00358
00359 template<class TypeName> TypeName *TPointerCollection<TypeName>::elementAtIndex(const long index)
00360 {
00361
00362 if (m_array && (index >= 0) && (index < m_arraySize))
00363 {
00364
00365 return m_array[index];
00366 }
00367
00368
00369 return NULL;
00370 }
00371
00372 template<class TypeName> const TypeName *TPointerCollection<TypeName>::constElementAtIndex(const long index) const
00373 {
00374
00375 if (m_array && (index >= 0) && (index < m_arraySize))
00376 {
00377
00378 return m_array[index];
00379 }
00380
00381
00382 return NULL;
00383 }
00384
00385
00386 template<class TypeName> void TPointerCollection<TypeName>::addElement(TypeName *pointer)
00387 {
00388
00389 if (m_array == NULL)
00390 {
00391 this->initialise();
00392 }
00393
00394
00395 if (m_insertIndex >= m_arraySize)
00396 {
00397 this->expand();
00398 }
00399
00400
00401 m_array[m_insertIndex++] = pointer;
00402
00403
00404 if (m_pointerDeletionHandler)
00405 {
00406 m_pointerDeletionHandler->pointerAdded(pointer);
00407 }
00408 }
00409
00410
00411 template<class TypeName> void TPointerCollection<TypeName>::addElementAtIndex(const long index, TypeName *pointer)
00412 {
00413
00414 if (m_array && (index >= 0 && index < m_arraySize))
00415 {
00416
00417 this->deletePointerAtIndex(index);
00418
00419
00420 m_array[index] = pointer;
00421
00422
00423 if (m_pointerDeletionHandler)
00424 {
00425 m_pointerDeletionHandler->pointerAdded(pointer);
00426 }
00427 }
00428 }
00429
00430
00431 template<class TypeName> void TPointerCollection<TypeName>::deletePointerAtIndex(const long index)
00432 {
00433
00434 if (m_array && (index >= 0 && index < m_arraySize))
00435 {
00436
00437 if (m_pointerDeletionHandler)
00438 {
00439
00440 if (m_array[index] != NULL)
00441 {
00442
00443 m_pointerDeletionHandler->deletePointer(m_array[index]);
00444 }
00445 }
00446
00447
00448 NULL_POINTER(m_array[index]);
00449 }
00450 }
00451
00452
00453 template<class TypeName> TypeName *TPointerCollection<TypeName>::removeElementAtIndexWithoutDeletion(const long index)
00454 {
00455
00456 if (m_array && (index >= 0 && index < m_arraySize))
00457 {
00458
00459 TypeName *object = m_array[index];
00460
00461
00462 NULL_POINTER(m_array[index]);
00463
00464
00465 return object;
00466 }
00467
00468
00469 return NULL;
00470 }
00471
00472
00473 template<class TypeName> void TPointerCollection<TypeName>::swapIndexes(const long index1, const long index2)
00474 {
00475
00476 if (m_array && index1 >= 0 && index2 >= 0 && index1 < m_arraySize && index2 < m_arraySize)
00477 {
00478
00479 TypeName *ptr = m_array[index1];
00480
00481
00482 m_array[index1] = m_array[index2];
00483
00484
00485 m_array[index2] = ptr;
00486 }
00487 }
00488
00489
00490 template<class TypeName> void TPointerCollection<TypeName>::reorder(const bool resize)
00491 {
00492
00493 if (m_array == NULL)
00494 {
00495 return;
00496 }
00497
00498
00499 TypeName **tempArray = new TypeName*[m_arraySize];
00500
00501
00502 long index = 0;
00503
00504
00505 for (long i = 0; i < m_arraySize; i++)
00506 {
00507
00508 NULL_POINTER(tempArray[i]);
00509
00510
00511 if (m_array[i] != NULL)
00512 {
00513
00514 tempArray[index++] = m_array[i];
00515 }
00516 }
00517
00518
00519 if (resize)
00520 {
00521
00522 if (index == m_arraySize)
00523 {
00524
00525 }
00526 else
00527 {
00528
00529 TypeName **tempArray2 = new TypeName*[index];
00530
00531
00532 for (long i = 0; i < index; i++)
00533 {
00534
00535 tempArray2[i] = tempArray[i];
00536 }
00537
00538
00539 m_arraySize = index;
00540 m_insertIndex = m_arraySize;
00541
00542
00543 FREE_ARRAY_POINTER(m_array);
00544 FREE_ARRAY_POINTER(tempArray);
00545
00546
00547 m_array = tempArray2;
00548
00549 }
00550 }
00551 else
00552 {
00553
00554 FREE_ARRAY_POINTER(m_array);
00555
00556
00557 m_array = tempArray;
00558
00559
00560
00561 m_insertIndex = index;
00562 }
00563 }
00564
00565
00566 template<class TypeName> long TPointerCollection<TypeName>::getIndexOfPointer(const TypeName *pointer)
00567 {
00568
00569 if (m_array)
00570 {
00571
00572 for (long i = 0; i < m_arraySize; i++)
00573 {
00574
00575 if (pointer == m_array[i])
00576 {
00577
00578 return i;
00579 }
00580 }
00581 }
00582
00583
00584 return TPOINTERCOLLECTION_FAILED_TO_FIND_POINTER;
00585 }
00586
00587
00588 template<class TypeName> bool TPointerCollection<TypeName>::isPointerInArray(const TypeName *pointer)
00589 {
00590 return (this->getIndexOfPointer(pointer) != TPOINTERCOLLECTION_FAILED_TO_FIND_POINTER);
00591 }
00592
00593
00594 template<class TypeName> void TPointerCollection<TypeName>::clearArray()
00595 {
00596 this->freePointers();
00597 }
00598
00599
00600 template<class TypeName> long TPointerCollection<TypeName>::getArraySize() const
00601 {
00602 return m_arraySize;
00603 }
00604
00605
00606 template<class TypeName> long TPointerCollection<TypeName>::getInsertIndex() const
00607 {
00608 return m_insertIndex;
00609 }
00610
00611
00612 template<class TypeName> bool TPointerCollection<TypeName>::isArrayEmpty() const
00613 {
00614 return (m_arraySize == 0);
00615 }
00616
00617
00618 template<class TypeName> void TPointerCollection<TypeName>::setGrowSize(const long growSize)
00619 {
00620 m_growSize = growSize;
00621 }
00622
00623
00624 template<class TypeName> long TPointerCollection<TypeName>::getNumberOfElementsUntilNextGrow()
00625 {
00626 return m_arraySize - m_insertIndex;
00627 }
00628
00629
00630 template<class TypeName> void TPointerCollection<TypeName>::sortArray(qsortCompare compareFunction)
00631 {
00632 qsort(m_array, m_arraySize, sizeof(TypeName *), compareFunction);
00633 }
00634
00635
00636 template<class TypeName> void TPointerCollection<TypeName>::initialise()
00637 {
00638
00639 this->freePointers();
00640
00641
00642 this->expand();
00643 }
00644
00645
00646 template<class TypeName> void TPointerCollection<TypeName>::expand()
00647 {
00648
00649 TypeName **tempArray = new TypeName*[m_arraySize + m_growSize];
00650
00651
00652 for (long i = 0; i < m_arraySize + m_growSize; i++)
00653 {
00654
00655 tempArray[i] = (i < m_arraySize) ? m_array[i] : NULL;
00656 }
00657
00658
00659 m_arraySize += m_growSize;
00660
00661
00662 FREE_ARRAY_POINTER(m_array);
00663
00664
00665 m_array = tempArray;
00666 }
00667
00668
00669 template<class TypeName> void TPointerCollection<TypeName>::freePointers()
00670 {
00671
00672 if (m_array)
00673 {
00674
00675 if (m_pointerDeletionHandler)
00676 {
00677
00678 for (long i = 0; i < m_arraySize; i++)
00679 {
00680
00681 if (m_array[i] != NULL)
00682 {
00683
00684 m_pointerDeletionHandler->deletePointer(m_array[i]);
00685 }
00686 }
00687 }
00688
00689
00690 FREE_ARRAY_POINTER(m_array);
00691 }
00692 m_arraySize = 0;
00693 m_insertIndex = 0;
00694 }
00695
00697 }
00698 }
00699 #endif // End of TPointerCollection.hpp