llassoclist.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLASSOCLIST_H
00033 #define LL_LLASSOCLIST_H
00034 
00035 //------------------------------------------------------------------------
00036 // LLAssocList is an associative list container class.
00037 //
00038 // The implementation is a single linked list.
00039 // Both index and value objects are stored by value (not reference).
00040 // If pointer values are specified for index and/or value, this
00041 // container does NOT assume ownership of the referenced objects,
00042 // and does NOT delete() them on removal or destruction of the container.
00043 //
00044 // Note that operations are generally not optimized, and may of them
00045 // are O(n) complexity.
00046 //------------------------------------------------------------------------
00047 
00048 #include <iostream>
00049 
00050 template<class INDEX_TYPE, class VALUE_TYPE>
00051 class LLAssocList
00052 {
00053 private:
00054         // internal list node type
00055         class Node
00056         {
00057         public:
00058                 Node(const INDEX_TYPE &index, const VALUE_TYPE &value, Node *next)
00059                 {
00060                         mIndex = index;
00061                         mValue = value;
00062                         mNext = next;
00063                 }
00064                 ~Node() { }
00065                 INDEX_TYPE      mIndex;
00066                 VALUE_TYPE      mValue;
00067                 Node            *mNext;
00068         };
00069 
00070         // head of the linked list
00071         Node *mHead;
00072 
00073 public:
00074         // Constructor
00075         LLAssocList()
00076         {
00077                 mHead = NULL;
00078         }
00079 
00080         // Destructor
00081         ~LLAssocList()
00082         {
00083                 removeAll();
00084         }
00085 
00086         // Returns TRUE if list is empty.
00087         BOOL isEmpty()
00088         {
00089                 return (mHead == NULL);
00090         }
00091 
00092         // Returns the number of items in the list.
00093         U32 length()
00094         {
00095                 U32 count = 0;
00096                 for (   Node *node = mHead;
00097                                 node;
00098                                 node = node->mNext )
00099                 {
00100                         count++;
00101                 }
00102                 return count;
00103         }
00104 
00105         // Removes item with the specified index.
00106         BOOL remove( const INDEX_TYPE &index )
00107         {
00108                 if (!mHead)
00109                         return FALSE;
00110 
00111                 if (mHead->mIndex == index)
00112                 {
00113                         Node *node = mHead;
00114                         mHead = mHead->mNext;
00115                         delete node;
00116                         return TRUE;
00117                 }
00118 
00119                 for (   Node *prev = mHead;
00120                                 prev->mNext;
00121                                 prev = prev->mNext )
00122                 {
00123                         if (prev->mNext->mIndex == index)
00124                         {
00125                                 Node *node = prev->mNext;
00126                                 prev->mNext = prev->mNext->mNext;
00127                                 delete node;
00128                                 return TRUE;
00129                         }
00130                 }
00131                 return FALSE;
00132         }
00133 
00134         // Removes all items from the list.
00135         void removeAll()
00136         {
00137                 while ( mHead )
00138                 {
00139                         Node *node = mHead;
00140                         mHead = mHead->mNext;
00141                         delete node;
00142                 }
00143         }
00144 
00145         // Adds a new item to the head of the list,
00146         // removing any existing item with same index.
00147         void addToHead( const INDEX_TYPE &index, const VALUE_TYPE &value )
00148         {
00149                 remove(index);
00150                 Node *node = new Node(index, value, mHead);
00151                 mHead = node;
00152         }
00153 
00154         // Adds a new item to the end of the list,
00155         // removing any existing item with the same index.
00156         void addToTail( const INDEX_TYPE &index, const VALUE_TYPE &value )
00157         {
00158                 remove(index);
00159                 Node *node = new Node(index, value, NULL);
00160                 if (!mHead)
00161                 {
00162                         mHead = node;
00163                         return;
00164                 }
00165                 for (   Node *prev=mHead;
00166                                 prev;
00167                                 prev=prev->mNext )
00168                 {
00169                         if (!prev->mNext)
00170                         {
00171                                 prev->mNext=node;
00172                                 return;
00173                         }
00174                 }
00175         }
00176 
00177         // Sets the value of a specified index.
00178         // If index does not exist, a new value will be added only if
00179         // 'addIfNotFound' is set to TRUE.
00180         // Returns TRUE if successful.
00181         BOOL setValue( const INDEX_TYPE &index, const VALUE_TYPE &value, BOOL addIfNotFound=FALSE )
00182         {
00183                 VALUE_TYPE *valueP = getValue(index);
00184                 if (valueP)
00185                 {
00186                         *valueP = value;
00187                         return TRUE;
00188                 }
00189                 if (!addIfNotFound)
00190                         return FALSE;
00191                 addToTail(index, value);
00192                 return TRUE;
00193         }
00194 
00195         // Sets the ith value in the list.
00196         // A new value will NOT be addded, if the ith value does not exist.
00197         // Returns TRUE if successful.
00198         BOOL setValueAt( U32 i, const VALUE_TYPE &value )
00199         {
00200                 VALUE_TYPE *valueP = getValueAt(i);
00201                 if (valueP)
00202                 {
00203                         *valueP = value;
00204                         return TRUE;
00205                 }
00206                 return FALSE;
00207         }
00208 
00209         // Returns a pointer to the value for the specified index,
00210         // or NULL if no item found.
00211         VALUE_TYPE *getValue( const INDEX_TYPE &index )
00212         {
00213                 for (   Node *node = mHead;
00214                                 node;
00215                                 node = node->mNext )
00216                 {
00217                         if (node->mIndex == index)
00218                                 return &node->mValue;
00219                 }
00220                 return NULL;
00221         }
00222 
00223         // Returns a pointer to the ith value in the list, or
00224         // NULL if i is not valid.
00225         VALUE_TYPE *getValueAt( U32 i )
00226         {
00227                 U32 count = 0;
00228                 for (   Node *node = mHead;
00229                                 node;
00230                                 node = node->mNext )
00231                 {
00232                         if (count == i)
00233                                 return &node->mValue;
00234                         count++;
00235                 }
00236                 return NULL;
00237         }
00238 
00239         // Returns a pointer to the index for the specified index,
00240         // or NULL if no item found.
00241         INDEX_TYPE *getIndex( const INDEX_TYPE &index )
00242         {
00243                 for (   Node *node = mHead;
00244                                 node;
00245                                 node = node->mNext )
00246                 {
00247                         if (node->mIndex == index)
00248                                 return &node->mIndex;
00249                 }
00250                 return NULL;
00251         }
00252 
00253         // Returns a pointer to the ith index in the list, or
00254         // NULL if i is not valid.
00255         INDEX_TYPE *getIndexAt( U32 i )
00256         {
00257                 U32 count = 0;
00258                 for (   Node *node = mHead;
00259                                 node;
00260                                 node = node->mNext )
00261                 {
00262                         if (count == i)
00263                                 return &node->mIndex;
00264                         count++;
00265                 }
00266                 return NULL;
00267         }
00268 
00269         // Returns a pointer to the value for the specified index,
00270         // or NULL if no item found.
00271         VALUE_TYPE *operator[](const INDEX_TYPE &index)
00272         {
00273                 return getValue(index);
00274         }
00275 
00276         // Returns a pointer to the ith value in the list, or
00277         // NULL if i is not valid.
00278         VALUE_TYPE *operator[](U32 i)
00279         {
00280                 return getValueAt(i);
00281         }
00282 
00283         // Prints the list contents to the specified stream.
00284         friend std::ostream &operator<<( std::ostream &os, LLAssocList &map )
00285         {
00286                 os << "{";
00287                 for (   Node *node = map.mHead;
00288                                 node;
00289                                 node = node->mNext )
00290                 {
00291                         os << "<" << node->mIndex << ", " << node->mValue << ">";
00292                         if (node->mNext)
00293                                 os << ", ";
00294                 }
00295                 os << "}";
00296 
00297                 return os;
00298         }
00299 };
00300 
00301 #endif // LL_LLASSOCLIST_H

Generated on Thu Jul 1 06:08:19 2010 for Second Life Viewer by  doxygen 1.4.7