166 } |
166 } |
167 |
167 |
168 GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal) |
168 GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal) |
169 : GenericGrowableArray(initial_size, 0, C_heap, F) { |
169 : GenericGrowableArray(initial_size, 0, C_heap, F) { |
170 _data = (E*)raw_allocate(sizeof(E)); |
170 _data = (E*)raw_allocate(sizeof(E)); |
|
171 // Needed for Visual Studio 2012 and older |
|
172 #ifdef _MSC_VER |
|
173 #pragma warning(suppress: 4345) |
|
174 #endif |
171 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); |
175 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); |
172 } |
176 } |
173 |
177 |
174 GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false, MEMFLAGS memflags = mtInternal) |
178 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) { |
179 : GenericGrowableArray(initial_size, initial_len, C_heap, memflags) { |
369 qsort(_data, length(), sizeof(E), (_sort_Fn)f); |
373 qsort(_data, length(), sizeof(E), (_sort_Fn)f); |
370 } |
374 } |
371 // sort by fixed-stride sub arrays: |
375 // sort by fixed-stride sub arrays: |
372 void sort(int f(E*,E*), int stride) { |
376 void sort(int f(E*,E*), int stride) { |
373 qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f); |
377 qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f); |
|
378 } |
|
379 |
|
380 // Binary search and insertion utility. Search array for element |
|
381 // matching key according to the static compare function. Insert |
|
382 // that element is not already in the list. Assumes the list is |
|
383 // already sorted according to compare function. |
|
384 template <int compare(const E&, const E&)> E insert_sorted(const E& key) { |
|
385 bool found; |
|
386 int location = find_sorted<E, compare>(key, found); |
|
387 if (!found) { |
|
388 insert_before(location, key); |
|
389 } |
|
390 return at(location); |
|
391 } |
|
392 |
|
393 template <typename K, int compare(const K&, const E&)> int find_sorted(const K& key, bool& found) { |
|
394 found = false; |
|
395 int min = 0; |
|
396 int max = length() - 1; |
|
397 |
|
398 while (max >= min) { |
|
399 int mid = (int)(((uint)max + min) / 2); |
|
400 E value = at(mid); |
|
401 int diff = compare(key, value); |
|
402 if (diff > 0) { |
|
403 min = mid + 1; |
|
404 } else if (diff < 0) { |
|
405 max = mid - 1; |
|
406 } else { |
|
407 found = true; |
|
408 return mid; |
|
409 } |
|
410 } |
|
411 return min; |
374 } |
412 } |
375 }; |
413 }; |
376 |
414 |
377 // Global GrowableArray methods (one instance in the library per each 'E' type). |
415 // Global GrowableArray methods (one instance in the library per each 'E' type). |
378 |
416 |
383 while (j >= _max) _max = _max*2; |
421 while (j >= _max) _max = _max*2; |
384 // j < _max |
422 // j < _max |
385 E* newData = (E*)raw_allocate(sizeof(E)); |
423 E* newData = (E*)raw_allocate(sizeof(E)); |
386 int i = 0; |
424 int i = 0; |
387 for ( ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]); |
425 for ( ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]); |
|
426 // Needed for Visual Studio 2012 and older |
|
427 #ifdef _MSC_VER |
|
428 #pragma warning(suppress: 4345) |
|
429 #endif |
388 for ( ; i < _max; i++) ::new ((void*)&newData[i]) E(); |
430 for ( ; i < _max; i++) ::new ((void*)&newData[i]) E(); |
389 for (i = 0; i < old_max; i++) _data[i].~E(); |
431 for (i = 0; i < old_max; i++) _data[i].~E(); |
390 if (on_C_heap() && _data != NULL) { |
432 if (on_C_heap() && _data != NULL) { |
391 FreeHeap(_data); |
433 FreeHeap(_data); |
392 } |
434 } |