151 template<class E, class UnaryPredicate> class GrowableArrayFilterIterator; 152 153 template<class E> class GrowableArray : public GenericGrowableArray { 154 friend class VMStructs; 155 156 private: 157 E* _data; // data array 158 159 void grow(int j); 160 void raw_at_put_grow(int i, const E& p, const E& fill); 161 void clear_and_deallocate(); 162 public: 163 GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) { 164 _data = (E*)raw_allocate(thread, sizeof(E)); 165 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); 166 } 167 168 GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal) 169 : GenericGrowableArray(initial_size, 0, C_heap, F) { 170 _data = (E*)raw_allocate(sizeof(E)); 171 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); 172 } 173 174 GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false, MEMFLAGS memflags = mtInternal) 175 : GenericGrowableArray(initial_size, initial_len, C_heap, memflags) { 176 _data = (E*)raw_allocate(sizeof(E)); 177 int i = 0; 178 for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler); 179 for (; i < _max; i++) ::new ((void*)&_data[i]) E(); 180 } 181 182 GrowableArray(Arena* arena, int initial_size, int initial_len, const E& filler) : GenericGrowableArray(arena, initial_size, initial_len) { 183 _data = (E*)raw_allocate(sizeof(E)); 184 int i = 0; 185 for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler); 186 for (; i < _max; i++) ::new ((void*)&_data[i]) E(); 187 } 188 189 GrowableArray() : GenericGrowableArray(2, 0, false) { 190 _data = (E*)raw_allocate(sizeof(E)); 368 void sort(int f(E*,E*)) { 369 qsort(_data, length(), sizeof(E), (_sort_Fn)f); 370 } 371 // sort by fixed-stride sub arrays: 372 void sort(int f(E*,E*), int stride) { 373 qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f); 374 } 375 }; 376 377 // Global GrowableArray methods (one instance in the library per each 'E' type). 378 379 template<class E> void GrowableArray<E>::grow(int j) { 380 // grow the array by doubling its size (amortized growth) 381 int old_max = _max; 382 if (_max == 0) _max = 1; // prevent endless loop 383 while (j >= _max) _max = _max*2; 384 // j < _max 385 E* newData = (E*)raw_allocate(sizeof(E)); 386 int i = 0; 387 for ( ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]); 388 for ( ; i < _max; i++) ::new ((void*)&newData[i]) E(); 389 for (i = 0; i < old_max; i++) _data[i].~E(); 390 if (on_C_heap() && _data != NULL) { 391 FreeHeap(_data); 392 } 393 _data = newData; 394 } 395 396 template<class E> void GrowableArray<E>::raw_at_put_grow(int i, const E& p, const E& fill) { 397 if (i >= _len) { 398 if (i >= _max) grow(i); 399 for (int j = _len; j < i; j++) 400 _data[j] = fill; 401 _len = i+1; 402 } 403 _data[i] = p; 404 } 405 406 // This function clears and deallocate the data in the growable array that 407 // has been allocated on the C heap. It's not public - called by the | 151 template<class E, class UnaryPredicate> class GrowableArrayFilterIterator; 152 153 template<class E> class GrowableArray : public GenericGrowableArray { 154 friend class VMStructs; 155 156 private: 157 E* _data; // data array 158 159 void grow(int j); 160 void raw_at_put_grow(int i, const E& p, const E& fill); 161 void clear_and_deallocate(); 162 public: 163 GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) { 164 _data = (E*)raw_allocate(thread, sizeof(E)); 165 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); 166 } 167 168 GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal) 169 : GenericGrowableArray(initial_size, 0, C_heap, F) { 170 _data = (E*)raw_allocate(sizeof(E)); 171 // Needed for Visual Studio 2012 and older 172 #pragma warning(suppress: 4345) 173 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); 174 } 175 176 GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false, MEMFLAGS memflags = mtInternal) 177 : GenericGrowableArray(initial_size, initial_len, C_heap, memflags) { 178 _data = (E*)raw_allocate(sizeof(E)); 179 int i = 0; 180 for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler); 181 for (; i < _max; i++) ::new ((void*)&_data[i]) E(); 182 } 183 184 GrowableArray(Arena* arena, int initial_size, int initial_len, const E& filler) : GenericGrowableArray(arena, initial_size, initial_len) { 185 _data = (E*)raw_allocate(sizeof(E)); 186 int i = 0; 187 for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler); 188 for (; i < _max; i++) ::new ((void*)&_data[i]) E(); 189 } 190 191 GrowableArray() : GenericGrowableArray(2, 0, false) { 192 _data = (E*)raw_allocate(sizeof(E)); 370 void sort(int f(E*,E*)) { 371 qsort(_data, length(), sizeof(E), (_sort_Fn)f); 372 } 373 // sort by fixed-stride sub arrays: 374 void sort(int f(E*,E*), int stride) { 375 qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f); 376 } 377 }; 378 379 // Global GrowableArray methods (one instance in the library per each 'E' type). 380 381 template<class E> void GrowableArray<E>::grow(int j) { 382 // grow the array by doubling its size (amortized growth) 383 int old_max = _max; 384 if (_max == 0) _max = 1; // prevent endless loop 385 while (j >= _max) _max = _max*2; 386 // j < _max 387 E* newData = (E*)raw_allocate(sizeof(E)); 388 int i = 0; 389 for ( ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]); 390 // Needed for Visual Studio 2012 and older 391 #pragma warning(suppress: 4345) 392 for ( ; i < _max; i++) ::new ((void*)&newData[i]) E(); 393 for (i = 0; i < old_max; i++) _data[i].~E(); 394 if (on_C_heap() && _data != NULL) { 395 FreeHeap(_data); 396 } 397 _data = newData; 398 } 399 400 template<class E> void GrowableArray<E>::raw_at_put_grow(int i, const E& p, const E& fill) { 401 if (i >= _len) { 402 if (i >= _max) grow(i); 403 for (int j = _len; j < i; j++) 404 _data[j] = fill; 405 _len = i+1; 406 } 407 _data[i] = p; 408 } 409 410 // This function clears and deallocate the data in the growable array that 411 // has been allocated on the C heap. It's not public - called by the |