00001
00002
00003
00004
00005 #pragma once
00006
00007
00010 class gv_arrayPTR
00011 {
00012 enum gv_arrayPTRType
00013 {
00014 gv_arrayPTR_VALUE,
00015 gv_arrayPTR_REFERENCE,
00016 };
00017 protected:
00018 gv_arrayPTRType m_ArrayListType;
00019 void* m_pData;
00020 unsigned int m_BytesPerEntry;
00021 unsigned int m_NumEntries;
00022 unsigned int m_NumEntriesAllocated;
00023
00024 public:
00025 gv_arrayPTR( gv_arrayPTRType Type=gv_arrayPTR_VALUE, unsigned int BytesPerEntry = 0 );
00026 virtual ~gv_arrayPTR( void );
00027 virtual int Add( void* pEntry );
00028 virtual void Remove( unsigned int Entry );
00029 virtual void* GetPtr( unsigned int Entry );
00030 virtual unsigned int Count( void ) { return m_NumEntries; }
00031 virtual bool Contains( void* pEntryDsata );
00032 virtual bool Contains( void* pEntryData, int& nIndex );
00033 virtual void Clear( void ) { m_NumEntries = 0; }
00034 };
00035
00036
00037 template <class T>
00038 class geArray
00039 {
00040
00041 public:
00042
00043 geArray()
00044 : data(0), allocated(0), used(0),
00045 free_when_destroyed(true), is_sorted(true)
00046 {
00047 }
00048
00051 geArray(unsigned int start_count)
00052 : data(0), allocated(0), used(0),
00053 free_when_destroyed(true), is_sorted(true)
00054 {
00055 reallocate(start_count);
00056 }
00057
00058
00060 geArray(const geArray<T>& other)
00061 : data(0)
00062 {
00063 *this = other;
00064 }
00065
00066
00067
00070 ~geArray()
00071 {
00072 if (free_when_destroyed)
00073 {
00074
00075
00076 if(data)
00077 delete []data;
00078 }
00079 }
00080
00081
00082
00085 void reallocate(unsigned int new_size)
00086 {
00087
00088 if(new_size==0) return;
00089
00090 T* old_data = data;
00091
00092
00093 data =new T[new_size];
00094 allocated = new_size;
00095
00096
00097 signed int end = used < new_size ? used : new_size;
00098
00099 for (signed int i=0; i<end; ++i)
00100 {
00101 data[i] = old_data[i];
00102
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 if (allocated < used)
00113 used = allocated;
00114
00115
00116
00117 if(old_data)
00118 delete []old_data;
00119
00120 }
00121
00125 void push_back(const T& element)
00126 {
00127 if (used + 1 > allocated)
00128 {
00129
00130
00131
00132
00133
00134 T e(element);
00135 reallocate(used * 2 +1);
00136
00137
00138 data[used++] = e;
00139
00140 is_sorted = false;
00141 return;
00142 }
00143
00144 data[used++] = element;
00145
00146
00147
00148 is_sorted = false;
00149 }
00150
00151
00156 void push_front(const T& element)
00157 {
00158 if (used + 1 > allocated)
00159 reallocate(used * 2 +1);
00160
00161 for (int i=(int)used; i>0; --i)
00162 {
00163 data[i] = data[i-1];
00164
00165 }
00166
00167 data[0] = element;
00168
00169
00170 is_sorted = false;
00171 ++used;
00172 }
00173
00174
00180 void insert(const T& element, unsigned int index=0)
00181 {
00182
00183
00184 if (used + 1 > allocated)
00185 reallocate(used * 2 +1);
00186
00187 for (unsigned int i=used++; i>index; i--)
00188
00189 data[i] = data[i-1];
00190
00191
00192 data[index] = element;
00193 is_sorted = false;
00194 }
00195
00196
00197
00198
00200 void clear()
00201 {
00202
00203
00204
00205
00206 if(data)
00207 delete [] data;
00208 data = 0;
00209 used = 0;
00210 allocated = 0;
00211 is_sorted = true;
00212 }
00213
00214
00215
00219 void set_pointer(T* newPointer, unsigned int size)
00220 {
00221
00222
00223
00224
00225 delete [] data;
00226 data = newPointer;
00227 allocated = size;
00228 used = size;
00229 is_sorted = false;
00230 }
00231
00232
00233
00237 void set_free_when_destroyed(bool f)
00238 {
00239 free_when_destroyed = f;
00240 }
00241
00242
00243
00245
00248 void set_used(unsigned int usedNow)
00249 {
00250 if (allocated < usedNow)
00251 reallocate(usedNow);
00252
00253 used = usedNow;
00254 }
00255
00256
00257
00259 void operator=(const geArray<T>& other)
00260 {
00261 if (data)
00262 {
00263
00264
00265
00266
00267 delete [] data;
00268 }
00269
00270
00271 if (other.allocated == 0)
00272 data = 0;
00273 else
00274 data = new T[other.allocated];
00275
00276 used = other.used;
00277 free_when_destroyed = other.free_when_destroyed;
00278 is_sorted = other.is_sorted;
00279 allocated = other.allocated;
00280
00281 for (unsigned int i=0; i<other.used; ++i)
00282
00283 data[i] = other.data[i];
00284 }
00285
00286
00288 T& operator [](unsigned int index)
00289 {
00290
00291
00292 return data[index];
00293 }
00294
00295
00296
00298 const T& operator [](unsigned int index) const
00299 {
00300
00301
00302 return data[index];
00303 }
00304
00306 T& getLast()
00307 {
00308
00309
00310 return data[used-1];
00311 }
00312
00313
00315 const T& getLast() const
00316 {
00317
00318
00319 return data[used-1];
00320 }
00321
00324 T* pointer()
00325 {
00326 return data;
00327 }
00328
00329
00330
00333 const T* const_pointer() const
00334 {
00335 return data;
00336 }
00337
00338
00339
00342 unsigned int size() const
00343 {
00344 return used;
00345 }
00346
00347
00348
00352 unsigned int allocated_size() const
00353 {
00354 return allocated;
00355 }
00356
00357
00358
00361 bool empty() const
00362 {
00363 return used == 0;
00364 }
00365
00366
00367
00370 void sort()
00371 {
00372 if (is_sorted || used<2)
00373 return;
00374
00375 heapsort(data, used);
00376 is_sorted = true;
00377 }
00378
00379
00380
00387 signed int binary_search(const T& element)
00388 {
00389 return binary_search(element, 0, used-1);
00390 }
00391
00392
00393
00402 signed int binary_search(const T& element, signed int left, signed int right)
00403 {
00404 if (!used)
00405 return -1;
00406
00407 sort();
00408
00409 signed int m;
00410
00411 do
00412 {
00413 m = (left+right)>>1;
00414
00415 if (element < data[m])
00416 right = m - 1;
00417 else
00418 left = m + 1;
00419
00420 } while((element < data[m] || data[m] < element) && left<=right);
00421
00422
00423
00424
00425
00426
00427 if (!(element < data[m]) && !(data[m] < element))
00428 return m;
00429
00430 return -1;
00431 }
00432
00433
00439 signed int linear_search(const T& element) const
00440 {
00441 for (unsigned int i=0; i<used; ++i)
00442 if (!(element < data[i]) && !(data[i] < element))
00443 return (signed int)i;
00444
00445 return -1;
00446 }
00447
00448
00454 signed int linear_reverse_search(const T& element) const
00455 {
00456 for (signed int i=used-1; i>=0; --i)
00457 if (data[i] == element)
00458 return (signed int)i;
00459
00460 return -1;
00461 }
00462
00463
00464
00468 void erase(unsigned int index)
00469 {
00470
00471
00472
00473 for (unsigned int i=index+1; i<used; ++i)
00474 {
00475
00476
00477 delete &data[i-1];
00478 data[i-1] = data[i];
00479 }
00480
00481
00482
00483 --used;
00484 }
00485
00486
00491 void erase(unsigned int index, signed int count)
00492 {
00493
00494
00495
00496 unsigned int i;
00497 for (i=index; i<index+count; ++i)
00498 {
00499
00500 delete &data[i];
00501 }
00502
00503 for (i=index+count; i<used; ++i)
00504 {
00505 if (i > index+count)
00506 {
00507
00508 delete &data[i-count];
00509 data[i-count]=0x00;
00510 }
00511
00512
00513 data[i-count] = data[i];
00514
00515 if (i >= used-count)
00516 {
00517
00518 delete &data[i];
00519 data[i]=0x00;
00520 }
00521 }
00522
00523 used-= count;
00524 }
00525
00526
00528 void set_sorted(bool _is_sorted)
00529 {
00530 is_sorted = _is_sorted;
00531 }
00532
00533
00534 private:
00535
00536 T* data;
00537 unsigned int allocated;
00538 unsigned int used;
00539 bool free_when_destroyed;
00540 bool is_sorted;
00541
00542 };
00543
00545 template <typename T>
00546 class gvString
00547 {
00548 private:
00549
00550 T* array;
00551 signed int allocated;
00552 signed int used;
00553
00554 public:
00555
00557 gvString()
00558 : array(0), allocated(1), used(1)
00559 {
00560 array = new T[1];
00561 array[0] = 0x0;
00562 }
00563
00564
00565
00567 gvString(const gvString<T>& other)
00568 : array(0), allocated(0), used(0)
00569 {
00570 *this = other;
00571 }
00572
00573
00575 gvString(double number)
00576 : array(0), allocated(0), used(0)
00577 {
00578 char tmpbuf[255];
00579 sprintf(tmpbuf,"%0.6f",number);
00580 *this = tmpbuf;
00581 }
00582
00584 gvString(int number)
00585 : array(0), allocated(0), used(0)
00586 {
00587
00588
00589 bool negative = false;
00590 if (number < 0)
00591 {
00592 number *= -1;
00593 negative = true;
00594 }
00595
00596
00597
00598 char tmpbuf[16];
00599 tmpbuf[15] = 0;
00600 signed int idx = 15;
00601
00602
00603
00604 if (!number)
00605 {
00606 tmpbuf[14] = '0';
00607 *this = &tmpbuf[14];
00608 return;
00609 }
00610
00611
00612
00613 while(number && idx)
00614 {
00615 idx--;
00616 tmpbuf[idx] = (char)('0' + (number % 10));
00617 number = number / 10;
00618 }
00619
00620
00621
00622 if (negative)
00623 {
00624 idx--;
00625 tmpbuf[idx] = '-';
00626 }
00627
00628 *this = &tmpbuf[idx];
00629 }
00630
00631
00632
00634 template <class B>
00635 gvString(const B* c, signed int length)
00636 : array(0), allocated(0), used(0)
00637 {
00638 if (!c)
00639 return;
00640
00641 allocated = used = length+1;
00642 array = new T[used];
00643
00644 for (signed int l = 0; l<length; ++l)
00645 array[l] = (T)c[l];
00646
00647 array[length] = 0;
00648 }
00649
00650
00651
00653 template <class B>
00654 gvString(const B* c)
00655 : array(0), allocated(0), used(0)
00656 {
00657 *this = c;
00658 }
00659
00660
00661
00663 ~gvString()
00664 {
00665 delete [] array;
00666 }
00667
00668
00669
00671 gvString<T>& operator=(const gvString<T>& other)
00672 {
00673 if (this == &other)
00674 return *this;
00675
00676 if(array)
00677 delete [] array;
00678
00679 allocated = used = other.size()+1;
00680 array = new T[used];
00681
00682 const T* p = other.c_str();
00683 for (signed int i=0; i<used; ++i, ++p)
00684 array[i] = *p;
00685
00686 return *this;
00687 }
00688
00689
00690
00692 template <class B>
00693 gvString<T>& operator=(const B* c)
00694 {
00695 if (!c)
00696 {
00697 if (!array)
00698 {
00699 array = new T[1];
00700 allocated = 1;
00701 }
00702 used = 1;
00703 array[0] = 0x0;
00704 return *this;
00705 }
00706
00707 if ((void*)c == (void*)array)
00708 return *this;
00709
00710 signed int len = 0;
00711 const B* p = c;
00712 while(*p)
00713 {
00714 ++len;
00715 ++p;
00716 }
00717
00718
00719
00720 T* oldArray = array;
00721
00722 allocated = used = len+1;
00723 array = new T[used];
00724
00725 for (signed int l = 0; l<len+1; ++l)
00726 array[l] = (T)c[l];
00727
00728 if(oldArray)
00729 delete [] oldArray;
00730 return *this;
00731 }
00732
00734 gvString<T> operator+(const gvString<T>& other) const
00735 {
00736 gvString<T> str(*this);
00737 str.append(other);
00738
00739 return str;
00740 }
00741
00743 template <class B>
00744 gvString<T> operator+(const B* c) const
00745 {
00746 gvString<T> str(*this);
00747 str.append(c);
00748
00749 return str;
00750 }
00751
00752
00753
00755 T& operator [](const signed int index) const
00756 {
00757
00758
00759 return array[index];
00760 }
00761
00762
00764 bool operator ==(const T* str) const
00765 {
00766 if (!str)
00767 return false;
00768 signed int i;
00769 for(i=0; array[i] && str[i]; ++i)
00770 if (array[i] != str[i])
00771 return false;
00772
00773 return !array[i] && !str[i];
00774 }
00775
00776
00777
00779 bool operator ==(const gvString<T>& other) const
00780 {
00781 for(signed int i=0; array[i] && other.array[i]; ++i)
00782 if (array[i] != other.array[i])
00783 return false;
00784
00785 return used == other.used;
00786 }
00787
00788
00789
00791 bool operator <(const gvString<T>& other) const
00792 {
00793 for(signed int i=0; array[i] && other.array[i]; ++i)
00794 if (array[i] != other.array[i])
00795 return (array[i] < other.array[i]);
00796
00797 return used < other.used;
00798 }
00799
00800
00801
00803 bool operator !=(const T* str) const
00804 {
00805 return !(*this == str);
00806 }
00807
00808
00809
00811 bool operator !=(const gvString<T>& other) const
00812 {
00813 return !(*this == other);
00814 }
00815
00816
00817
00819
00820 signed int size() const
00821 {
00822 return used-1;
00823 }
00824
00825
00826
00828
00829 const T* c_str() const
00830 {
00831 return array;
00832 }
00833
00834
00835
00837 void make_lower()
00838 {
00839 const T A = (T)'A';
00840 const T Z = (T)'Z';
00841 const T diff = (T)'a' - A;
00842
00843 for (signed int i=0; i<used; ++i)
00844 {
00845 if (array[i]>=A && array[i]<=Z)
00846 array[i] += diff;
00847 }
00848 }
00849
00850
00851
00853 void make_upper()
00854 {
00855 const T a = (T)'a';
00856 const T z = (T)'z';
00857 const T diff = (T)'A' - a;
00858
00859 for (signed int i=0; i<used; ++i)
00860 {
00861 if (array[i]>=a && array[i]<=z)
00862 array[i] += diff;
00863 }
00864 }
00865
00866
00867
00869
00871 bool equals_ignore_case(const gvString<T>& other) const
00872 {
00873 for(signed int i=0; array[i] && other[i]; ++i)
00874 if (toLower(array[i]) != toLower(other[i]))
00875 return false;
00876
00877 return used == other.used;
00878 }
00879
00880
00882 bool equalsn(const gvString<T>& other, int len) const
00883 {
00884 int i;
00885 for(i=0; array[i] && other[i] && i < len; ++i)
00886 if (array[i] != other[i])
00887 return false;
00888
00889
00890
00891 return (i == len) || (used == other.used);
00892 }
00893
00894
00896 bool equalsn(const T* str, int len) const
00897 {
00898 if (!str)
00899 return false;
00900 int i;
00901 for(i=0; array[i] && str[i] && i < len; ++i)
00902 if (array[i] != str[i])
00903 return false;
00904
00905
00906
00907 return (i == len) || (array[i] == 0 && str[i] == 0);
00908 }
00909
00910
00912
00913 void append(T character)
00914 {
00915 if (used + 1 > allocated)
00916 reallocate((signed int)used + 1);
00917
00918 used += 1;
00919
00920 array[used-2] = character;
00921 array[used-1] = 0;
00922 }
00923
00925
00926 void append(const T* other)
00927 {
00928 if (!other)
00929 return;
00930
00931 --used;
00932
00933 signed int len = 0;
00934 const T* p = other;
00935 while(*p)
00936 {
00937 ++len;
00938 ++p;
00939 }
00940
00941 if (used + len + 1 > allocated)
00942 reallocate((signed int)used + (signed int)len + 1);
00943
00944 for (signed int l=0; l<len+1; ++l)
00945 array[l+used] = *(other+l);
00946
00947 used = used + len + 1;
00948 }
00949
00950
00952
00953 void append(const gvString<T>& other)
00954 {
00955 --used;
00956
00957 signed int len = other.size();
00958
00959 if (used + len + 1 > allocated)
00960 reallocate((signed int)used + (signed int)len + 1);
00961
00962 for (signed int l=0; l<len+1; ++l)
00963 array[l+used] = other[l];
00964
00965 used = used + len + 1;
00966 }
00967
00968
00970
00972 void append(const gvString<T>& other, signed int length)
00973 {
00974 signed int len = other.size();
00975
00976 if (len < length)
00977 {
00978 append(other);
00979 return;
00980 }
00981
00982 len = length;
00983 --used;
00984
00985 if (used + len > allocated)
00986 reallocate((signed int)used + (signed int)len);
00987
00988 for (signed int l=0; l<len; ++l)
00989 array[l+used] = other[l];
00990
00991 used = used + len;
00992 }
00993
00994
00996
00997 void reserve(signed int count)
00998 {
00999 if (count < allocated)
01000 return;
01001
01002 reallocate(count);
01003 }
01004
01005
01007
01010 signed int findFirst(T c) const
01011 {
01012 for (signed int i=0; i<used; ++i)
01013 if (array[i] == c)
01014 return i;
01015
01016 return -1;
01017 }
01018
01020
01026 signed int findFirstChar(T* c, int count) const
01027 {
01028 if (!c)
01029 return -1;
01030
01031 for (signed int i=0; i<used; ++i)
01032 for (int j=0; j<count; ++j)
01033 if (array[i] == c[j])
01034 return i;
01035
01036 return -1;
01037 }
01038
01039
01041
01047 template <class B>
01048 signed int findFirstCharNotInList(B* c, int count) const
01049 {
01050 for (int i=0; i<used; ++i)
01051 {
01052 int j;
01053 for (j=0; j<count; ++j)
01054 if (array[i] == c[j])
01055 break;
01056
01057 if (j==count)
01058 return i;
01059 }
01060
01061 return -1;
01062 }
01063
01065
01071 template <class B>
01072 signed int findLastCharNotInList(B* c, int count) const
01073 {
01074 for (int i=used-2; i>=0; --i)
01075 {
01076 int j;
01077 for (j=0; j<count; ++j)
01078 if (array[i] == c[j])
01079 break;
01080
01081 if (j==count)
01082 return i;
01083 }
01084
01085 return -1;
01086 }
01087
01089
01093 signed int findNext(T c, signed int startPos) const
01094 {
01095 for (signed int i=startPos; i<used; ++i)
01096 if (array[i] == c)
01097 return i;
01098
01099 return -1;
01100 }
01101
01102
01107 signed int findLast(T c) const
01108 {
01109 for (signed int i=used-1; i>=0; --i)
01110 if (array[i] == c)
01111 return i;
01112
01113 return -1;
01114 }
01115
01120 template <class B>
01121 signed int find(B* str) const
01122 {
01123 if (str && *str)
01124 {
01125 int len = 0;
01126
01127 while (str[len])
01128 ++len;
01129
01130 for (int i=0; i<(int)(used-len); ++i)
01131 {
01132 int j=0;
01133
01134 while(str[j] && array[i+j] == str[j])
01135 ++j;
01136
01137 if (!str[j])
01138 return i;
01139 }
01140 }
01141
01142 return -1;
01143 }
01144
01145
01149 gvString<T> subString(signed int begin, signed int length) const
01150 {
01151 if (length <= 0)
01152 return gvString<T>("");
01153
01154 gvString<T> o;
01155 o.reserve(length+1);
01156
01157 for (signed int i=0; i<length; ++i)
01158 o.array[i] = array[i+begin];
01159
01160 o.array[length] = 0;
01161 o.used = o.allocated;
01162
01163 return o;
01164 }
01165
01166
01167 void operator += (T c)
01168 {
01169 append(c);
01170 }
01171
01172 void operator += (const T* c)
01173 {
01174 append(c);
01175 }
01176
01177 void operator += (const gvString<T>& other)
01178 {
01179 append(other);
01180 }
01181
01182 void operator += (int i)
01183 {
01184 append(gvString<T>(i));
01185 }
01186
01187 void operator += (double i)
01188 {
01189 append(gvString<T>(i));
01190 }
01191
01193 void replace(T toReplace, T replaceWith)
01194 {
01195 for (signed int i=0; i<used; ++i)
01196 if (array[i] == toReplace)
01197 array[i] = replaceWith;
01198 }
01199
01201
01202 void trim()
01203 {
01204 const char whitespace[] = " \t\n\r";
01205 const int whitespacecount = 4;
01206
01207
01208 int begin = findFirstCharNotInList(whitespace, whitespacecount);
01209 if (begin == -1)
01210 return;
01211
01212 int end = findLastCharNotInList(whitespace, whitespacecount);
01213 if (end == -1)
01214 return;
01215
01216 *this = subString(begin, (end +1) - begin);
01217 }
01218
01219
01223 void erase(int index)
01224 {
01225
01226
01227 for (int i=index+1; i<used; ++i)
01228 array[i-1] = array[i];
01229
01230 --used;
01231 }
01232
01233
01234
01235 private:
01236
01238 T toLower(const T& t) const
01239 {
01240 if (t>=(T)'A' && t<=(T)'Z')
01241 return t + ((T)'a' - (T)'A');
01242 else
01243 return t;
01244 }
01245
01247 void reallocate(signed int new_size)
01248 {
01249 T* old_array = array;
01250
01251 array = new T[new_size];
01252 allocated = new_size;
01253
01254 signed int amount = used < new_size ? used : new_size;
01255 for (signed int i=0; i<amount; ++i)
01256 array[i] = old_array[i];
01257
01258 if (allocated < used)
01259 used = allocated;
01260
01261 delete [] old_array;
01262 }
01263 };
01264
01265
01267 typedef gvString<char> stringc;
01268
01270 typedef gvString<unsigned short > stringw;
01271
01272
01273 typedef gvString<char> gvStringc;
01274 typedef gvString<unsigned short> gvStringw;
01275
01276
01277
01278
01279
01281 template <class T>
01282 class gvList
01283 {
01284 private:
01285
01287 struct SKListNode
01288 {
01289 SKListNode() : next(0), prev(0) {};
01290
01291 SKListNode* next;
01292 SKListNode* prev;
01293 T element;
01294 };
01295
01296 public:
01297
01299 class Iterator
01300 {
01301 public:
01302
01303 Iterator() : current(0) {};
01304
01305 Iterator& operator ++() { current = current->next; return *this; };
01306 Iterator& operator --() { current = current->prev; return *this; };
01307 Iterator operator ++(signed int) { Iterator tmp = *this; current = current->next; return tmp; };
01308 Iterator operator --(signed int) { Iterator tmp = *this; current = current->prev; return tmp; };
01309
01310 Iterator operator+(signed int num) const
01311 {
01312 Iterator tmp = *this;
01313
01314 if (num >= 0)
01315 while (num-- && tmp.current != 0) ++tmp;
01316 else
01317 while (num++ && tmp.current != 0) --tmp;
01318
01319 return tmp;
01320 }
01321
01322 Iterator& operator+=(signed int num)
01323 {
01324 if (num >= 0)
01325 while (num-- && this->current != 0) ++(*this);
01326 else
01327 while (num++ && this->current != 0) --(*this);
01328
01329 return *this;
01330 }
01331
01332 Iterator operator-(signed int num) const { return (*this)+(-num); }
01333 Iterator operator-=(signed int num) const { (*this)+=(-num); return *this; }
01334
01335 bool operator ==(const Iterator& other) const { return current == other.current; };
01336 bool operator !=(const Iterator& other) const { return current != other.current; };
01337
01338 T& operator *() { return current->element; };
01339
01340 private:
01341
01342 Iterator(SKListNode* begin) : current(begin) {};
01343
01344 friend class gvList<T>;
01345
01346 SKListNode* current;
01347 };
01348
01349
01351 gvList()
01352 : root(0), last(0), size(0) {}
01353
01354
01356 gvList(const gvList<T>& other)
01357 {
01358 *this = other;
01359 }
01360
01361
01363 ~gvList()
01364 {
01365 clear();
01366 }
01367
01368
01369
01371 void operator=(const gvList<T>& other)
01372 {
01373 clear();
01374
01375 SKListNode* node = other.root;
01376 while(node)
01377 {
01378 push_back(node->element);
01379 node = node->next;
01380 }
01381 }
01382
01383
01384
01387 unsigned int getSize() const
01388 {
01389 return size;
01390 }
01391
01392
01393
01396 void clear()
01397 {
01398 SKListNode* node = root;
01399 while(node)
01400 {
01401 SKListNode* next = node->next;
01402 delete node;
01403 node = next;
01404 }
01405
01406 root = 0;
01407 last = 0;
01408 size = 0;
01409 }
01410
01411
01412
01415 bool empty() const
01416 {
01417 return root == 0;
01418 }
01419
01420
01421
01424 void push_back(const T& element)
01425 {
01426 SKListNode* node = new SKListNode;
01427 node->element = element;
01428
01429 ++size;
01430
01431 if (root == 0)
01432 root = node;
01433
01434 node->prev = last;
01435
01436 if (last != 0)
01437 last->next = node;
01438
01439 last = node;
01440 }
01441
01442
01445 void push_front(const T& element)
01446 {
01447 SKListNode* node = new SKListNode;
01448 node->element = element;
01449
01450 ++size;
01451
01452 if (root == 0)
01453 {
01454 last = node;
01455 root = node;
01456 }
01457 else
01458 {
01459 node->next = root;
01460 root->prev = node;
01461 root = node;
01462 }
01463 }
01464
01465
01468 Iterator begin() const
01469 {
01470 return Iterator(root);
01471 }
01472
01473
01476 Iterator end() const
01477 {
01478 return Iterator(0);
01479 }
01480
01481
01484 Iterator getLast() const
01485 {
01486 return Iterator(last);
01487 }
01488
01489
01494 void insert_after(Iterator& it, const T& element)
01495 {
01496 SKListNode* node = new SKListNode;
01497 node->element = element;
01498
01499 node->next = it.current->next;
01500
01501 if (it.current->next)
01502 it.current->next->prev = node;
01503
01504 node->prev = it.current;
01505 it.current->next = node;
01506 ++size;
01507
01508 if (it.current == last)
01509 last = node;
01510 }
01511
01512
01517 void insert_before(Iterator& it, const T& element)
01518 {
01519 SKListNode* node = new SKListNode;
01520 node->element = element;
01521
01522 node->prev = it.current->prev;
01523
01524 if (it.current->prev)
01525 it.current->prev->next = node;
01526
01527 node->next = it.current;
01528 it.current->prev = node;
01529 ++size;
01530
01531 if (it.current == root)
01532 root = node;
01533 }
01534
01535
01539 Iterator erase(Iterator& it)
01540 {
01541 Iterator returnIterator(it);
01542 ++returnIterator;
01543
01544 if (it.current == root)
01545 root = it.current->next;
01546
01547 if (it.current == last)
01548 last = it.current->prev;
01549
01550 if (it.current->next)
01551 it.current->next->prev = it.current->prev;
01552
01553 if (it.current->prev)
01554 it.current->prev->next = it.current->next;
01555
01556 delete it.current;
01557 it.current = 0;
01558 --size;
01559
01560 return returnIterator;
01561 }
01562
01563 private:
01564
01565 SKListNode* root;
01566 SKListNode* last;
01567 unsigned int size;
01568
01569 };
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624