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

Infinity API - TPointerCollection.hpp Source File generated on 7 Mar 2007