Gel2D - The free/open source game creation suite

gelLinkedList.h
Go to the documentation of this file.
00001 /*
00002 Gel2D Game Engine - Cross-platform 2D gaming middleware
00003 Copyright (C) 2011 Mark D. Procarione
00004 
00005 Gel2D is free software: you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation, either version 3 of the License, or
00008 (at your option) any later version.
00009 
00010 Gel2D is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 GNU General Public License for more details.
00014 */
00015 
00016 #ifndef __GELLINKEDLIST_H__
00017 #define __GELLINKEDLIST_H__
00018 
00019 #include <cstdio>
00020 
00021 namespace gel
00022 {
00026 
00027         template <class dType> class GelListNode
00028         {
00029                 public:
00030                         GelListNode()
00031                         {
00032                                 // Warning! Undefined data. Only use this constructor for head!
00033                                 next = NULL;
00034                                 prev = NULL;
00035                         }
00036 
00037                         GelListNode( const dType &nodeData )
00038                         {
00039                                 data = nodeData;
00040                                 next = NULL;
00041                                 prev = NULL;
00042                         }
00043 
00044                 public: // This should probably be private
00045                         dType data;
00046                         GelListNode *next, *prev;
00047         };
00048 
00050 
00057         template <class dType> class GelLinkedList
00058     {
00059                 typedef GelListNode<dType> Node;
00060 
00061         public:
00063 
00064                         GelLinkedList()
00065                         {
00066                                 head = new Node();
00067                                 tail = new Node();
00068                                 size = 0;
00069                         }
00070 
00072                         GelLinkedList( const GelLinkedList<dType> &list )
00073                         {
00074                 head = new Node();
00075                                 tail = new Node();
00076                                 size = 0;
00077 
00078                             *this = list;
00079                         }
00080 
00082                         ~GelLinkedList()
00083                         {
00084                                 clear();
00085                                 delete head;
00086                                 delete tail;
00087                         }
00088 
00090 
00091                         void append( const dType &newData )
00092                         {
00093                                 Node *node = new Node(newData);
00094 
00095                                 if(head->next == NULL)
00096                                         head->next = node;
00097                                 if(tail->prev == NULL)
00098                                         tail->prev = node;
00099 
00100                                 node->next = tail;
00101                                 node->prev = tail->prev;
00102                                 node->prev->next = node;
00103                                 tail->prev = node;
00104 
00105                                 size++;
00106                         }
00107 
00109 
00110                         void prepend( const dType &newData )
00111                         {
00112                                 Node *node = new Node(newData);
00113 
00114                                 if(head->next == NULL)
00115                                         head->next = node;
00116                                 if(tail->prev == NULL)
00117                                         tail->prev = node;
00118 
00119                                 node->next = head->next;
00120                                 node->prev = head;
00121                                 node->next->prev = node;
00122                                 head->next = node;
00123 
00124                                 size++;
00125                         }
00126 
00128 
00130                         void insert( int i, const dType &newData )
00131                         {
00132                                 Node *node = new Node(newData);
00133                                 Node *after;
00134 
00135                                 if(i <= 0) prepend(newData);
00136                                 else if(i >= size-1) append(newData);
00137                                 else
00138                                 {
00139                                         after = _getNode(i);
00140 
00141                                         node->next = after;
00142                                         node->prev = after->prev;
00143                                         node->prev->next = node;
00144                                         after->prev = node;
00145 
00146                                         size++;
00147                                 }
00148                         }
00149 
00151                         void removeFirst()
00152                         {
00153                                 Node *tmp = head->next;
00154 
00155                                 head->next = head->next->next;
00156                                 head->next->prev = head;
00157 
00158                                 delete tmp;
00159 
00160                                 size--;
00161                         }
00162 
00164                         void removeLast()
00165                         {
00166                                 Node *tmp = tail->prev;
00167 
00168                                 tail->prev = tail->prev->prev;
00169                                 tail->prev->next = tail;
00170 
00171                                 delete tmp;
00172 
00173                                 size--;
00174                         }
00175 
00177 
00178                         void remove( int i )
00179                         {
00180                                 if(size == 0) return;
00181 
00182                                 if(i <= 0) removeFirst();
00183                                 else if(i >= size-1) removeLast();
00184                                 else
00185                                 {
00186                                         Node *node = _getNode(i);
00187 
00188                                         node->prev->next = node->next;
00189                                         node->next->prev = node->prev;
00190 
00191                                         delete node;
00192 
00193                                         size--;
00194                                 }
00195                         }
00196 
00198 
00200                         int removeAll( dType val )
00201                         {
00202                                 if(size == 0) return 0;
00203 
00204                                 Node *node = head->next;
00205                                 int num = 0;
00206                                 int count = 0;
00207 
00208                                 while(count < size)
00209                                 {
00210                                         if(node->data == val)
00211                                         {
00212                                                 Node *tmp = node;
00213                                                 node->prev->next = node->next;
00214                                                 node->next->prev = node->prev;
00215                                                 node = node->next;
00216                                                 delete tmp;
00217                                                 num++;
00218                                         }
00219                                         else
00220                                                 node = node->next;
00221 
00222                                         count++;
00223                                 }
00224 
00225                                 size-=num;
00226                                 return num;
00227                         }
00228 
00230 
00232                         void replace( int i, const dType &newData )
00233                         {
00234                                 _getNode(i)->data = newData;
00235                         }
00236 
00238 
00239                         dType &getFirst() { return head->next->data; }
00240 
00242 
00243                         const dType &getFirst() const { return head->next->data; }
00244 
00246 
00247                         dType &getLast() { return tail->prev->data; }
00248 
00250 
00251                         const dType &getLast() const { return tail->prev->data; }
00252 
00254 
00256                         dType &getItem( int i ) { return _getNode(i)->data; }
00257 
00259 
00260                         const dType &getItem( int i ) const { return _getNode(i)->data; }
00261 
00263 
00264                         dType takeFirst()
00265                         {
00266                                 dType data = getFirst();
00267                         removeFirst();
00268                         return data;
00269                         }
00270 
00272 
00273                         dType takeLast()
00274                         {
00275                                 dType data = getLast();
00276                         removeLast();
00277                         return data;
00278                         }
00279 
00281 
00283                         dType takeItem( int i )
00284                         {
00285                                 dType data = getItem(i);
00286                         remove(i);
00287                         return data;
00288                         }
00289 
00291 
00292                         void reverse()
00293                         {
00294                                 /*
00295                                 Node *result = NULL;
00296                                 Node *current = head->next;
00297                                 Node *next = NULL;
00298                                 int count = 0;
00299 
00300                                 while(count < size)
00301                                 {
00302                                         next = current->next;
00303                                         current->next = result;
00304                                         result = current;
00305                                         current = next;
00306                                 }
00307 
00308                                 head = result;
00309                                  */
00310                         }
00311 
00313 
00315                         int countAll( dType val )
00316                         {
00317                                 Node *node = head->next;
00318                                 int num = 0;
00319                                 int count = 0;
00320 
00321                                 while(count < size)
00322                                 {
00323                                         if(node->data == val)
00324                                                 num++;
00325 
00326                                         node = node->next;
00327                                         count++;
00328                                 }
00329 
00330                                 return num;
00331                         }
00332 
00334 
00335             int getSize() { return size; }
00336 
00338                         void clear()
00339                         {
00340                                 if(isEmpty()) return;
00341 
00342                                 //Node *tmp;
00343                                 Node *node = head->next;
00344                                 int count = 0;
00345 
00346                                 while(count < size)
00347                                 {
00348                                         Node *tmp = node;
00349                                         node = node->next;
00350                                         delete tmp;
00351                                         count++;
00352                                 }
00353 
00354                                 head->next = NULL;
00355                                 tail->prev = NULL;
00356 
00357                                 size = 0;
00358                         }
00359 
00361 
00363             bool isMember( const dType &val )
00364             {
00365                                 Node *node = head->next;
00366                                 int count = 0;
00367 
00368                                 while(count < size)
00369                                 {
00370                                         if(node->data == val)
00371                                                 return true;
00372 
00373                                         node = node->next;
00374                                         count++;
00375                                 }
00376                                 return false;
00377                         }
00378 
00380 
00381             bool isEmpty() { return !size; }
00382 
00384             GelLinkedList<dType> &operator = ( const GelLinkedList<dType> &l )
00385             {
00386                                 clear();
00387 
00388                 for(int i=0; i<l.size; i++)
00389                     append(l[i]);
00390 
00391                 return *this;
00392             }
00393 
00395             GelLinkedList<dType> &operator += ( const GelLinkedList<dType> &l )
00396             {
00397                 for(int i=0; i<l.size; i++)
00398                     append(l[i]);
00399 
00400                 return *this;
00401             }
00402 
00404 
00405             dType &operator[] ( int i ) { return getItem(i); }
00406 
00408 
00409             const dType &operator[] ( int i ) const { return getItem(i); }
00410 
00411         private:
00412                         GelListNode<dType> *_getNode( int i )
00413                         {
00414                                 Node *current = head->next;
00415                                 int count = 0;
00416 
00417                                 if(i <= 0) return head->next;
00418                                 else if(i >= size-1) return tail->prev;
00419                                 //if(i < 0) i = 0;
00420                                 //else if(i > size-1) i = size-1;
00421 
00422                                 // Determines whether to work backward or forward.
00423                                 // This cuts search time by half.
00424                                 // More optimizations would be welcome.
00425                                 if(i < (size/2))
00426                                 {
00427                                         while(count < i)
00428                                         {
00429                                                 current = current->next;
00430                                                 count++;
00431                                         }
00432                                 }
00433                                 else if(i >= (size/2))
00434                                 {
00435                                         current = tail->prev;
00436                                         count = size-1;
00437 
00438                                         while(count > i)
00439                                         {
00440                                                 current = current->prev;
00441                                                 count--;
00442                                         }
00443                                 }
00444 
00445                                 return current;
00446                         }
00447 
00448             const GelListNode<dType> *_getNode( int i ) const
00449                         {
00450                 Node *current = head->next;
00451                                 int count = 0;
00452 
00453                                 if(i <= 0) return head->next;
00454                                 else if(i >= size-1) return tail->prev;
00455                                 //if(i < 0) i = 0;
00456                                 //else if(i > size-1) i = size-1;
00457 
00458                                 // Determines whether to work backward or forward.
00459                                 // This cuts search time by half.
00460                                 // More optimizations would be welcome.
00461                                 if(i < (size/2))
00462                                 {
00463                                         while(count < i)
00464                                         {
00465                                                 current = current->next;
00466                                                 count++;
00467                                         }
00468                                 }
00469                                 else if(i >= (size/2))
00470                                 {
00471                                         current = tail->prev;
00472                                         count = size-1;
00473 
00474                                         while(count > i)
00475                                         {
00476                                                 current = current->prev;
00477                                                 count--;
00478                                         }
00479                                 }
00480 
00481                                 return current;
00482                         }
00483 
00484         private:
00485             GelListNode<dType> *head;
00486             GelListNode<dType> *tail;
00487             int size;
00488     };
00489 
00491 }
00492 
00493 #endif // __GELLINKEDLIST_H__