| Irrlicht 3D Engine |

irrList.h
Go to the documentation of this file.

    00001 // Copyright (C) 2002-2012 Nikolaus Gebhardt
    00002 // This file is part of the "Irrlicht Engine".
    00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
    00004
    00005 #ifndef __IRR_LIST_H_INCLUDED__
    00006 #define __IRR_LIST_H_INCLUDED__
    00007
    00008 #include "irrTypes.h"
    00009 #include "irrAllocator.h"
    00010 #include "irrMath.h"
    00011
    00012 namespace irr
    00013 {
    00014 namespace core
    00015 {
    00016
    00017
    00019 template <class T>
    00020 class list
    00021 {
    00022 private:
    00023
    00025     struct SKListNode
    00026     {
    00027         SKListNode(const T& e) : Next(0), Prev(0), Element(e) {}
    00028
    00029         SKListNode* Next;
    00030         SKListNode* Prev;
    00031         T Element;
    00032     };
    00033
    00034 public:
    00035     class ConstIterator;
    00036
    00038     class Iterator
    00039     {
    00040     public:
    00041         Iterator() : Current(0) {}
    00042
    00043         Iterator& operator ++()    { Current = Current->Next; return *this; }
    00044         Iterator& operator --()    { Current = Current->Prev; return *this; }
    00045         Iterator  operator ++(s32) { Iterator tmp = *this; Current = Current->Next; return tmp; }
    00046         Iterator  operator --(s32) { Iterator tmp = *this; Current = Current->Prev; return tmp; }
    00047
    00048         Iterator& operator +=(s32 num)
    00049         {
    00050             if(num > 0)
    00051             {
    00052                 while (num-- && this->Current != 0) ++(*this);
    00053             }
    00054             else
    00055             {
    00056                 while(num++ && this->Current != 0) --(*this);
    00057             }
    00058             return *this;
    00059         }
    00060
    00061         Iterator  operator + (s32 num) const { Iterator tmp = *this; return tmp += num; }
    00062         Iterator& operator -=(s32 num) { return (*this)+=(-num); }
    00063         Iterator  operator - (s32 num) const { return (*this)+ (-num); }
    00064
    00065         bool operator ==(const Iterator&      other) const { return Current == other.Current; }
    00066         bool operator !=(const Iterator&      other) const { return Current != other.Current; }
    00067         bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
    00068         bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
    00069
    00070         #if defined (_MSC_VER) && (_MSC_VER < 1300)
    00071             #pragma warning(disable:4284) // infix notation problem when using iterator operator ->
    00072         #endif
    00073
    00074         T & operator * () { return Current->Element; }
    00075         T * operator ->() { return &Current->Element; }
    00076
    00077     private:
    00078         explicit Iterator(SKListNode* begin) : Current(begin) {}
    00079
    00080         SKListNode* Current;
    00081
    00082         friend class list<T>;
    00083         friend class ConstIterator;
    00084     };
    00085
    00087     class ConstIterator
    00088     {
    00089     public:
    00090
    00091         ConstIterator() : Current(0) {}
    00092         ConstIterator(const Iterator& iter) : Current(iter.Current)  {}
    00093
    00094         ConstIterator& operator ++()    { Current = Current->Next; return *this; }
    00095         ConstIterator& operator --()    { Current = Current->Prev; return *this; }
    00096         ConstIterator  operator ++(s32) { ConstIterator tmp = *this; Current = Current->Next; return tmp; }
    00097         ConstIterator  operator --(s32) { ConstIterator tmp = *this; Current = Current->Prev; return tmp; }
    00098
    00099         ConstIterator& operator +=(s32 num)
    00100         {
    00101             if(num > 0)
    00102             {
    00103                 while(num-- && this->Current != 0) ++(*this);
    00104             }
    00105             else
    00106             {
    00107                 while(num++ && this->Current != 0) --(*this);
    00108             }
    00109             return *this;
    00110         }
    00111
    00112         ConstIterator  operator + (s32 num) const { ConstIterator tmp = *this; return tmp += num; }
    00113         ConstIterator& operator -=(s32 num) { return (*this)+=(-num); }
    00114         ConstIterator  operator - (s32 num) const { return (*this)+ (-num); }
    00115
    00116         bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
    00117         bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
    00118         bool operator ==(const Iterator&      other) const { return Current == other.Current; }
    00119         bool operator !=(const Iterator&      other) const { return Current != other.Current; }
    00120
    00121         const T & operator * () { return Current->Element; }
    00122         const T * operator ->() { return &Current->Element; }
    00123
    00124         ConstIterator & operator =(const Iterator & iterator) { Current = iterator.Current; return *this; }
    00125
    00126     private:
    00127         explicit ConstIterator(SKListNode* begin) : Current(begin) {}
    00128
    00129         SKListNode* Current;
    00130
    00131         friend class Iterator;
    00132         friend class list<T>;
    00133     };
    00134
    00136     list()
    00137         : First(0), Last(0), Size(0) {}
    00138
    00139
    00141     list(const list<T>& other) : First(0), Last(0), Size(0)
    00142     {
    00143         *this = other;
    00144     }
    00145
    00146
    00148     ~list()
    00149     {
    00150         clear();
    00151     }
    00152
    00153
    00155     void operator=(const list<T>& other)
    00156     {
    00157         if(&other == this)
    00158         {
    00159             return;
    00160         }
    00161
    00162         clear();
    00163
    00164         SKListNode* node = other.First;
    00165         while(node)
    00166         {
    00167             push_back(node->Element);
    00168             node = node->Next;
    00169         }
    00170     }
    00171
    00172
    00174
    00175     u32 size() const
    00176     {
    00177         return Size;
    00178     }
    00179     u32 getSize() const
    00180     {
    00181         return Size;
    00182     }
    00183
    00184
    00186
    00187     void clear()
    00188     {
    00189         while(First)
    00190         {
    00191             SKListNode * next = First->Next;
    00192             allocator.destruct(First);
    00193             allocator.deallocate(First);
    00194             First = next;
    00195         }
    00196
    00197         //First = 0; handled by loop
    00198         Last = 0;
    00199         Size = 0;
    00200     }
    00201
    00202
    00204
    00205     bool empty() const
    00206     {
    00207         return (First == 0);
    00208     }
    00209
    00210
    00212
    00213     void push_back(const T& element)
    00214     {
    00215         SKListNode* node = allocator.allocate(1);
    00216         allocator.construct(node, element);
    00217
    00218         ++Size;
    00219
    00220         if (First == 0)
    00221             First = node;
    00222
    00223         node->Prev = Last;
    00224
    00225         if (Last != 0)
    00226             Last->Next = node;
    00227
    00228         Last = node;
    00229     }
    00230
    00231
    00233
    00234     void push_front(const T& element)
    00235     {
    00236         SKListNode* node = allocator.allocate(1);
    00237         allocator.construct(node, element);
    00238
    00239         ++Size;
    00240
    00241         if (First == 0)
    00242         {
    00243             Last = node;
    00244             First = node;
    00245         }
    00246         else
    00247         {
    00248             node->Next = First;
    00249             First->Prev = node;
    00250             First = node;
    00251         }
    00252     }
    00253
    00254
    00256
    00257     Iterator begin()
    00258     {
    00259         return Iterator(First);
    00260     }
    00261
    00262
    00264
    00265     ConstIterator begin() const
    00266     {
    00267         return ConstIterator(First);
    00268     }
    00269
    00270
    00272
    00273     Iterator end()
    00274     {
    00275         return Iterator(0);
    00276     }
    00277
    00278
    00280
    00281     ConstIterator end() const
    00282     {
    00283         return ConstIterator(0);
    00284     }
    00285
    00286
    00288
    00289     Iterator getLast()
    00290     {
    00291         return Iterator(Last);
    00292     }
    00293
    00294
    00296
    00297     ConstIterator getLast() const
    00298     {
    00299         return ConstIterator(Last);
    00300     }
    00301
    00302
    00304
    00308     void insert_after(const Iterator& it, const T& element)
    00309     {
    00310         SKListNode* node = allocator.allocate(1);
    00311         allocator.construct(node, element);
    00312
    00313         node->Next = it.Current->Next;
    00314
    00315         if (it.Current->Next)
    00316             it.Current->Next->Prev = node;
    00317
    00318         node->Prev = it.Current;
    00319         it.Current->Next = node;
    00320         ++Size;
    00321
    00322         if (it.Current == Last)
    00323             Last = node;
    00324     }
    00325
    00326
    00328
    00332     void insert_before(const Iterator& it, const T& element)
    00333     {
    00334         SKListNode* node = allocator.allocate(1);
    00335         allocator.construct(node, element);
    00336
    00337         node->Prev = it.Current->Prev;
    00338
    00339         if (it.Current->Prev)
    00340             it.Current->Prev->Next = node;
    00341
    00342         node->Next = it.Current;
    00343         it.Current->Prev = node;
    00344         ++Size;
    00345
    00346         if (it.Current == First)
    00347             First = node;
    00348     }
    00349
    00350
    00352
    00354     Iterator erase(Iterator& it)
    00355     {
    00356         // suggest changing this to a const Iterator& and
    00357         // working around line: it.Current = 0 (possibly with a mutable, or just let it be garbage?)
    00358
    00359         Iterator returnIterator(it);
    00360         ++returnIterator;
    00361
    00362         if(it.Current == First)
    00363         {
    00364             First = it.Current->Next;
    00365         }
    00366         else
    00367         {
    00368             it.Current->Prev->Next = it.Current->Next;
    00369         }
    00370
    00371         if(it.Current == Last)
    00372         {
    00373             Last = it.Current->Prev;
    00374         }
    00375         else
    00376         {
    00377             it.Current->Next->Prev = it.Current->Prev;
    00378         }
    00379
    00380         allocator.destruct(it.Current);
    00381         allocator.deallocate(it.Current);
    00382         it.Current = 0;
    00383         --Size;
    00384
    00385         return returnIterator;
    00386     }
    00387
    00389
    00393     void swap(list<T>& other)
    00394     {
    00395         core::swap(First, other.First);
    00396         core::swap(Last, other.Last);
    00397         core::swap(Size, other.Size);
    00398         core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation
    00399     }
    00400
    00401
    00402 private:
    00403
    00404     SKListNode* First;
    00405     SKListNode* Last;
    00406     u32 Size;
    00407     irrAllocator<SKListNode> allocator;
    00408
    00409 };
    00410
    00411
    00412 } // end namespace core
    00413 }// end namespace irr
    00414
    00415 #endif
    00416