- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- File List
- File Members

# TPointerCollection.hpp

Go to the documentation of this file.

    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             // First we want to register the pointer deleter
    00335             this->registerPointerDeleter(pointerDeleter);
    00336
    00337             // Set the default growing size
    00338             this->setGrowSize();
    00339
    00340             // We have no pointers just yet
    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             // Check the index is within the correct range and we have valid pointers
    00362             if (m_array && (index >= 0) && (index < m_arraySize))
    00363             {
    00364                 // Return the pointer
    00365                 return m_array[index];
    00366             }
    00367
    00368             // They failed
    00369             return NULL;
    00370         }
    00371 //  ===========================================================================
    00372         template<class TypeName> const TypeName *TPointerCollection<TypeName>::constElementAtIndex(const long index) const
    00373         {
    00374             // Check the index is within the correct range and we have valid pointers
    00375             if (m_array && (index >= 0) && (index < m_arraySize))
    00376             {
    00377                 // Return the pointer
    00378                 return m_array[index];
    00379             }
    00380
    00381             // They failed
    00382             return NULL;
    00383         }
    00384
    00385 //  ===========================================================================
    00386         template<class TypeName> void TPointerCollection<TypeName>::addElement(TypeName *pointer)
    00387         {
    00388             // If we dont yet have an array, we want to create it
    00389             if (m_array == NULL)
    00390             {
    00391                 this->initialise();
    00392             }
    00393
    00394             // Check if we need more elements
    00395             if (m_insertIndex >= m_arraySize)
    00396             {
    00397                 this->expand();
    00398             }
    00399
    00400             // Add the element to the array
    00401             m_array[m_insertIndex++] = pointer;
    00402
    00403             // Notify handler
    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             // Check we have valid indicies and pointers
    00414             if (m_array && (index >= 0 && index < m_arraySize))
    00415             {
    00416                 // Delete the current position
    00417                 this->deletePointerAtIndex(index);
    00418
    00419                 // Now null the pointer in the array
    00420                 m_array[index] = pointer;
    00421
    00422                 // Notify handler
    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             // Check we have valid indicies and pointers
    00434             if (m_array && (index >= 0 && index < m_arraySize))
    00435             {
    00436                 // If we have a handler, let it do the deleting
    00437                 if (m_pointerDeletionHandler)
    00438                 {
    00439                     // Check its valid
    00440                     if (m_array[index] != NULL)
    00441                     {
    00442                         // Delete it
    00443                         m_pointerDeletionHandler->deletePointer(m_array[index]);
    00444                     }
    00445                 }
    00446
    00447                 // Now null the pointer in the array
    00448                 NULL_POINTER(m_array[index]);
    00449             }
    00450         }
    00451
    00452 //  ===========================================================================
    00453         template<class TypeName> TypeName *TPointerCollection<TypeName>::removeElementAtIndexWithoutDeletion(const long index)
    00454         {
    00455             // Check we have pointers and valid indicies
    00456             if (m_array && (index >= 0 && index < m_arraySize))
    00457             {
    00458                 // Get the object
    00459                 TypeName *object = m_array[index];
    00460
    00461                 // Null the position pointer
    00462                 NULL_POINTER(m_array[index]);
    00463
    00464                 // Return the new object
    00465                 return object;
    00466             }
    00467
    00468             // They failed!
    00469             return NULL;
    00470         }
    00471
    00472 //  ===========================================================================
    00473         template<class TypeName> void TPointerCollection<TypeName>::swapIndexes(const long index1, const long index2)
    00474         {
    00475             // If we have validity
    00476             if (m_array && index1 >= 0 && index2 >= 0 && index1 < m_arraySize && index2 < m_arraySize)
    00477             {
    00478                 // Copy the pointer
    00479                 TypeName *ptr   = m_array[index1];
    00480
    00481                 // Move first pointer
    00482                 m_array[index1] = m_array[index2];
    00483
    00484                 // STore the copy
    00485                 m_array[index2] = ptr;
    00486             }
    00487         }
    00488
    00489 //  ===========================================================================
    00490         template<class TypeName> void TPointerCollection<TypeName>::reorder(const bool resize)
    00491         {
    00492             // Check that we have values that are valid
    00493             if (m_array == NULL)
    00494             {
    00495                 return;
    00496             }
    00497
    00498             // Create a temporary array
    00499             TypeName **tempArray = new TypeName*[m_arraySize];
    00500
    00501             // Pointr to the final size
    00502             long index = 0;
    00503
    00504             // Copy everything
    00505             for (long i = 0; i < m_arraySize; i++)
    00506             {
    00507                 // Null the position
    00508                 NULL_POINTER(tempArray[i]);
    00509
    00510                 // If its non null
    00511                 if (m_array[i] != NULL)
    00512                 {
    00513                     // We want to add it
    00514                     tempArray[index++] = m_array[i];
    00515                 }
    00516             }
    00517
    00518             // We only resize if requested
    00519             if (resize)
    00520             {
    00521                 // We want to shrink the array
    00522                 if (index == m_arraySize)
    00523                 {
    00524                     // Dont need to do anything, no nulls
    00525                 }
    00526                 else
    00527                 {
    00528                     // Fewer elements
    00529                     TypeName **tempArray2 = new TypeName*[index];
    00530
    00531                     // Copy everything
    00532                     for (long i = 0; i < index; i++)
    00533                     {
    00534                         // We want to store it
    00535                         tempArray2[i] = tempArray[i];
    00536                     }
    00537
    00538                     // Store the new size
    00539                     m_arraySize   = index;
    00540                     m_insertIndex = m_arraySize;
    00541
    00542                     // Delete the old array
    00543                     FREE_ARRAY_POINTER(m_array);
    00544                     FREE_ARRAY_POINTER(tempArray);
    00545
    00546                     // Store the array
    00547                     m_array = tempArray2;
    00548
    00549                 }
    00550             }
    00551             else
    00552             {
    00553                 // Delete the old array
    00554                 FREE_ARRAY_POINTER(m_array);
    00555
    00556                 // Store the array
    00557                 m_array = tempArray;
    00558
    00559                 // Store the size ad the insert index
    00560                 // Size of the array has not changed
    00561                 m_insertIndex = index;
    00562             }
    00563         }
    00564
    00565 //  ===========================================================================
    00566         template<class TypeName> long TPointerCollection<TypeName>::getIndexOfPointer(const TypeName *pointer)
    00567         {
    00568             // If we have an array
    00569             if (m_array)
    00570             {
    00571                 // Loop through the pointers
    00572                 for (long i = 0; i < m_arraySize; i++)
    00573                 {
    00574                     // If its the one..
    00575                     if (pointer == m_array[i])
    00576                     {
    00577                         // Then we are done
    00578                         return i;
    00579                     }
    00580                 }
    00581             }
    00582
    00583             // Pointer is not in the array
    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             // Delete any old array that we may have
    00639             this->freePointers();
    00640
    00641             // Expand to the initial size
    00642             this->expand();
    00643         }
    00644
    00645 //  ===========================================================================
    00646         template<class TypeName> void TPointerCollection<TypeName>::expand()
    00647         {
    00648             // Create a temporary array
    00649             TypeName **tempArray = new TypeName*[m_arraySize + m_growSize];
    00650
    00651             // Copy everything in
    00652             for (long i = 0; i < m_arraySize + m_growSize; i++)
    00653             {
    00654                 // Copy as necessary
    00655                 tempArray[i] = (i < m_arraySize) ? m_array[i] : NULL;
    00656             }
    00657
    00658             // Increase the array size
    00659             m_arraySize += m_growSize;
    00660
    00661             // Delete the old array
    00662             FREE_ARRAY_POINTER(m_array);
    00663
    00664             // Now store the new pointers
    00665             m_array = tempArray;
    00666         }
    00667
    00668 //  ===========================================================================
    00669         template<class TypeName> void TPointerCollection<TypeName>::freePointers()
    00670         {
    00671             // Only if we have pointers
    00672             if (m_array)
    00673             {
    00674                 // If we have a handler, let it do the deleting
    00675                 if (m_pointerDeletionHandler)
    00676                 {
    00677                     // Delete all the elements
    00678                     for (long i = 0; i < m_arraySize; i++)
    00679                     {
    00680                         // Check its valid
    00681                         if (m_array[i] != NULL)
    00682                         {
    00683                             // Delete it
    00684                             m_pointerDeletionHandler->deletePointer(m_array[i]);
    00685                         }
    00686                     }
    00687                 }
    00688
    00689                 // Delete the array
    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