00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _UT_LISTS_H_
00026 #define _UT_LISTS_H_
00027
00028
00029
00030
00031
00032 #include "UT.h"
00033
00034
00035
00036 template <class T>
00037 class Array_t
00038
00046 {
00047
00048 public:
00049
00050 Array_t();
00052
00053 Array_t( T* stack_buffer, int stack_buffer_num_items_allcoated );
00057
00058 ~Array_t();
00062
00063 void InstallStackBuffer( T* stack_buffer, int stack_buffer_num_items_allcoated );
00065
00066 T AddHead(const T& item);
00068
00069 T AddTail(const T& item);
00071
00072 T AddItemAt( const T& item, int index );
00077
00078 T RemoveHead();
00080
00081 T RemoveTail();
00083
00084 T RemoveItemAt(int index);
00087
00088 inline int CountItems() const;
00090
00091 inline int AllocatedItems() const;
00094
00095 inline void SetNumValidItems(int count);
00100
00101 void GrowIfNeeded( int min_allocated_items, bool expect_more_growth = false );
00106
00107 inline T Head() const;
00109
00110 inline T Tail() const;
00112
00113 inline T ItemAt(int index) const;
00118
00119 inline T& operator [](int index) const;
00125
00126 inline void operator +=(const T& item);
00128
00129
00130 private:
00131
00132 T* m_items;
00133 int m_num_items;
00134 int m_items_allocated;
00135 bool m_items_allocated_on_stack;
00136 int m_head_index;
00137 };
00138
00139
00140
00141 template <class T>
00142 class List_t
00143
00144 : public Array_t<T*>
00146 {
00147
00148 public:
00149
00150 inline List_t();
00152
00153 inline List_t( T** stack_buffer, int stack_buffer_num_items_allcoated );
00157
00158 T* RemoveItem(T* item);
00160
00161 int IndexOfItem(T* item);
00164
00165 inline T& operator [](int index) const;
00168
00169 inline void operator -=(T* item);
00171 };
00172
00173
00174
00175 template <class T>
00176 class OwnedList_t
00177
00178 : public List_t<T>
00180 {
00181
00182 public:
00183
00184 inline OwnedList_t();
00186
00187 inline OwnedList_t( T** stack_buffer, int stack_buffer_num_items_allcoated );
00191
00192 ~OwnedList_t();
00194 };
00195
00196
00197
00198 template <class T>
00199 class LinkedList_t
00200
00202 {
00203
00204 public:
00205
00206 inline LinkedList_t();
00208
00209 T* AddHead(T* item);
00211
00212 T* AddTail(T* item);
00214
00215 T* AddItemBefore( T* new_item, T* after_item );
00217
00218 T* AddItemAfter( T* before_item, T* new_item );
00220
00221 T* RemoveHead();
00223
00224 T* RemoveTail();
00226
00227 T* RemoveItem(T* item);
00229
00230 inline int CountItems() const;
00232
00233 inline T* Head() const;
00236
00237 inline T* Tail() const;
00240
00241 inline void operator +=(T* item);
00243
00244 inline void operator -=(T* item);
00246
00247 void SortSmallOrSlow();
00253
00254
00255 private:
00256
00257 T* m_head;
00258 T* m_tail;
00259 int m_num_items;
00260 };
00261
00262
00263
00264 template <class T>
00265 class LinkedListNode_t
00266
00273 {
00274
00275 protected:
00276
00277 inline LinkedListNode_t();
00279
00280
00281 public:
00282
00283 inline T* Next() const;
00286
00287 inline T* Prev() const;
00290
00291
00292 private:
00293
00294 LinkedListNode_t<T>* m_next;
00295 LinkedListNode_t<T>* m_prev;
00296
00297 friend class LinkedList_t<T>;
00298 };
00299
00300
00301
00302 template <class T>
00303 class OwnedLinkedList_t
00304
00305 : public LinkedList_t<T>
00311 {
00312
00313 public:
00314
00315 ~OwnedLinkedList_t();
00317 };
00318
00319
00320
00321 template <class T, class K>
00322 class BTree_t
00323
00346 {
00347
00348 public:
00349
00350 inline BTree_t();
00352
00353 T* FindItem(K key) const;
00357
00358 T* FindItemAtOrBefore(K key) const;
00363
00364 T* FindItemAtOrAfter(K key) const;
00369
00370 T* IsInTree(T* item) const;
00373
00374 void AddItem( T* new_item, bool balance_tree = true );
00378
00379 T* RemoveHead(bool balance_tree = true);
00381
00382 T* RemoveTail(bool balance_tree = true);
00384
00385 T* RemoveItem( T* item, bool balance_tree = true );
00387
00388 inline int CountItems() const;
00390
00391 T* Head() const;
00394
00395 T* Tail() const;
00398
00399 inline T* Root() const;
00403
00404 inline void operator +=(T* new_item);
00408
00409 inline void operator -=(T* item);
00411
00412
00413 private:
00414
00415 void UpdateChildNodeCountsAndBalanceToRoot( T* node, bool balance_tree );
00416
00417
00418
00419
00420 private:
00421
00422 T* m_root;
00423 int m_num_items;
00424 };
00425
00426
00427
00428 template <class T, class K>
00429 class BTreeNode_t
00430
00437 {
00438
00439 protected:
00440
00441 inline BTreeNode_t();
00443
00444
00445 public:
00446
00447 T* Next() const;
00451
00452 T* Prev() const;
00456
00457 inline bool operator < (const T& other);
00464
00465 inline bool operator <= (const T& other);
00468
00469 inline bool operator > (const T& other);
00472
00473 inline bool operator >= (const T& other);
00476
00477 inline bool operator == (const T& other);
00480
00481 inline bool operator < (K key);
00488
00489 inline bool operator <= (K key);
00492
00493 inline bool operator > (K key);
00496
00497 inline bool operator >= (K key);
00500
00501 inline bool operator == (K key);
00504
00505 inline int ChildNodesDepth() const;
00507
00508 void ValidateChildNodeDepth() const;
00510
00511
00512 private:
00513
00514 BTreeNode_t<T,K>* m_prev;
00515 BTreeNode_t<T,K>* m_parent;
00516 BTreeNode_t<T,K>* m_next;
00517 int m_child_nodes_depth;
00518
00519 friend class BTree_t<T,K>;
00520 };
00521
00522
00523
00524 template <class T, class K>
00525 class OwnedBTree_t
00526
00527 : public BTree_t<T,K>
00534 {
00535
00536 public:
00537
00538 ~OwnedBTree_t();
00540 };
00541
00542
00543
00544 template <class T, class K>
00545 class SortedList_t
00546
00574 {
00575
00576 public:
00577
00578 SortedList_t();
00580
00581 SortedList_t( T** stack_buffer, int stack_buffer_num_items_allcoated );
00585
00586 ~SortedList_t();
00590
00591 T* FindItem( K key, out int* index = NULL ) const;
00597
00598 T* FindItemAtOrBefore( K key, out int* index = NULL ) const;
00605
00606 T* FindItemAtOrAfter( K key, out int* index = NULL ) const;
00613
00614 T* IsInList(T* item) const;
00617
00618 void AddItem(T* new_item);
00625
00626 void AddHead(T* item);
00631
00632 void AddTail( T* item, bool will_sort_later = false );
00637
00638 void Sort();
00647
00648 T* RemoveItem(T* item);
00653
00654 T* RemoveHead();
00658
00659 inline T* RemoveTail();
00661
00662 T* RemoveItemAt(int index);
00667
00668 int IndexOfItem(T* item);
00671
00672 inline int CountItems() const;
00674
00675 inline T* Head() const;
00677
00678 inline T* Tail() const;
00680
00681 inline T* ItemAt(int index) const;
00684
00685 inline T& operator [](int index) const;
00688
00689 inline void operator +=(T* new_item);
00693
00694 inline void operator -=(T* item);
00699
00700
00701 private:
00702
00703 int FindItemIndex( K key, bool at_or_before, bool at_or_after ) const;
00704 int FindItemIndex( T* item, bool adding ) const;
00705 static bool MergeSort( T** from, T** to, int num_items );
00706
00707
00708
00709 private:
00710
00711 T** m_items;
00712 int m_num_items;
00713 int m_items_allocated;
00714 bool m_items_allocated_on_stack;
00715 };
00716
00717
00718
00719 template <class T, class K>
00720 class OwnedSortedList_t
00721
00722 : public SortedList_t<T,K>
00724 {
00725
00726 public:
00727
00728 inline OwnedSortedList_t();
00730
00731 inline OwnedSortedList_t( T** stack_buffer, int stack_buffer_num_items_allcoated );
00735
00736 ~OwnedSortedList_t();
00738 };
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 template <class T>
00751 Array_t<T>::Array_t()
00752 {
00753 m_items = NULL;
00754 m_num_items = 0;
00755 m_items_allocated = 0;
00756 m_items_allocated_on_stack = false;
00757 m_head_index = 0;
00758 }
00759
00760
00761 template <class T>
00762 Array_t<T>::Array_t( T* stack_buffer, int stack_buffer_num_items_allcoated )
00763 {
00764 m_items = stack_buffer;
00765 m_num_items = 0;
00766 m_items_allocated = stack_buffer_num_items_allcoated;
00767 m_items_allocated_on_stack = true;
00768 m_head_index = 0;
00769 }
00770
00771
00772 template <class T>
00773 Array_t<T>::~Array_t()
00774 {
00775 if(m_items && !m_items_allocated_on_stack)
00776 delete[] m_items;
00777 }
00778
00779
00780 template <class T>
00781 void
00782 Array_t<T>::InstallStackBuffer( T* stack_buffer, int stack_buffer_num_items_allcoated )
00783 {
00784 assert(m_items == NULL);
00785 m_items = stack_buffer;
00786 m_items_allocated = stack_buffer_num_items_allcoated;
00787 m_items_allocated_on_stack = true;
00788 }
00789
00790
00791 template <class T>
00792 T
00793 Array_t<T>::AddHead(const T& item)
00794 {
00795 assert(m_head_index < m_items_allocated || !m_items_allocated);
00796 assert(m_items_allocated >= m_num_items);
00797
00798 if(m_num_items == m_items_allocated)
00799 {
00800
00801 int new_items_allocated = m_items_allocated;
00802 if(new_items_allocated == 0)
00803 new_items_allocated = 16;
00804 else if(new_items_allocated < 128)
00805 new_items_allocated *= 2;
00806 else
00807 new_items_allocated += new_items_allocated / 2;
00808
00809
00810 T* new_list = new T[new_items_allocated];
00811
00812
00813 new_list[0] = item;
00814
00815
00816 int copy_items_from_head_index = m_num_items;
00817 if(copy_items_from_head_index > m_items_allocated - m_head_index)
00818 copy_items_from_head_index = m_items_allocated - m_head_index;
00819 memcpy( new_list+1, m_items+m_head_index, copy_items_from_head_index * sizeof(T) );
00820 memcpy( new_list+1+copy_items_from_head_index,
00821 m_items,
00822 (m_num_items - copy_items_from_head_index) * sizeof(T) );
00823
00824
00825 m_num_items++;
00826
00827
00828 if(m_items && !m_items_allocated_on_stack)
00829 delete[] m_items;
00830 m_items = new_list;
00831 m_items_allocated = new_items_allocated;
00832 m_items_allocated_on_stack = false;
00833 m_head_index = 0;
00834 return item;
00835 }
00836
00837 m_head_index--;
00838 if(m_head_index <= -1)
00839 {
00840 assert(m_head_index == -1);
00841 m_head_index = m_items_allocated-1;
00842 }
00843 m_items[m_head_index] = item;
00844 m_num_items++;
00845 return item;
00846 }
00847
00848
00849 template <class T>
00850 T
00851 Array_t<T>::AddTail(const T& item)
00852 {
00853 assert(m_head_index < m_items_allocated || !m_items_allocated);
00854 assert(m_items_allocated >= m_num_items);
00855
00856 if(m_num_items == m_items_allocated)
00857 {
00858
00859 int new_items_allocated = m_items_allocated;
00860 if(new_items_allocated == 0)
00861 new_items_allocated = 16;
00862 else if(new_items_allocated < 128)
00863 new_items_allocated *= 2;
00864 else
00865 new_items_allocated += new_items_allocated / 2;
00866
00867
00868 T* new_list = new T[new_items_allocated];
00869
00870
00871 int copy_items_from_head_index = m_num_items;
00872 if(copy_items_from_head_index > m_items_allocated - m_head_index)
00873 copy_items_from_head_index = m_items_allocated - m_head_index;
00874 memcpy( new_list, m_items+m_head_index, copy_items_from_head_index * sizeof(T) );
00875 memcpy( new_list+copy_items_from_head_index,
00876 m_items,
00877 (m_num_items - copy_items_from_head_index) * sizeof(T) );
00878
00879
00880 new_list[m_num_items] = item;
00881
00882
00883 m_num_items++;
00884
00885
00886 if(m_items && !m_items_allocated_on_stack)
00887 delete[] m_items;
00888 m_items = new_list;
00889 m_items_allocated = new_items_allocated;
00890 m_items_allocated_on_stack = false;
00891 m_head_index = 0;
00892 return item;
00893 }
00894
00895 int add_index;
00896 #if TARGET_CPU_FAST_INTEGER_MOD
00897 add_index = (m_head_index + m_num_items) % m_items_allocated;
00898 #else
00899 add_index = m_head_index + m_num_items;
00900 if(add_index >= m_items_allocated)
00901 add_index -= m_items_allocated;
00902 #endif
00903
00904 m_items[add_index] = item;
00905 m_num_items++;
00906 return item;
00907 }
00908
00909
00910 template <class T>
00911 T
00912 Array_t<T>::AddItemAt( const T& item, int index )
00913 {
00914 int head_segment_count;
00915 int tail_segment_count;
00916
00917 if(index == -1)
00918 index = m_num_items;
00919 assert(m_head_index < m_items_allocated || !m_items_allocated);
00920 assert(m_items_allocated >= m_num_items);
00921 assert(index >= 0 && index <= m_num_items);
00922
00923 if(m_num_items == m_items_allocated)
00924 {
00925
00926 int new_items_allocated = m_items_allocated;
00927 if(new_items_allocated == 0)
00928 new_items_allocated = 16;
00929 else if(new_items_allocated < 128)
00930 new_items_allocated *= 2;
00931 else
00932 new_items_allocated += new_items_allocated / 2;
00933
00934
00935 T* new_list = new T[new_items_allocated];
00936
00937
00938 head_segment_count = m_items_allocated - m_head_index;
00939 tail_segment_count = m_num_items - head_segment_count;
00940 if(index <= head_segment_count)
00941 {
00942
00943
00944 memcpy( new_list, m_items+m_head_index, index * sizeof(T) );
00945 new_list[index] = item;
00946 memcpy( new_list+index+1,
00947 m_items+m_head_index+index,
00948 (head_segment_count-index) * sizeof(T) );
00949 memcpy( new_list+head_segment_count+1, m_items, tail_segment_count * sizeof(T) );
00950 }
00951 else
00952 {
00953
00954
00955 memcpy( new_list, m_items+m_head_index, head_segment_count * sizeof(T) );
00956 memcpy( new_list+head_segment_count, m_items, (index-head_segment_count) * sizeof(T) );
00957 new_list[index] = item;
00958 memcpy( new_list+index+1,
00959 m_items+index-head_segment_count,
00960 (m_num_items-index) * sizeof(T) );
00961 }
00962
00963
00964 m_num_items++;
00965
00966
00967 if(m_items && !m_items_allocated_on_stack)
00968 delete[] m_items;
00969 m_items = new_list;
00970 m_items_allocated = new_items_allocated;
00971 m_items_allocated_on_stack = false;
00972 m_head_index = 0;
00973 return item;
00974 }
00975
00976 if(index == 0)
00977 return AddHead(item);
00978 if(index == m_num_items)
00979 return AddTail(item);
00980
00981 int array_index;
00982
00983
00984
00985 if(index < m_num_items - index)
00986 {
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 #if TARGET_CPU_FAST_INTEGER_MOD
01006 array_index = (m_head_index + index - 1) % m_items_allocated;
01007 #else
01008 array_index = m_head_index + index - 1;
01009 if(array_index >= m_items_allocated)
01010 array_index -= m_items_allocated;
01011 #endif
01012
01013 if(m_head_index == 0)
01014 {
01015
01016
01017
01018
01019
01020 m_head_index = m_items_allocated-1;
01021 m_items[m_head_index] = m_items[0];
01022 memmove( m_items, m_items+1, array_index * sizeof(T) );
01023 m_items[array_index] = item;
01024 m_num_items++;
01025 return item;
01026 }
01027
01028 else if(m_head_index <= array_index)
01029 {
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071 memmove( m_items+m_head_index-1, m_items+m_head_index, index * sizeof(T) );
01072 m_head_index--;
01073 m_items[array_index] = item;
01074 m_num_items++;
01075 return item;
01076 }
01077
01078 else
01079 {
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093 memmove( m_items+m_head_index-1,
01094 m_items+m_head_index,
01095 (m_items_allocated-m_head_index) * sizeof(T) );
01096 m_head_index--;
01097 m_items[m_items_allocated-1] = m_items[0];
01098 memmove( m_items,
01099 m_items+1,
01100 array_index * sizeof(T) );
01101 m_items[array_index] = item;
01102 m_num_items++;
01103 return item;
01104 }
01105 }
01106 else
01107 {
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 #if TARGET_CPU_FAST_INTEGER_MOD
01127 array_index = (m_head_index + index) % m_items_allocated;
01128 #else
01129 array_index = m_head_index + index;
01130 if(array_index >= m_items_allocated)
01131 array_index -= m_items_allocated;
01132 #endif
01133
01134 if(m_head_index + m_num_items < m_items_allocated)
01135 {
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 memmove( m_items+array_index+1,
01154 m_items+array_index,
01155 (m_num_items-index) * sizeof(T) );
01156 m_items[array_index] = item;
01157 m_num_items++;
01158 return item;
01159 }
01160
01161 else if(array_index > m_head_index)
01162 {
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 memmove( m_items+1,
01189 m_items,
01190 (m_head_index + m_num_items - m_items_allocated) * sizeof(T) );
01191 m_items[0] = m_items[m_items_allocated-1];
01192 memmove( m_items+array_index+1,
01193 m_items+array_index,
01194 ( m_items_allocated - (array_index+1) ) * sizeof(T) );
01195 m_items[array_index] = item;
01196 m_num_items++;
01197 return item;
01198 }
01199
01200 else
01201 {
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219 memmove( m_items+array_index+1,
01220 m_items+array_index,
01221 (m_num_items-index) * sizeof(T) );
01222 m_items[array_index] = item;
01223 m_num_items++;
01224 return item;
01225 }
01226 }
01227 }
01228
01229
01230 template <class T>
01231 T
01232 Array_t<T>::RemoveHead()
01233 {
01234 assert(m_num_items);
01235 assert(m_head_index >= 0 && m_head_index < m_items_allocated);
01236
01237 T* item = &m_items[m_head_index];
01238 m_num_items--;
01239 #if TARGET_CPU_FAST_INTEGER_MOD
01240 m_head_index = (m_head_index + 1) % m_items_allocated;
01241 #else
01242 m_head_index++;
01243 if(m_head_index == m_items_allocated)
01244 m_head_index = 0;
01245 #endif
01246
01247 return *item;
01248 }
01249
01250
01251 template <class T>
01252 T
01253 Array_t<T>::RemoveTail()
01254 {
01255 assert(m_num_items);
01256 assert(m_head_index >= 0 && m_head_index < m_items_allocated);
01257
01258 m_num_items--;
01259 int tail_index;
01260 #if TARGET_CPU_FAST_INTEGER_MOD
01261 tail_index = (m_head_index + m_num_items) % m_items_allocated;
01262 #else
01263 tail_index = m_head_index + m_num_items;
01264 if(tail_index >= m_items_allocated)
01265 tail_index -= m_items_allocated;
01266 #endif
01267 return m_items[tail_index];
01268 }
01269
01270
01271 template <class T>
01272 T
01273 Array_t<T>::RemoveItemAt(int index)
01274 {
01275 assert(index >= 0 && index < m_num_items);
01276 assert(m_head_index >= 0 && m_head_index < m_items_allocated);
01277
01278 int array_index;
01279 #if TARGET_CPU_FAST_INTEGER_MOD
01280 array_index = (m_head_index + index) % m_items_allocated;
01281 #else
01282 array_index = m_head_index + index;
01283 if(array_index >= m_items_allocated)
01284 array_index -= m_items_allocated;
01285 #endif
01286 T item = m_items[array_index];
01287
01288
01289
01290
01291 if (index < m_num_items - (index+1) )
01292 {
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307 if(m_head_index <= array_index)
01308 {
01309
01310
01311
01312
01313
01314
01315 memmove( m_items+m_head_index+1, m_items+m_head_index, index * sizeof(T) );
01316 #if TARGET_CPU_FAST_INTEGER_MOD
01317 m_head_index = (m_head_index + 1) % m_items_allocated;
01318 #else
01319 m_head_index++;
01320 if(m_head_index == m_items_allocated)
01321 m_head_index = 0;
01322 #endif
01323 m_num_items--;
01324 return item;
01325 }
01326
01327 else
01328 {
01329
01330
01331
01332
01333 memmove( m_items+1, m_items, array_index * sizeof(T) );
01334 m_items[0] = m_items[m_items_allocated-1];
01335 memmove( m_items+m_head_index+1,
01336 m_items+m_head_index,
01337 ( m_items_allocated-(m_head_index+1) ) * sizeof(T) );
01338 #if TARGET_CPU_FAST_INTEGER_MOD
01339 m_head_index = (m_head_index + 1) % m_items_allocated;
01340 #else
01341 m_head_index++;
01342 if(m_head_index == m_items_allocated)
01343 m_head_index = 0;
01344 #endif
01345 m_num_items--;
01346 return item;
01347 }
01348 }
01349 else
01350 {
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 int tail_array_index;
01366 #if TARGET_CPU_FAST_INTEGER_MOD
01367 tail_array_index = (m_head_index + m_num_items - 1) % m_items_allocated;
01368 #else
01369 tail_array_index = m_head_index + m_num_items - 1;
01370 if(tail_array_index >= m_items_allocated)
01371 tail_array_index -= m_items_allocated;
01372 #endif
01373 if(tail_array_index >= array_index)
01374 {
01375
01376
01377
01378
01379
01380
01381 memmove( m_items+array_index,
01382 m_items+array_index+1,
01383 ( m_num_items - (index+1) ) * sizeof(T) );
01384 m_num_items--;
01385 return item;
01386 }
01387
01388 else
01389 {
01390
01391
01392
01393
01394 memmove( m_items+array_index,
01395 m_items+array_index+1,
01396 ( m_items_allocated - (array_index+1) ) * sizeof(T) );
01397 m_items[m_items_allocated-1] = m_items[0];
01398 memmove( m_items, m_items+1, tail_array_index * sizeof(T) );
01399 m_num_items--;
01400 return item;
01401 }
01402 }
01403 }
01404
01405
01406 template <class T>
01407 inline int
01408 Array_t<T>::CountItems() const
01409 {
01410 return m_num_items;
01411 }
01412
01413
01414 template <class T>
01415 inline int
01416 Array_t<T>::AllocatedItems() const
01417 {
01418 return m_items_allocated;
01419 }
01420
01421
01422 template <class T>
01423 inline void
01424 Array_t<T>::SetNumValidItems(int count)
01425 {
01426 assert(count <= m_num_items);
01427 m_num_items = count;
01428 }
01429
01430
01431 template <class T>
01432 void
01433 Array_t<T>::GrowIfNeeded( int min_allocated_items, bool expect_more_growth )
01434 {
01435 if(m_items_allocated >= min_allocated_items)
01436 return;
01437
01438
01439 int new_items_allocated = min_allocated_items;
01440 if(expect_more_growth)
01441 {
01442 if(new_items_allocated == 0)
01443 new_items_allocated = 16;
01444 else if(new_items_allocated < 128)
01445 new_items_allocated *= 2;
01446 else
01447 new_items_allocated += new_items_allocated / 2;
01448 }
01449
01450
01451 T* new_list = new T[new_items_allocated];
01452
01453
01454 int copy_items_from_head_index = m_num_items;
01455 if(copy_items_from_head_index > m_items_allocated - m_head_index)
01456 copy_items_from_head_index = m_items_allocated - m_head_index;
01457 memcpy( new_list, m_items+m_head_index, copy_items_from_head_index * sizeof(T) );
01458 memcpy( new_list+copy_items_from_head_index,
01459 m_items,
01460 (m_num_items - copy_items_from_head_index) * sizeof(T) );
01461
01462
01463 if(m_items && !m_items_allocated_on_stack)
01464 delete[] m_items;
01465 m_items = new_list;
01466 m_items_allocated = new_items_allocated;
01467 m_items_allocated_on_stack = false;
01468 m_head_index = 0;
01469 }
01470
01471
01472
01473 template <class T>
01474 inline T
01475 Array_t<T>::Head() const
01476 {
01477 if(m_num_items == 0)
01478 return NULL;
01479 return m_items[m_head_index];
01480 }
01481
01482
01483 template <class T>
01484 inline T
01485 Array_t<T>::Tail() const
01486 {
01487 if(m_num_items == 0)
01488 return NULL;
01489 int tail_array_index;
01490 #if TARGET_CPU_FAST_INTEGER_MOD
01491 tail_array_index = (m_head_index + m_num_items - 1) % m_items_allocated;
01492 #else
01493 tail_array_index = m_head_index + m_num_items - 1;
01494 if(tail_array_index >= m_items_allocated)
01495 tail_array_index -= m_items_allocated;
01496 #endif
01497 return m_items[tail_array_index];
01498 }
01499
01500
01501 template <class T>
01502 inline T
01503 Array_t<T>::ItemAt(int index) const
01504 {
01505 assert(index >= 0 && index < m_num_items);
01506 int array_index;
01507 #if TARGET_CPU_FAST_INTEGER_MOD
01508 array_index = (m_head_index + index) % m_items_allocated;
01509 #else
01510 array_index = m_head_index + index;
01511 if(array_index >= m_items_allocated)
01512 array_index -= m_items_allocated;
01513 #endif
01514 return m_items[array_index];
01515 }
01516
01517
01518 template <class T>
01519 inline T&
01520 Array_t<T>::operator [](int index) const
01521 {
01522 assert(index >= 0 && index <= m_num_items);
01523 if(index == m_num_items)
01524 const_cast<Array_t<T>*>(this)->GrowIfNeeded( m_num_items+1, true );
01525
01526 int array_index;
01527 #if TARGET_CPU_FAST_INTEGER_MOD
01528 array_index = (m_head_index + index) % m_items_allocated;
01529 #else
01530 array_index = m_head_index + index;
01531 if(array_index >= m_items_allocated)
01532 array_index -= m_items_allocated;
01533 #endif
01534 return m_items[array_index];
01535 }
01536
01537
01538 template <class T>
01539 inline void
01540 Array_t<T>::operator +=(const T& item)
01541 {
01542 AddTail(item);
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 template <class T>
01556 inline
01557 List_t<T>::List_t()
01558 { }
01559
01560
01561 template <class T>
01562 inline
01563 List_t<T>::List_t( T** stack_buffer, int stack_buffer_num_items_allcoated )
01564 : Array_t<T*>( stack_buffer, stack_buffer_num_items_allcoated )
01565 { }
01566
01567
01568 template <class T>
01569 T*
01570 List_t<T>::RemoveItem(T* item)
01571 {
01572 for(int i = 0; i < Array_t<T*>::CountItems(); i++)
01573 {
01574 if(Array_t<T*>::ItemAt(i) == item)
01575 {
01576 Array_t<T*>::RemoveItemAt(i);
01577 return item;
01578 }
01579 }
01580 debug_error("The specified item was not found");
01581 return NULL;
01582 }
01583
01584
01585 template <class T>
01586 int
01587 List_t<T>::IndexOfItem(T* item)
01588 {
01589 for(int i = 0; i < Array_t<T*>::CountItems(); i++)
01590 if(Array_t<T*>::ItemAt(i) == item)
01591 return i;
01592 return -1;
01593 }
01594
01595
01596 template <class T>
01597 inline T&
01598 List_t<T>::operator [](int index) const
01599 {
01600 return *Array_t<T*>::ItemAt(index);
01601 }
01602
01603
01604 template <class T>
01605 inline void
01606 List_t<T>::operator -=(T* item)
01607 {
01608 RemoveItem(item);
01609 }
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621 template <class T>
01622 inline
01623 OwnedList_t<T>::OwnedList_t()
01624 { }
01625
01626
01627 template <class T>
01628 inline
01629 OwnedList_t<T>::OwnedList_t( T** stack_buffer, int stack_buffer_num_items_allcoated )
01630 : List_t<T*>( stack_buffer, stack_buffer_num_items_allcoated )
01631 { }
01632
01633
01634 template <class T>
01635 OwnedList_t<T>::~OwnedList_t()
01636 {
01637 for(int i=0; i<List_t<T>::CountItems(); i++)
01638 delete List_t<T>::ItemAt(i);
01639 }
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651 template <class T>
01652 inline
01653 LinkedList_t<T>::LinkedList_t()
01654 {
01655 m_head = NULL;
01656 m_tail = NULL;
01657 m_num_items = 0;
01658 }
01659
01660
01661 template <class T>
01662 T*
01663 LinkedList_t<T>::AddHead(T* item)
01664 {
01665 assert(!item->m_next);
01666 assert(!item->m_prev);
01667 if(m_num_items == 0)
01668 {
01669 m_head = item;
01670 m_tail = item;
01671 m_num_items = 1;
01672 return item;
01673 }
01674 assert(!static_cast<LinkedListNode_t<T>*>(m_head)->m_prev);
01675 assert(static_cast<LinkedListNode_t<T>*>(m_head) != item);
01676 m_head->m_prev = item;
01677 item->m_next = m_head;
01678 m_head = item;
01679 m_num_items++;
01680 return item;
01681 }
01682
01683
01684 template <class T>
01685 T*
01686 LinkedList_t<T>::AddTail(T* item)
01687 {
01688 assert(!static_cast<LinkedListNode_t<T>*>(item)->m_next);
01689 assert(!static_cast<LinkedListNode_t<T>*>(item)->m_prev);
01690 if(m_num_items == 0)
01691 {
01692 m_head = item;
01693 m_tail = item;
01694 m_num_items = 1;
01695 return item;
01696 }
01697 assert(!static_cast<LinkedListNode_t<T>*>(m_tail)->m_next);
01698 assert(static_cast<LinkedListNode_t<T>*>(m_tail) != item);
01699 static_cast<LinkedListNode_t<T>*>(m_tail)->m_next = item;
01700 static_cast<LinkedListNode_t<T>*>(item)->m_prev = m_tail;
01701 m_tail = item;
01702 m_num_items++;
01703 return item;
01704 }
01705
01706
01707 template <class T>
01708 T*
01709 LinkedList_t<T>::AddItemBefore( T* new_item, T* after_item )
01710 {
01711 assert(new_item && after_item);
01712 if(after_item == m_head)
01713 {
01714 AddHead(new_item);
01715 return new_item;
01716 }
01717 assert(!static_cast<LinkedListNode_t<T>*>(new_item)->m_next);
01718 assert(!static_cast<LinkedListNode_t<T>*>(new_item)->m_prev);
01719 assert(m_num_items);
01720 static_cast<LinkedListNode_t<T>*>(new_item)->m_prev =
01721 static_cast<LinkedListNode_t<T>*>(after_item)->m_prev;
01722 static_cast<LinkedListNode_t<T>*>(new_item)->m_next = after_item;
01723 static_cast<LinkedListNode_t<T>*>(new_item)->m_prev->m_next = new_item;
01724 after_item->m_prev = new_item;
01725 m_num_items++;
01726 return new_item;
01727 }
01728
01729
01730 template <class T>
01731 T*
01732 LinkedList_t<T>::AddItemAfter( T* before_item, T* new_item )
01733 {
01734 assert(before_item && new_item);
01735 if(before_item == m_tail)
01736 {
01737 AddTail(new_item);
01738 return new_item;
01739 }
01740 assert(!new_item->m_next);
01741 assert(!new_item->m_prev);
01742 assert(m_num_items);
01743 new_item->m_prev = before_item;
01744 new_item->m_next = before_item->m_next;
01745 before_item->m_next = new_item;
01746 new_item->m_next->m_prev = new_item;
01747 m_num_items++;
01748 return new_item;
01749 }
01750
01751
01752 template <class T>
01753 T*
01754 LinkedList_t<T>::RemoveHead()
01755 {
01756 assert(m_num_items && m_head);
01757 LinkedListNode_t<T>* item = m_head;
01758 assert(!item->m_prev);
01759 if(m_num_items == 1)
01760 {
01761 assert(m_head == m_tail);
01762 assert(!item->m_next);
01763 assert(!item->m_prev);
01764 m_head = NULL;
01765 m_tail = NULL;
01766 m_num_items = 0;
01767 return static_cast<T*>(item);
01768 }
01769 m_head = static_cast<T*>(item->m_next);
01770 static_cast<LinkedListNode_t<T>*>(m_head)->m_prev = NULL;
01771 item->m_next = NULL;
01772 m_num_items--;
01773 return static_cast<T*>(item);
01774 }
01775
01776
01777 template <class T>
01778 T*
01779 LinkedList_t<T>::RemoveTail()
01780 {
01781 assert(m_num_items && m_tail);
01782 LinkedListNode_t<T>* item = m_tail;
01783 assert(!item->m_next);
01784 if(m_num_items == 1)
01785 {
01786 assert(m_head == m_tail);
01787 assert(!item->m_prev);
01788 m_head = NULL;
01789 m_tail = NULL;
01790 m_num_items = 0;
01791 return static_cast<T*>(item);
01792 }
01793 m_tail = static_cast<T*>(item->m_prev);
01794 static_cast<LinkedListNode_t<T>*>(m_tail)->m_next = NULL;
01795 item->m_prev = NULL;
01796 m_num_items--;
01797 return static_cast<T*>(item);
01798 }
01799
01800
01801 template <class T>
01802 T*
01803 LinkedList_t<T>::RemoveItem(T* item)
01804 {
01805 assert(m_num_items);
01806 if(item == m_head)
01807 return RemoveHead();
01808 if(item == m_tail)
01809 return RemoveTail();
01810 assert(m_head && (m_head != m_tail) && m_tail);
01811 assert( static_cast<LinkedListNode_t<T>*>(item)->m_prev
01812 && static_cast<LinkedListNode_t<T>*>(item)->m_next);
01813 #if DEBUG
01814 LinkedListNode_t<T>* check_item_fwd = static_cast<LinkedListNode_t<T>*>(m_head)->m_next;
01815 LinkedListNode_t<T>* check_item_back = static_cast<LinkedListNode_t<T>*>(m_tail)->m_prev;
01816 while(check_item_fwd)
01817 {
01818 assert(check_item_back);
01819 if(check_item_fwd == item)
01820 break;
01821 if(check_item_fwd == check_item_back)
01822 break;
01823 if(check_item_back == item)
01824 break;
01825
01826 check_item_fwd = check_item_fwd->m_next;
01827 if(check_item_fwd == check_item_back)
01828 break;
01829 check_item_back = check_item_back->m_prev;
01830 }
01831
01832 assert(check_item_fwd == item || check_item_back == item);
01833
01834 #endif
01835 static_cast<LinkedListNode_t<T>*>(static_cast<LinkedListNode_t<T>*>(item)->m_prev)->m_next =
01836 static_cast<LinkedListNode_t<T>*>(item)->m_next;
01837 static_cast<LinkedListNode_t<T>*>(static_cast<LinkedListNode_t<T>*>(item)->m_next)->m_prev =
01838 static_cast<LinkedListNode_t<T>*>(item)->m_prev;
01839 static_cast<LinkedListNode_t<T>*>(item)->m_prev = NULL;
01840 static_cast<LinkedListNode_t<T>*>(item)->m_next = NULL;
01841 m_num_items--;
01842 return item;
01843 }
01844
01845
01846 template <class T>
01847 inline int
01848 LinkedList_t<T>::CountItems() const
01849 {
01850 return m_num_items;
01851 }
01852
01853
01854 template <class T>
01855 inline T*
01856 LinkedList_t<T>::Head() const
01857 {
01858 return m_head;
01859 }
01860
01861
01862 template <class T>
01863 inline T*
01864 LinkedList_t<T>::Tail() const
01865 {
01866 return m_tail;
01867 }
01868
01869
01870 template <class T>
01871 inline void
01872 LinkedList_t<T>::operator +=(T* item)
01873 {
01874 AddTail(item);
01875 }
01876
01877
01878 template <class T>
01879 inline void
01880 LinkedList_t<T>::operator -=(T* item)
01881 {
01882 RemoveItem(item);
01883 }
01884
01885
01886 template <class T>
01887 void
01888 LinkedList_t<T>::SortSmallOrSlow()
01889 {
01890 if(m_num_items < 2)
01891 return;
01892
01893 T* first_unsorted = static_cast<T*>(m_head->m_next);
01894 while(first_unsorted)
01895 {
01896 if( (*first_unsorted) < *( static_cast<T*>(first_unsorted->m_prev) ) )
01897 {
01898 T* reposition_item = first_unsorted;
01899 T* check_pos = static_cast<T*>(first_unsorted->m_prev->m_prev);
01900
01901 first_unsorted = static_cast<T*>(first_unsorted->m_next);
01902 RemoveItem(reposition_item);
01903
01904
01905 while(check_pos)
01906 {
01907 if( (*reposition_item) < (*check_pos) )
01908 check_pos = static_cast<T*>(check_pos->m_prev);
01909 else
01910 {
01911 AddItemAfter( check_pos, reposition_item );
01912 break;
01913 }
01914 }
01915 if(!check_pos)
01916 AddHead(reposition_item);
01917 }
01918 else
01919 first_unsorted = static_cast<T*>(first_unsorted->m_next);
01920 }
01921 }
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933 template <class T>
01934 inline
01935 LinkedListNode_t<T>::LinkedListNode_t()
01936 {
01937 m_next = NULL;
01938 m_prev = NULL;
01939 }
01940
01941
01942 template <class T>
01943 inline T*
01944 LinkedListNode_t<T>::Next() const
01945 {
01946 assert( (!m_next) || m_next->m_prev == this );
01947 return static_cast<T*>(m_next);
01948 }
01949
01950
01951 template <class T>
01952 inline T*
01953 LinkedListNode_t<T>::Prev() const
01954 {
01955 assert( (!m_prev) || m_prev->m_next == this );
01956 return static_cast<T*>(m_prev);
01957 }
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969 template <class T>
01970 OwnedLinkedList_t<T>::~OwnedLinkedList_t()
01971 {
01972 while( LinkedList_t<T>::Tail() )
01973 delete LinkedList_t<T>::RemoveTail();
01974 }
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986 template <class T, class K>
01987 inline
01988 BTree_t<T,K>::BTree_t()
01989 {
01990 m_root = NULL;
01991 m_num_items = 0;
01992 }
01993
01994
01995 template <class T, class K>
01996 T*
01997 BTree_t<T,K>::FindItem(K key) const
01998 {
01999 BTreeNode_t<T,K>* node = static_cast<BTreeNode_t<T,K>*>( const_cast<T*>(m_root) );
02000 for(;;)
02001 {
02002 if(!node)
02003 return NULL;
02004
02005 int compare = static_cast<T*>(node)->Compare(key);
02006
02007 if(compare < 0)
02008 node = node->m_next;
02009 else if(compare > 0)
02010 node = node->m_prev;
02011 else
02012 {
02013
02014 for(;;)
02015 {
02016 BTreeNode_t<T,K>* prev = node->Prev();
02017 if(prev && static_cast<T*>(prev)->Compare(key) == 0)
02018 node = prev;
02019 else
02020 return static_cast<T*>(node);
02021 }
02022 }
02023 }
02024 }
02025
02026
02027 template <class T, class K>
02028 T*
02029 BTree_t<T,K>::FindItemAtOrBefore(K key) const
02030 {
02031 BTreeNode_t<T,K>* node = m_root;
02032 BTreeNode_t<T,K>* last_before_node = NULL;
02033 for(;;)
02034 {
02035 if(!node)
02036 return static_cast<T*>(last_before_node);
02037
02038 int compare = static_cast<T*>(node)->Compare(key);
02039
02040 if(compare < 0)
02041 {
02042 last_before_node = node;
02043 node = node->m_next;
02044 }
02045 else if(compare > 0)
02046 node = node->m_prev;
02047 else
02048 {
02049
02050 for(;;)
02051 {
02052 BTreeNode_t<T,K>* next = node->Next();
02053 if(next && static_cast<T*>(next)->Compare(key) == 0)
02054 node = next;
02055 else
02056 return static_cast<T*>(node);
02057 }
02058 }
02059 }
02060 }
02061
02062
02063 template <class T, class K>
02064 T*
02065 BTree_t<T,K>::FindItemAtOrAfter(K key) const
02066 {
02067 BTreeNode_t<T,K>* node = m_root;
02068 BTreeNode_t<T,K>* last_after_node = NULL;
02069 for(;;)
02070 {
02071 if(!node)
02072 return static_cast<T*>(last_after_node);
02073
02074 int compare = static_cast<T*>(node)->Compare(key);
02075
02076 if(compare < 0)
02077 node = node->m_next;
02078 else if(compare > 0)
02079 {
02080 last_after_node = node;
02081 node = node->m_prev;
02082 }
02083 else
02084 {
02085
02086 for(;;)
02087 {
02088 BTreeNode_t<T,K>* prev = node->Prev();
02089 if(prev && static_cast<T*>(prev)->Compare(key) == 0)
02090 node = prev;
02091 else
02092 return static_cast<T*>(node);
02093 }
02094 }
02095 }
02096 }
02097
02098
02099 template <class T, class K>
02100 void
02101 BTree_t<T,K>::AddItem( T* new_item, bool balance_tree )
02102 {
02103 assert(new_item);
02104 assert( (static_cast<BTreeNode_t<T,K>*>(new_item) )->m_prev == NULL);
02105 assert( (static_cast<BTreeNode_t<T,K>*>(new_item) )->m_next == NULL);
02106 assert( (static_cast<BTreeNode_t<T,K>*>(new_item) )->m_parent == NULL);
02107 assert( (static_cast<BTreeNode_t<T,K>*>(new_item) )->m_child_nodes_depth == 0);
02108
02109 if(!m_root)
02110 {
02111 assert(m_num_items == 0);
02112 m_root = new_item;
02113 m_num_items = 1;
02114 return;
02115 }
02116
02117 BTreeNode_t<T,K>* node = m_root;
02118 m_num_items++;
02119 for(;;)
02120 {
02121 int compare = static_cast<T*>(node)->Compare( static_cast<K>(*new_item) );
02122
02123 if(compare <= 0)
02124 {
02125
02126 if(node->m_next)
02127 node = node->m_next;
02128 else
02129 {
02130 node->m_next = new_item;
02131 static_cast<BTreeNode_t<T,K>*>(new_item)->m_parent = node;
02132 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(node), balance_tree );
02133 return;
02134 }
02135 }
02136 else if(compare > 0)
02137 {
02138
02139 if(node->m_prev)
02140 node = node->m_prev;
02141 else
02142 {
02143 node->m_prev = new_item;
02144 static_cast<BTreeNode_t<T,K>*>(new_item)->m_parent = node;
02145 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(node), balance_tree );
02146 return;
02147 }
02148 }
02149 }
02150 }
02151
02152
02153 template <class T, class K>
02154 void
02155 BTree_t<T,K>::UpdateChildNodeCountsAndBalanceToRoot( T* a_node, bool balance_tree )
02156 {
02157 assert(a_node);
02158 BTreeNode_t<T,K>* node = a_node;
02159 BTreeNode_t<T,K>* parent;
02160 BTreeNode_t<T,K>* a;
02161 BTreeNode_t<T,K>* b;
02162 BTreeNode_t<T,K>* c;
02163 BTreeNode_t<T,K>* d;
02164
02165 while(node)
02166 {
02167 int left_child_nodes_depth = 0;
02168 int right_child_nodes_depth = 0;
02169 if(node->m_prev)
02170 left_child_nodes_depth = node->m_prev->m_child_nodes_depth + 1;
02171 if(node->m_next)
02172 right_child_nodes_depth = node->m_next->m_child_nodes_depth + 1;
02173
02174 if(!balance_tree)
02175 node->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02176 else if(left_child_nodes_depth >= right_child_nodes_depth + 2)
02177 {
02178
02179
02180
02181
02182
02183 parent = node->m_parent;
02184 b = node->m_prev;
02185 d = node->m_next;
02186 a = b->m_prev;
02187 c = b->m_next;
02188
02189
02190 if(c && c->m_child_nodes_depth == left_child_nodes_depth - 2)
02191 {
02192
02193 node->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02194 }
02195 else
02196 {
02197
02198 if(parent)
02199 {
02200 if(parent->m_prev == node)
02201 parent->m_prev = b;
02202 else
02203 {
02204 assert(parent->m_next == node);
02205 parent->m_next = b;
02206 }
02207 }
02208 else
02209 m_root = static_cast<T*>(b);
02210 b->m_parent = parent;
02211 b->m_prev = a;
02212 if(a)
02213 a->m_parent = b;
02214 b->m_next = node;
02215 node->m_parent = b;
02216 node->m_prev = c;
02217 if(c)
02218 c->m_parent = node;
02219
02220
02221
02222
02223 left_child_nodes_depth = 0;
02224 if(c)
02225 left_child_nodes_depth = c->m_child_nodes_depth + 1;
02226 right_child_nodes_depth = 0;
02227 if(d)
02228 right_child_nodes_depth = d->m_child_nodes_depth + 1;
02229 node->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02230
02231
02232 left_child_nodes_depth = 0;
02233 if(a)
02234 left_child_nodes_depth = a->m_child_nodes_depth + 1;
02235 right_child_nodes_depth = node->m_child_nodes_depth + 1;
02236 b->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02237
02238
02239 if(parent)
02240 {
02241 left_child_nodes_depth = 0;
02242 if(parent->m_prev)
02243 left_child_nodes_depth = parent->m_prev->m_child_nodes_depth + 1;
02244 right_child_nodes_depth = 0;
02245 if(parent->m_next)
02246 right_child_nodes_depth = parent->m_next->m_child_nodes_depth + 1;
02247 parent->m_child_nodes_depth = max( left_child_nodes_depth,
02248 right_child_nodes_depth );
02249 }
02250 }
02251 }
02252 else if(right_child_nodes_depth >= left_child_nodes_depth + 2)
02253 {
02254
02255
02256
02257
02258
02259 parent = node->m_parent;
02260 a = node->m_prev;
02261 c = node->m_next;
02262 b = c->m_prev;
02263 d = c->m_next;
02264
02265
02266 if(b && b->m_child_nodes_depth == right_child_nodes_depth - 2)
02267 {
02268
02269 node->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02270 }
02271 else
02272 {
02273
02274 if(parent)
02275 {
02276 if(parent->m_prev == node)
02277 parent->m_prev = c;
02278 else
02279 {
02280 assert(parent->m_next == node);
02281 parent->m_next = c;
02282 }
02283 }
02284 else
02285 m_root = static_cast<T*>(c);
02286 c->m_parent = parent;
02287 c->m_prev = node;
02288 c->m_next = d;
02289 if(d)
02290 d->m_parent = c;
02291 node->m_parent = c;
02292 node->m_next = b;
02293 if(b)
02294 b->m_parent = node;
02295
02296
02297
02298
02299 left_child_nodes_depth = 0;
02300 if(a)
02301 left_child_nodes_depth = a->m_child_nodes_depth + 1;
02302 right_child_nodes_depth = 0;
02303 if(b)
02304 right_child_nodes_depth = b->m_child_nodes_depth + 1;
02305 node->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02306
02307
02308 left_child_nodes_depth = node->m_child_nodes_depth + 1;
02309 right_child_nodes_depth = 0;
02310 if(d)
02311 right_child_nodes_depth = d->m_child_nodes_depth + 1;
02312 c->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02313
02314
02315 if(parent)
02316 {
02317 left_child_nodes_depth = 0;
02318 if(parent->m_prev)
02319 left_child_nodes_depth = parent->m_prev->m_child_nodes_depth + 1;
02320 right_child_nodes_depth = 0;
02321 if(parent->m_next)
02322 right_child_nodes_depth = parent->m_next->m_child_nodes_depth + 1;
02323 parent->m_child_nodes_depth = max( left_child_nodes_depth,
02324 right_child_nodes_depth );
02325 }
02326 }
02327 }
02328 else
02329 node->m_child_nodes_depth = max( left_child_nodes_depth, right_child_nodes_depth );
02330
02331 node = node->m_parent;
02332 }
02333 }
02334
02335
02336 template <class T, class K>
02337 T*
02338 BTree_t<T,K>::RemoveHead(bool balance_tree)
02339 {
02340 assert(m_root);
02341
02342 BTreeNode_t<T,K>* node = m_root;
02343 while(node->m_prev)
02344 node = node->m_prev;
02345
02346 if(node->m_parent)
02347 {
02348 node->m_parent->m_prev = node->m_next;
02349 if(node->m_next)
02350 node->m_next->m_parent = node->m_parent;
02351 }
02352 else
02353 {
02354 m_root = static_cast<T*>(node->m_next);
02355 if(node->m_next)
02356 node->m_next->m_parent = NULL;
02357 }
02358
02359 if(node->m_parent)
02360 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(node->m_parent), balance_tree );
02361
02362 m_num_items--;
02363
02364 node->m_next = NULL;
02365 node->m_parent = NULL;
02366 node->m_child_nodes_depth = 0;
02367
02368 #if DEBUG
02369 if(m_num_items)
02370 assert(m_root);
02371 else
02372 assert(!m_root);
02373 #endif
02374
02375 return static_cast<T*>(node);
02376 }
02377
02378
02379 template <class T, class K>
02380 T*
02381 BTree_t<T,K>::RemoveTail(bool balance_tree)
02382 {
02383 assert(m_root);
02384
02385 BTreeNode_t<T,K>* node = m_root;
02386 while(node->m_next)
02387 node = node->m_next;
02388
02389 if(node->m_parent)
02390 {
02391 node->m_parent->m_next = node->m_prev;
02392 if(node->m_prev)
02393 node->m_prev->m_parent = node->m_parent;
02394 }
02395 else
02396 {
02397 m_root = static_cast<T*>(node->m_prev);
02398 if(node->m_prev)
02399 node->m_prev->m_parent = NULL;
02400 }
02401
02402 if(node->m_parent)
02403 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(node->m_parent), balance_tree );
02404
02405 m_num_items--;
02406
02407 node->m_prev = NULL;
02408 node->m_parent = NULL;
02409 node->m_child_nodes_depth = 0;
02410
02411 #if DEBUG
02412 if(m_num_items)
02413 assert(m_root);
02414 else
02415 assert(!m_root);
02416 #endif
02417
02418 return static_cast<T*>(node);
02419 }
02420
02421
02422 template <class T, class K>
02423 T*
02424 BTree_t<T,K>::IsInTree(T* item) const
02425 {
02426 BTreeNode_t<T,K>* check_root = item;
02427 while(check_root && check_root->m_parent)
02428 check_root = check_root->m_parent;
02429 if(check_root == m_root)
02430 return item;
02431 return NULL;
02432 }
02433
02434
02435 template <class T, class K>
02436 T*
02437 BTree_t<T,K>::RemoveItem( T* item, bool balance_tree )
02438 {
02439 BTreeNode_t<T,K>* prev = static_cast<BTreeNode_t<T,K>*>(item)->m_prev;
02440 BTreeNode_t<T,K>* next = static_cast<BTreeNode_t<T,K>*>(item)->m_next;
02441 BTreeNode_t<T,K>* parent = static_cast<BTreeNode_t<T,K>*>(item)->m_parent;
02442
02443 #if DEBUG
02444 BTreeNode_t<T,K>* check_root = item;
02445 while(check_root->m_parent)
02446 check_root = check_root->m_parent;
02447 assert(check_root == m_root);
02448 #endif
02449
02450 if(prev && !next)
02451 {
02452
02453
02454
02455 if(parent)
02456 {
02457 if(parent->m_prev == item)
02458 parent->m_prev = prev;
02459 else
02460 {
02461 assert(parent->m_next == item);
02462 parent->m_next = prev;
02463 }
02464 prev->m_parent = parent;
02465 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(parent), balance_tree );
02466 }
02467 else
02468 {
02469 m_root = static_cast<T*>(prev);
02470 prev->m_parent = NULL;
02471 }
02472 }
02473 else if(next && !prev)
02474 {
02475
02476
02477
02478 if(parent)
02479 {
02480 if(parent->m_prev == item)
02481 parent->m_prev = next;
02482 else
02483 {
02484 assert(parent->m_next == item);
02485 parent->m_next = next;
02486 }
02487 next->m_parent = parent;
02488 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(parent), balance_tree );
02489 }
02490 else
02491 {
02492 m_root = static_cast<T*>(next);
02493 next->m_parent = NULL;
02494 }
02495 }
02496 else if( !(prev || next) )
02497 {
02498
02499
02500
02501 if(parent)
02502 {
02503 if(parent->m_prev == item)
02504 parent->m_prev = NULL;
02505 else
02506 {
02507 assert(parent->m_next == item);
02508 parent->m_next = NULL;
02509 }
02510 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(parent), balance_tree );
02511 }
02512 else
02513 m_root = NULL;
02514 }
02515 else
02516 {
02517
02518
02519
02520
02521
02522
02523
02524 if(parent)
02525 {
02526 if(parent->m_prev == item)
02527 parent->m_prev = prev;
02528 else
02529 {
02530 assert(parent->m_next == item);
02531 parent->m_next = prev;
02532 }
02533 prev->m_parent = parent;
02534 }
02535 else
02536 {
02537 m_root = static_cast<T*>(prev);
02538 prev->m_parent = NULL;
02539 }
02540
02541
02542
02543 while(prev->m_next)
02544 prev = prev->m_next;
02545
02546 prev->m_next = next;
02547 next->m_parent = prev;
02548 UpdateChildNodeCountsAndBalanceToRoot( static_cast<T*>(prev), balance_tree );
02549 }
02550
02551 m_num_items--;
02552
02553 static_cast<BTreeNode_t<T,K>*>(item)->m_prev = NULL;
02554 static_cast<BTreeNode_t<T,K>*>(item)->m_parent = NULL;
02555 static_cast<BTreeNode_t<T,K>*>(item)->m_next = NULL;
02556 static_cast<BTreeNode_t<T,K>*>(item)->m_child_nodes_depth = 0;
02557
02558 #if DEBUG
02559 if(m_num_items)
02560 assert(m_root);
02561 else
02562 assert(!m_root);
02563 #endif
02564
02565 return item;
02566 }
02567
02568
02569 template <class T, class K>
02570 inline int
02571 BTree_t<T,K>::CountItems() const
02572 {
02573 return m_num_items;
02574 }
02575
02576
02577 template <class T, class K>
02578 T*
02579 BTree_t<T,K>::Head() const
02580 {
02581 BTreeNode_t<T,K>* node = m_root;
02582 if(!node)
02583 return NULL;
02584 while(node->m_prev)
02585 node = node->m_prev;
02586 return static_cast<T*>(node);
02587 }
02588
02589
02590 template <class T, class K>
02591 T*
02592 BTree_t<T,K>::Tail() const
02593 {
02594 BTreeNode_t<T,K>* node = m_root;
02595 if(!node)
02596 return NULL;
02597 while(node->m_next)
02598 node = node->m_next;
02599 return static_cast<T*>(node);
02600 }
02601
02602
02603 template <class T, class K>
02604 inline T*
02605 BTree_t<T,K>::Root() const
02606 {
02607 return m_root;
02608 }
02609
02610
02611 template <class T, class K>
02612 inline void
02613 BTree_t<T,K>::operator +=(T* item)
02614 {
02615 AddItem(item);
02616 }
02617
02618
02619 template <class T, class K>
02620 inline void
02621 BTree_t<T,K>::operator -=(T* item)
02622 {
02623 RemoveItem(item);
02624 }
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636 template <class T, class K>
02637 inline
02638 BTreeNode_t<T,K>::BTreeNode_t()
02639 {
02640 m_prev = NULL;
02641 m_next = NULL;
02642 m_parent = NULL;
02643 m_child_nodes_depth = 0;
02644 }
02645
02646
02647 template <class T, class K>
02648 T*
02649 BTreeNode_t<T,K>::Next() const
02650 {
02651 BTreeNode_t<T,K>* node;
02652 if(m_next)
02653 {
02654 node = m_next;
02655 while(node && node->m_prev)
02656 node = node->m_prev;
02657 return static_cast<T*>(node);
02658 }
02659
02660 node = const_cast<T*>( static_cast<const T*>(this) );
02661 for(;;)
02662 {
02663 if(!node->m_parent)
02664 return NULL;
02665 if(node->m_parent->m_prev == node)
02666 return static_cast<T*>(node->m_parent);
02667 node = node->m_parent;
02668 }
02669 }
02670
02671
02672 template <class T, class K>
02673 T*
02674 BTreeNode_t<T,K>::Prev() const
02675 {
02676 BTreeNode_t<T,K>* node;
02677 if(m_prev)
02678 {
02679 node = m_prev;
02680 while(node && node->m_next)
02681 node = node->m_next;
02682 return static_cast<T*>(node);
02683 }
02684
02685 node = const_cast<T*>( static_cast<const T*>(this) );
02686 for(;;)
02687 {
02688 if(!node->m_parent)
02689 return NULL;
02690 if(node->m_parent->m_next == node)
02691 return static_cast<T*>(node->m_parent);
02692 node = node->m_parent;
02693 }
02694 }
02695
02696
02697 template <class T, class K>
02698 inline bool
02699 BTreeNode_t<T,K>::operator < (const T& other)
02700 {
02701 return (static_cast<T*>(this)->Compare( static_cast<K>(other) ) < 0);
02702 }
02703
02704
02705 template <class T, class K>
02706 inline bool
02707 BTreeNode_t<T,K>::operator <= (const T& other)
02708 {
02709 return (static_cast<T*>(this)->Compare( static_cast<K>(other) ) <= 0);
02710 }
02711
02712
02713 template <class T, class K>
02714 inline bool
02715 BTreeNode_t<T,K>::operator > (const T& other)
02716 {
02717 return (static_cast<T*>(this)->Compare( static_cast<K>(other) ) > 0);
02718 }
02719
02720
02721 template <class T, class K>
02722 inline bool
02723 BTreeNode_t<T,K>::operator >= (const T& other)
02724 {
02725 return (static_cast<T*>(this)->Compare( static_cast<K>(other) ) >= 0);
02726 }
02727
02728
02729 template <class T, class K>
02730 inline bool
02731 BTreeNode_t<T,K>::operator == (const T& other)
02732 {
02733 return (static_cast<T*>(this)->Compare( static_cast<K>(other) ) == 0);
02734 }
02735
02736
02737 template <class T, class K>
02738 inline bool
02739 BTreeNode_t<T,K>::operator < (K key)
02740 {
02741 return (static_cast<T*>(this)->Compare(key) < 0);
02742 }
02743
02744
02745 template <class T, class K>
02746 inline bool
02747 BTreeNode_t<T,K>::operator <= (K key)
02748 {
02749 return (static_cast<T*>(this)->Compare(key) <= 0);
02750 }
02751
02752
02753 template <class T, class K>
02754 inline bool
02755 BTreeNode_t<T,K>::operator > (K key)
02756 {
02757 return (static_cast<T*>(this)->Compare(key) > 0);
02758 }
02759
02760
02761 template <class T, class K>
02762 inline bool
02763 BTreeNode_t<T,K>::operator >= (K key)
02764 {
02765 return (static_cast<T*>(this)->Compare(key) >= 0);
02766 }
02767
02768
02769 template <class T, class K>
02770 inline bool
02771 BTreeNode_t<T,K>::operator == (K key)
02772 {
02773 return (static_cast<T*>(this)->Compare(key) == 0);
02774 }
02775
02776
02777 template <class T, class K>
02778 inline int
02779 BTreeNode_t<T,K>::ChildNodesDepth() const
02780 {
02781 return m_child_nodes_depth;
02782 }
02783
02784
02785 template <class T, class K>
02786 void
02787 BTreeNode_t<T,K>::ValidateChildNodeDepth() const
02788 {
02789 assert( (m_next && m_child_nodes_depth == m_next->m_child_nodes_depth + 1)
02790 || (m_prev && m_child_nodes_depth == m_prev->m_child_nodes_depth + 1)
02791 || (m_child_nodes_depth == 0) );
02792 }
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804 template <class T, class K>
02805 OwnedBTree_t<T,K>::~OwnedBTree_t()
02806 {
02807 while( BTree_t<T,K>::CountItems() )
02808 delete BTree_t<T,K>::RemoveHead(false);
02809 }
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821 template <class T, class K>
02822 SortedList_t<T,K>::SortedList_t()
02823 {
02824 m_items = NULL;
02825 m_num_items = 0;
02826 m_items_allocated = 0;
02827 m_items_allocated_on_stack = false;
02828 }
02829
02830
02831 template <class T, class K>
02832 SortedList_t<T,K>::SortedList_t( T** stack_buffer, int stack_buffer_num_items_allcoated )
02833 {
02834 m_items = stack_buffer;
02835 m_num_items = 0;
02836 m_items_allocated = stack_buffer_num_items_allcoated;
02837 m_items_allocated_on_stack = true;
02838 }
02839
02840 template <class T, class K>
02841 SortedList_t<T,K>::~SortedList_t()
02842 {
02843 if(m_items && !m_items_allocated_on_stack)
02844 delete[] m_items;
02845 }
02846
02847
02848 template <class T, class K>
02849 int
02850 SortedList_t<T,K>::FindItemIndex( K key, bool at_or_before, bool at_or_after ) const
02851 {
02852 if(m_num_items == 0)
02853 return -1;
02854
02855 int first_unchecked = 0;
02856 int last_unchecked = m_num_items-1;
02857 for(;;)
02858 {
02859 int mid = (first_unchecked + last_unchecked) / 2;
02860 assert(mid >= 0 && mid < m_num_items);
02861 int result = m_items[mid]->Compare(key);
02862 if(result == 0)
02863 {
02864
02865 if(at_or_before)
02866 {
02867
02868 for(;;)
02869 {
02870 int next = mid+1;
02871 if(next < m_num_items && m_items[next]->Compare(key) == 0)
02872 mid = next;
02873 else
02874 return mid;
02875 }
02876 }
02877 else
02878 {
02879
02880 for(;;)
02881 {
02882 int prev = mid-1;
02883 if(prev >= 0 && m_items[prev]->Compare(key) == 0)
02884 mid = prev;
02885 else
02886 return mid;
02887 }
02888 }
02889 }
02890 else if(result < 0)
02891 {
02892
02893 first_unchecked = mid+1;
02894 if(last_unchecked < first_unchecked)
02895 {
02896
02897
02898 if(at_or_before)
02899 {
02900 #if DEBUG
02901 if(mid+1 < m_num_items)
02902 assert(m_items[mid+1]->Compare(key) > 0);
02903 #endif
02904 return mid;
02905 }
02906 else if(at_or_after)
02907 {
02908
02909 if(mid+1 == m_num_items)
02910 return -1;
02911 assert(m_items[mid+1]->Compare(key) > 0);
02912 return mid+1;
02913 }
02914 return -1;
02915 }
02916 }
02917 else
02918 {
02919
02920 last_unchecked = mid-1;
02921 if(last_unchecked < first_unchecked)
02922 {
02923
02924
02925 if(at_or_before)
02926 {
02927 if(mid-1 < 0)
02928 return -1;
02929 assert(m_items[mid-1]->Compare(key) < 0);
02930 return mid-1;
02931 }
02932 else if(at_or_after)
02933 {
02934 #if DEBUG
02935 if(mid-1 >= 0)
02936 assert(m_items[mid-1]->Compare(key) < 0);
02937 #endif
02938 return mid;
02939 }
02940 return -1;
02941 }
02942 }
02943 }
02944 }
02945
02946
02947 template <class T, class K>
02948 int
02949 SortedList_t<T,K>::FindItemIndex( T* item, bool adding ) const
02950 {
02951 if(m_num_items == 0)
02952 return -1;
02953
02954 int first_unchecked = 0;
02955 int last_unchecked = m_num_items-1;
02956 for(;;)
02957 {
02958 int mid = (first_unchecked + last_unchecked) / 2;
02959 assert(mid >= 0 && mid < m_num_items);
02960 int result = m_items[mid]->Compare( static_cast<K>(*item) );
02961 if(result == 0)
02962 {
02963
02964 if(adding)
02965 {
02966
02967 for(;;)
02968 {
02969 int next = mid+1;
02970 if( next < m_num_items
02971 && m_items[next]->Compare( static_cast<K>(*item) ) == 0 )
02972 {
02973 mid = next;
02974 }
02975 else
02976 return mid;
02977 }
02978 }
02979 else
02980 {
02981
02982 if(m_items[mid] == item)
02983 return mid;
02984
02985
02986 int sibling = mid-1;
02987 while(sibling >= 0)
02988 {
02989 if(m_items[sibling]->Compare( static_cast<K>(*item) ) != 0)
02990 break;
02991 if(m_items[sibling] == item)
02992 return sibling;
02993 sibling--;
02994 }
02995 sibling = mid+1;
02996 while(sibling < m_num_items)
02997 {
02998 if(m_items[sibling]->Compare( static_cast<K>(*item) ) != 0)
02999 break;
03000 if(m_items[sibling] == item)
03001 return sibling;
03002 sibling++;
03003 }
03004 return -1;
03005 }
03006 }
03007 else if(result < 0)
03008 {
03009
03010 first_unchecked = mid+1;
03011 if(last_unchecked < first_unchecked)
03012 {
03013
03014 if(adding)
03015 {
03016
03017 return mid;
03018 }
03019 return -1;
03020 }
03021 }
03022 else
03023 {
03024
03025 last_unchecked = mid-1;
03026 if(last_unchecked < first_unchecked)
03027 {
03028
03029 if(adding)
03030 {
03031 return mid-1;
03032 }
03033 return -1;
03034 }
03035 }
03036 }
03037 }
03038
03039
03040 template <class T, class K>
03041 T*
03042 SortedList_t<T,K>::FindItem( K key, out int* a_index ) const
03043 {
03044 int index = FindItemIndex( key, false, false );
03045 if(index == -1)
03046 {
03047 if(a_index)
03048 *a_index = -1;
03049 return NULL;
03050 }
03051 if(a_index)
03052 *a_index = index;
03053 return m_items[index];
03054 }
03055
03056
03057 template <class T, class K>
03058 T*
03059 SortedList_t<T,K>::FindItemAtOrBefore( K key, out int* a_index ) const
03060 {
03061 int index = FindItemIndex( key, true, false );
03062 if(index == -1)
03063 {
03064 if(a_index)
03065 *a_index = -1;
03066 return NULL;
03067 }
03068 if(a_index)
03069 *a_index = index;
03070 return m_items[index];
03071 }
03072
03073
03074 template <class T, class K>
03075 T*
03076 SortedList_t<T,K>::FindItemAtOrAfter( K key, out int* a_index ) const
03077 {
03078 int index = FindItemIndex( key, false, true );
03079 if(index == -1)
03080 {
03081 if(a_index)
03082 *a_index = -1;
03083 return NULL;
03084 }
03085 if(a_index)
03086 *a_index = index;
03087 return m_items[index];
03088 }
03089
03090
03091 template <class T, class K>
03092 void
03093 SortedList_t<T,K>::AddItem(T* item)
03094 {
03095 assert(item);
03096 if( m_num_items == 0
03097 || m_items[m_num_items-1]->Compare( static_cast<K>(*item) ) <= 0 )
03098 {
03099 AddTail(item);
03100 return;
03101 }
03102 int result = m_items[0]->Compare( static_cast<K>(*item) );
03103 if(result > 0)
03104 {
03105 AddHead(item);
03106 return;
03107 }
03108
03109
03110 int index = FindItemIndex( item, true ) + 1;
03111
03112 if(m_num_items < m_items_allocated)
03113 {
03114
03115 memmove( m_items+index+1, m_items+index, (m_num_items-index) * sizeof(T*) );
03116 m_items[index] = item;
03117 }
03118 else
03119 {
03120
03121 int new_items_allocated = m_items_allocated;
03122 if(new_items_allocated == 0)
03123 new_items_allocated = 16;
03124 else if(new_items_allocated < 128)
03125 new_items_allocated *= 2;
03126 else
03127 new_items_allocated += new_items_allocated / 2;
03128
03129
03130 T** new_list = new T*[new_items_allocated];
03131
03132
03133 memcpy( new_list, m_items, index * sizeof(T*) );
03134 new_list[index] = item;
03135 memcpy( new_list+index+1, m_items+index, (m_num_items-index) * sizeof(T*) );
03136 if(m_items && !m_items_allocated_on_stack)
03137 delete[] m_items;
03138 m_items = new_list;
03139 m_items_allocated = new_items_allocated;
03140 m_items_allocated_on_stack = false;
03141 }
03142 m_num_items++;
03143 }
03144
03145
03146 template <class T, class K>
03147 void
03148 SortedList_t<T,K>::AddHead(T* item)
03149 {
03150 if(m_num_items == 0)
03151 {
03152 if(!m_items)
03153 {
03154 assert(m_items_allocated == 0);
03155 m_items_allocated = 16;
03156 m_items = new T*[m_items_allocated];
03157 }
03158 m_items[0] = item;
03159 m_num_items = 1;
03160 return;
03161 }
03162
03163
03164 assert(item->Compare( static_cast<K>(*m_items[0]) ) <= 0);
03165
03166 if(m_num_items < m_items_allocated)
03167 {
03168
03169 memmove( m_items+1, m_items, (m_num_items) * sizeof(T*) );
03170 m_items[0] = item;
03171 }
03172 else
03173 {
03174
03175 int new_items_allocated = m_items_allocated;
03176 if(new_items_allocated == 0)
03177 new_items_allocated = 16;
03178 else if(new_items_allocated < 128)
03179 new_items_allocated *= 2;
03180 else
03181 new_items_allocated += new_items_allocated / 2;
03182
03183
03184 T** new_list = new T*[new_items_allocated];
03185 new_list[0] = item;
03186
03187
03188 memcpy( new_list+1, m_items, m_num_items * sizeof(T*) );
03189 if(m_items && !m_items_allocated_on_stack)
03190 delete[] m_items;
03191 m_items = new_list;
03192 m_items_allocated = new_items_allocated;
03193 m_items_allocated_on_stack = false;
03194 }
03195 m_num_items++;
03196 }
03197
03198
03199 template <class T, class K>
03200 void
03201 SortedList_t<T,K>::AddTail( T* item, bool will_sort_later )
03202 {
03203 if(m_num_items == 0)
03204 {
03205 if(!m_items)
03206 {
03207 assert(m_items_allocated == 0);
03208 m_items_allocated = 16;
03209 m_items = new T*[m_items_allocated];
03210 }
03211 m_items[0] = item;
03212 m_num_items = 1;
03213 return;
03214 }
03215
03216
03217 assert(will_sort_later || item->Compare( static_cast<K>(*m_items[m_num_items-1]) ) >= 0);
03218
03219 if(m_num_items == m_items_allocated)
03220 {
03221
03222 int new_items_allocated = m_items_allocated;
03223 if(new_items_allocated == 0)
03224 new_items_allocated = 16;
03225 else if(new_items_allocated < 128)
03226 new_items_allocated *= 2;
03227 else
03228 new_items_allocated += new_items_allocated / 2;
03229
03230
03231 T** new_list = new T*[new_items_allocated];
03232
03233
03234 memcpy( new_list, m_items, m_num_items * sizeof(T*) );
03235
03236 if(m_items && !m_items_allocated_on_stack)
03237 delete[] m_items;
03238 m_items = new_list;
03239 m_items_allocated = new_items_allocated;
03240 m_items_allocated_on_stack = false;
03241 }
03242 m_items[m_num_items] = item;
03243 m_num_items++;
03244 }
03245
03246
03247 template <class T, class K>
03248 void
03249 SortedList_t<T,K>::Sort()
03250 {
03251 if(m_num_items < 2)
03252 return;
03253
03254 T** alt_buf;
03255 T* stack_buf[c_max_stack_buf/sizeof(T*)];
03256 if( m_num_items > static_cast<int>( c_max_stack_buf/sizeof(T*) ) )
03257 alt_buf = new T*[m_num_items];
03258 else
03259 alt_buf = stack_buf;
03260
03261 bool sorted_items_in_alt_buf = MergeSort( m_items, alt_buf, m_num_items );
03262
03263
03264
03265
03266
03267 int max_waste_heap_items = ( c_max_stack_buf/sizeof(T*) ) / 32;
03268
03269 if(alt_buf == stack_buf)
03270 {
03271
03272
03273 if(m_items_allocated_on_stack)
03274 {
03275
03276 if(sorted_items_in_alt_buf)
03277 {
03278
03279 memcpy( m_items, alt_buf, m_num_items*sizeof(T*) );
03280 }
03281 }
03282 else
03283 {
03284
03285 if(m_num_items < m_items_allocated - max_waste_heap_items)
03286 {
03287
03288 T** new_items = new T*[m_num_items];
03289 if(sorted_items_in_alt_buf)
03290 memcpy( new_items, alt_buf, m_num_items*sizeof(T*) );
03291 else
03292 memcpy( new_items, m_items, m_num_items*sizeof(T*) );
03293 delete[] m_items;
03294 m_items = new_items;
03295 m_items_allocated = m_num_items;
03296 }
03297 else
03298 {
03299
03300 if(sorted_items_in_alt_buf)
03301 {
03302
03303 memcpy( m_items, alt_buf, m_num_items*sizeof(T*) );
03304 }
03305 }
03306 }
03307 }
03308 else
03309 {
03310
03311
03312 if(m_items_allocated_on_stack)
03313 {
03314
03315 if(sorted_items_in_alt_buf)
03316 {
03317
03318 memcpy( m_items, alt_buf, m_num_items*sizeof(T*) );
03319 }
03320 delete[] alt_buf;
03321 }
03322 else
03323 {
03324 if(sorted_items_in_alt_buf)
03325 {
03326
03327 delete[] m_items;
03328 m_items = alt_buf;
03329 m_items_allocated = m_num_items;
03330 }
03331 else
03332 {
03333
03334
03335 if(m_num_items < m_items_allocated - max_waste_heap_items)
03336 {
03337
03338 memcpy( alt_buf, m_items, m_num_items*sizeof(T*) );
03339 delete[] m_items;
03340 m_items = alt_buf;
03341 m_items_allocated = m_num_items;
03342 }
03343 else
03344 {
03345
03346 delete[] alt_buf;
03347 }
03348 }
03349 }
03350 }
03351 }
03352
03353
03354 template <class T, class K>
03355 bool
03356 SortedList_t<T,K>::MergeSort( T** from, T** to, int num_items )
03357 {
03358 int first_half_num_items = num_items/2;
03359 assert(first_half_num_items >= 1);
03360 int second_half_num_items = num_items - first_half_num_items;
03361 assert(second_half_num_items >= 1);
03362 T* temp;
03363
03364
03365 bool first_half_in_to;
03366 if(first_half_num_items == 1)
03367 first_half_in_to = false;
03368 else if(first_half_num_items == 2)
03369 {
03370 if(from[0]->Compare( static_cast<K>(*from[1]) ) > 0)
03371 {
03372
03373 temp = from[0];
03374 from[0] = from[1];
03375 from[1] = temp;
03376 }
03377 first_half_in_to = false;
03378 }
03379 else
03380 {
03381 first_half_in_to = MergeSort( from, to, first_half_num_items );
03382 }
03383
03384
03385 bool second_half_in_to;
03386 if(second_half_num_items == 1)
03387 second_half_in_to = false;
03388 else if(second_half_num_items == 2)
03389 {
03390 if(from[first_half_num_items]->Compare( static_cast<K>(*from[first_half_num_items+1]) ) > 0)
03391 {
03392
03393 temp = from[first_half_num_items];
03394 from[first_half_num_items] = from[first_half_num_items+1];
03395 from[first_half_num_items+1] = temp;
03396 }
03397 second_half_in_to = false;
03398 }
03399 else
03400 {
03401 second_half_in_to = MergeSort( from+first_half_num_items,
03402 to+first_half_num_items,
03403 second_half_num_items );
03404 }
03405
03406
03407
03408 bool result_in_caller_to;
03409 if(first_half_in_to && !second_half_in_to)
03410 {
03411
03412 result_in_caller_to = true;
03413 memcpy( from, to, first_half_num_items*sizeof(T*) );
03414 }
03415 else if(second_half_in_to && !first_half_in_to)
03416 {
03417
03418 result_in_caller_to = true;
03419 memcpy( from + first_half_num_items,
03420 to + first_half_num_items,
03421 second_half_num_items * sizeof(T*) );
03422 }
03423 else if(first_half_in_to)
03424 {
03425
03426
03427 assert(second_half_in_to);
03428 T** temp_buf = from;
03429 from = to;
03430 to = temp_buf;
03431 result_in_caller_to = false;
03432 }
03433 else
03434 {
03435
03436
03437 assert(!second_half_in_to);
03438 result_in_caller_to = true;
03439 }
03440
03441
03442 int first_half_index = 0;
03443 int second_half_index = 0;
03444 int to_index = 0;
03445 T** from_second_half = from + first_half_num_items;
03446 for(;;)
03447 {
03448 assert(first_half_index < first_half_num_items);
03449 assert(second_half_index < second_half_num_items);
03450 if( from[first_half_index]->Compare(
03451 static_cast<K>(*from_second_half[second_half_index]) )
03452 <= 0 )
03453 {
03454
03455 to[to_index++] = from[first_half_index++];
03456 if(first_half_index == first_half_num_items)
03457 {
03458
03459 while(second_half_index < second_half_num_items)
03460 to[to_index++] = from_second_half[second_half_index++];
03461 break;
03462 }
03463 }
03464 else
03465 {
03466
03467 to[to_index++] = from_second_half[second_half_index++];
03468 if(second_half_index == second_half_num_items)
03469 {
03470
03471 while(first_half_index < first_half_num_items)
03472 to[to_index++] = from[first_half_index++];
03473 break;
03474 }
03475 }
03476 }
03477
03478
03479 assert(first_half_index == first_half_num_items);
03480 assert(second_half_index == second_half_num_items);
03481 assert(to_index == num_items);
03482
03483 return result_in_caller_to;
03484 }
03485
03486
03487 template <class T, class K>
03488 T*
03489 SortedList_t<T,K>::IsInList(T* item) const
03490 {
03491 if(item == NULL)
03492 return NULL;
03493 int index = FindItemIndex( item, false );
03494 if(index == -1)
03495 return NULL;
03496 return item;
03497 }
03498
03499
03500 template <class T, class K>
03501 T*
03502 SortedList_t<T,K>::RemoveItem(T* item)
03503 {
03504 int index = FindItemIndex( item, false );
03505 if(index == -1)
03506 {
03507 debug_error("The specified item was not found");
03508 return NULL;
03509 }
03510
03511
03512 m_num_items--;
03513 assert(m_items[index] == item);
03514 memmove( m_items+index, m_items+index+1, (m_num_items-index) * sizeof(T*) );
03515 return item;
03516 }
03517
03518
03519 template <class T, class K>
03520 T*
03521 SortedList_t<T,K>::RemoveHead()
03522 {
03523 assert(m_num_items);
03524 T* head = m_items[0];
03525 m_num_items--;
03526 memmove( m_items, m_items+1, m_num_items * sizeof(T*) );
03527 return head;
03528 }
03529
03530
03531 template <class T, class K>
03532 inline T*
03533 SortedList_t<T,K>::RemoveTail()
03534 {
03535 assert(m_num_items);
03536 m_num_items--;
03537 return m_items[m_num_items];
03538 }
03539
03540
03541 template <class T, class K>
03542 T*
03543 SortedList_t<T,K>::RemoveItemAt(int index)
03544 {
03545 m_num_items--;
03546 assert(m_num_items > index);
03547 T* item = m_items[index];
03548 memmove( m_items+index, m_items+index+1, (m_num_items-index) * sizeof(T*) );
03549 return item;
03550 }
03551
03552
03553 template <class T, class K>
03554 int
03555 SortedList_t<T,K>::IndexOfItem(T* item)
03556 {
03557 return FindItemIndex( item, false );
03558 }
03559
03560
03561 template <class T, class K>
03562 inline int
03563 SortedList_t<T,K>::CountItems() const
03564 {
03565 return m_num_items;
03566 }
03567
03568
03569 template <class T, class K>
03570 inline T*
03571 SortedList_t<T,K>::Head() const
03572 {
03573 if(m_num_items == 0)
03574 return NULL;
03575 return m_items[0];
03576 }
03577
03578
03579 template <class T, class K>
03580 inline T*
03581 SortedList_t<T,K>::Tail() const
03582 {
03583 if(m_num_items == 0)
03584 return NULL;
03585 return m_items[m_num_items-1];
03586 }
03587
03588
03589 template <class T, class K>
03590 inline T*
03591 SortedList_t<T,K>::ItemAt(int index) const
03592 {
03593 assert(m_num_items > index);
03594 return m_items[index];
03595 }
03596
03597
03598 template <class T, class K>
03599 inline T&
03600 SortedList_t<T,K>::operator [](int index) const
03601 {
03602 assert(m_num_items > index);
03603 return *m_items[index];
03604 }
03605
03606
03607 template <class T, class K>
03608 inline void
03609 SortedList_t<T,K>::operator +=(T* item)
03610 {
03611 AddItem(item);
03612 }
03613
03614
03615 template <class T, class K>
03616 inline void
03617 SortedList_t<T,K>::operator -=(T* item)
03618 {
03619 RemoveItem(item);
03620 }
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632 template <class T, class K>
03633 inline
03634 OwnedSortedList_t<T,K>::OwnedSortedList_t()
03635 { }
03636
03637
03638 template <class T, class K>
03639 inline
03640 OwnedSortedList_t<T,K>::OwnedSortedList_t( T** stack_buffer, int stack_buffer_num_items_allcoated )
03641 : List_t<T*>( stack_buffer, stack_buffer_num_items_allcoated )
03642 { }
03643
03644
03645 template <class T, class K>
03646 OwnedSortedList_t<T,K>::~OwnedSortedList_t()
03647 {
03648 for(int i=0; i<SortedList_t<T,K>::CountItems(); i++)
03649 delete SortedList_t<T,K>::ItemAt(i);
03650 }
03651
03652
03653 #endif // _UT_LISTS_H_