Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef SkTArray_DEFINED | 8 #ifndef SkTArray_DEFINED |
| 9 #define SkTArray_DEFINED | 9 #define SkTArray_DEFINED |
| 10 | 10 |
| 11 #include "../private/SkTLogic.h" | |
| 11 #include "../private/SkTemplates.h" | 12 #include "../private/SkTemplates.h" |
| 12 #include "SkTypes.h" | 13 #include "SkTypes.h" |
| 13 | 14 |
| 14 #include <new> | 15 #include <new> |
| 15 #include <utility> | 16 #include <utility> |
| 16 | 17 |
| 17 template <typename T, bool MEM_COPY = false> class SkTArray; | 18 template <typename T, bool MEM_COPY = false> class SkTArray; |
| 18 | |
| 19 namespace SkTArrayExt { | |
| 20 | |
| 21 template<typename T> | |
| 22 inline void copy(SkTArray<T, true>* self, int dst, int src) { | |
| 23 memcpy(&self->fItemArray[dst], &self->fItemArray[src], sizeof(T)); | |
| 24 } | |
| 25 template<typename T> | |
| 26 inline void copy(SkTArray<T, true>* self, const T* array) { | |
| 27 sk_careful_memcpy(self->fMemArray, array, self->fCount * sizeof(T)); | |
| 28 } | |
| 29 template<typename T> | |
| 30 inline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) { | |
| 31 sk_careful_memcpy(newMemArray, self->fMemArray, self->fCount * sizeof(T)); | |
| 32 } | |
| 33 | |
| 34 template<typename T> | |
| 35 inline void copy(SkTArray<T, false>* self, int dst, int src) { | |
| 36 new (&self->fItemArray[dst]) T(self->fItemArray[src]); | |
| 37 } | |
| 38 template<typename T> | |
| 39 inline void copy(SkTArray<T, false>* self, const T* array) { | |
| 40 for (int i = 0; i < self->fCount; ++i) { | |
| 41 new (self->fItemArray + i) T(array[i]); | |
| 42 } | |
| 43 } | |
| 44 template<typename T> | |
| 45 inline void copyAndDelete(SkTArray<T, false>* self, char* newMemArray) { | |
| 46 for (int i = 0; i < self->fCount; ++i) { | |
| 47 new (newMemArray + sizeof(T) * i) T(self->fItemArray[i]); | |
| 48 self->fItemArray[i].~T(); | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 } | |
| 53 | |
| 54 template <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_ COPY>*, int); | 19 template <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_ COPY>*, int); |
| 55 | 20 |
| 56 /** When MEM_COPY is true T will be bit copied when moved. | 21 /** When MEM_COPY is true T will be bit copied when moved. |
| 57 When MEM_COPY is false, T will be copy constructed / destructed. | 22 When MEM_COPY is false, T will be copy constructed / destructed. |
| 58 In all cases T will be default-initialized on allocation, | 23 In all cases T will be default-initialized on allocation, |
| 59 and its destructor will be called from this object's destructor. | 24 and its destructor will be called from this object's destructor. |
| 60 */ | 25 */ |
| 61 template <typename T, bool MEM_COPY> class SkTArray { | 26 template <typename T, bool MEM_COPY> class SkTArray { |
| 62 public: | 27 public: |
| 63 /** | 28 /** |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 /** | 63 /** |
| 99 * assign copy of array to this | 64 * assign copy of array to this |
| 100 */ | 65 */ |
| 101 SkTArray& operator =(const SkTArray& array) { | 66 SkTArray& operator =(const SkTArray& array) { |
| 102 for (int i = 0; i < fCount; ++i) { | 67 for (int i = 0; i < fCount; ++i) { |
| 103 fItemArray[i].~T(); | 68 fItemArray[i].~T(); |
| 104 } | 69 } |
| 105 fCount = 0; | 70 fCount = 0; |
| 106 this->checkRealloc((int)array.count()); | 71 this->checkRealloc((int)array.count()); |
| 107 fCount = array.count(); | 72 fCount = array.count(); |
| 108 SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray)); | 73 this->copy(static_cast<const T*>(array.fMemArray)); |
| 109 return *this; | 74 return *this; |
| 110 } | 75 } |
| 111 | 76 |
| 112 ~SkTArray() { | 77 ~SkTArray() { |
| 113 for (int i = 0; i < fCount; ++i) { | 78 for (int i = 0; i < fCount; ++i) { |
| 114 fItemArray[i].~T(); | 79 fItemArray[i].~T(); |
| 115 } | 80 } |
| 116 if (fMemArray != fPreAllocMemArray) { | 81 if (fMemArray != fPreAllocMemArray) { |
| 117 sk_free(fMemArray); | 82 sk_free(fMemArray); |
| 118 } | 83 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 143 /** | 108 /** |
| 144 * Resets to a copy of a C array. | 109 * Resets to a copy of a C array. |
| 145 */ | 110 */ |
| 146 void reset(const T* array, int count) { | 111 void reset(const T* array, int count) { |
| 147 for (int i = 0; i < fCount; ++i) { | 112 for (int i = 0; i < fCount; ++i) { |
| 148 fItemArray[i].~T(); | 113 fItemArray[i].~T(); |
| 149 } | 114 } |
| 150 int delta = count - fCount; | 115 int delta = count - fCount; |
| 151 this->checkRealloc(delta); | 116 this->checkRealloc(delta); |
| 152 fCount = count; | 117 fCount = count; |
| 153 SkTArrayExt::copy(this, array); | 118 this->copy(array); |
| 154 } | 119 } |
| 155 | 120 |
| 156 void removeShuffle(int n) { | 121 void removeShuffle(int n) { |
| 157 SkASSERT(n < fCount); | 122 SkASSERT(n < fCount); |
| 158 int newCount = fCount - 1; | 123 int newCount = fCount - 1; |
| 159 fCount = newCount; | 124 fCount = newCount; |
| 160 fItemArray[n].~T(); | 125 fItemArray[n].~T(); |
| 161 if (n != newCount) { | 126 if (n != newCount) { |
| 162 SkTArrayExt::copy(this, n, newCount); | 127 this->move(n, newCount); |
| 163 fItemArray[newCount].~T(); | |
| 164 } | 128 } |
| 165 } | 129 } |
| 166 | 130 |
| 167 /** | 131 /** |
| 168 * Number of elements in the array. | 132 * Number of elements in the array. |
| 169 */ | 133 */ |
| 170 int count() const { return fCount; } | 134 int count() const { return fCount; } |
| 171 | 135 |
| 172 /** | 136 /** |
| 173 * Is the array empty. | 137 * Is the array empty. |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 fPreAllocMemArray = preAllocStorage; | 379 fPreAllocMemArray = preAllocStorage; |
| 416 if (fReserveCount >= fCount && | 380 if (fReserveCount >= fCount && |
| 417 preAllocStorage) { | 381 preAllocStorage) { |
| 418 fAllocCount = fReserveCount; | 382 fAllocCount = fReserveCount; |
| 419 fMemArray = preAllocStorage; | 383 fMemArray = preAllocStorage; |
| 420 } else { | 384 } else { |
| 421 fAllocCount = SkMax32(fCount, fReserveCount); | 385 fAllocCount = SkMax32(fCount, fReserveCount); |
| 422 fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); | 386 fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); |
| 423 } | 387 } |
| 424 | 388 |
| 425 SkTArrayExt::copy(this, array); | 389 this->copy(array); |
| 426 } | 390 } |
| 427 | 391 |
| 428 private: | 392 private: |
| 393 /** In the following move and copy methods, 'dst' is assumed to be uninitial ized raw storage. | |
| 394 * When moving (and MEM_COPY is false), the moved from element will be dest royed. | |
|
mtklein
2016/02/07 22:21:23
Shouldn't we just move assign/copy it and let the
bungeman-skia
2016/02/08 03:17:03
How would it? Everything here is placement newed a
bungeman-skia
2016/02/08 03:36:24
Perhaps it would be clearer to replace this second
mtklein
2016/02/08 16:33:07
sgtm
| |
| 395 */ | |
| 396 template <bool E = MEM_COPY> SK_WHEN(E, void) copy(const T* src) { | |
| 397 sk_careful_memcpy(fMemArray, src, fCount * sizeof(T)); | |
| 398 } | |
| 399 template <bool E = MEM_COPY> SK_WHEN(E, void) move(int dst, int src) { | |
| 400 memcpy(&fItemArray[dst], &fItemArray[src], sizeof(T)); | |
| 401 } | |
| 402 template <bool E = MEM_COPY> SK_WHEN(E, void) move(char* dst) { | |
| 403 sk_careful_memcpy(dst, fMemArray, fCount * sizeof(T)); | |
| 404 } | |
| 405 | |
| 406 template <bool E = MEM_COPY> SK_WHEN(!E, void) copy(const T* src) { | |
| 407 for (int i = 0; i < fCount; ++i) { | |
| 408 new (fItemArray + i) T(src[i]); | |
| 409 } | |
| 410 } | |
| 411 template <bool E = MEM_COPY> SK_WHEN(!E, void) move(int dst, int src) { | |
| 412 new (&fItemArray[dst]) T(std::move(fItemArray[src])); | |
| 413 fItemArray[src].~T(); | |
| 414 } | |
| 415 template <bool E = MEM_COPY> SK_WHEN(!E, void) move(char* dst) { | |
| 416 for (int i = 0; i < fCount; ++i) { | |
| 417 new (dst + sizeof(T) * i) T(std::move(fItemArray[i])); | |
| 418 fItemArray[i].~T(); | |
| 419 } | |
| 420 } | |
| 429 | 421 |
| 430 static const int gMIN_ALLOC_COUNT = 8; | 422 static const int gMIN_ALLOC_COUNT = 8; |
| 431 | 423 |
| 432 // Helper function that makes space for n objects, adjusts the count, but do es not initialize | 424 // Helper function that makes space for n objects, adjusts the count, but do es not initialize |
| 433 // the new objects. | 425 // the new objects. |
| 434 void* push_back_raw(int n) { | 426 void* push_back_raw(int n) { |
| 435 this->checkRealloc(n); | 427 this->checkRealloc(n); |
| 436 void* ptr = fItemArray + fCount; | 428 void* ptr = fItemArray + fCount; |
| 437 fCount += n; | 429 fCount += n; |
| 438 return ptr; | 430 return ptr; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 456 | 448 |
| 457 fAllocCount = newAllocCount; | 449 fAllocCount = newAllocCount; |
| 458 char* newMemArray; | 450 char* newMemArray; |
| 459 | 451 |
| 460 if (fAllocCount == fReserveCount && fPreAllocMemArray) { | 452 if (fAllocCount == fReserveCount && fPreAllocMemArray) { |
| 461 newMemArray = (char*) fPreAllocMemArray; | 453 newMemArray = (char*) fPreAllocMemArray; |
| 462 } else { | 454 } else { |
| 463 newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T)); | 455 newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T)); |
| 464 } | 456 } |
| 465 | 457 |
| 466 SkTArrayExt::copyAndDelete<T>(this, newMemArray); | 458 this->move(newMemArray); |
| 467 | 459 |
| 468 if (fMemArray != fPreAllocMemArray) { | 460 if (fMemArray != fPreAllocMemArray) { |
| 469 sk_free(fMemArray); | 461 sk_free(fMemArray); |
| 470 } | 462 } |
| 471 fMemArray = newMemArray; | 463 fMemArray = newMemArray; |
| 472 } | 464 } |
| 473 } | 465 } |
| 474 | 466 |
| 475 friend void* operator new<T>(size_t, SkTArray*, int); | 467 friend void* operator new<T>(size_t, SkTArray*, int); |
| 476 | 468 |
| 477 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, int dst, int src); | |
| 478 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*); | |
| 479 template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true >* that, char*); | |
| 480 | |
| 481 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, int dst, int src); | |
| 482 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*); | |
| 483 template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, fals e>* that, char*); | |
| 484 | |
| 485 int fReserveCount; | 469 int fReserveCount; |
| 486 int fCount; | 470 int fCount; |
| 487 int fAllocCount; | 471 int fAllocCount; |
| 488 void* fPreAllocMemArray; | 472 void* fPreAllocMemArray; |
| 489 union { | 473 union { |
| 490 T* fItemArray; | 474 T* fItemArray; |
| 491 void* fMemArray; | 475 void* fMemArray; |
| 492 }; | 476 }; |
| 493 }; | 477 }; |
| 494 | 478 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 SkSTArray& operator= (const INHERITED& array) { | 534 SkSTArray& operator= (const INHERITED& array) { |
| 551 INHERITED::operator=(array); | 535 INHERITED::operator=(array); |
| 552 return *this; | 536 return *this; |
| 553 } | 537 } |
| 554 | 538 |
| 555 private: | 539 private: |
| 556 SkAlignedSTStorage<N,T> fStorage; | 540 SkAlignedSTStorage<N,T> fStorage; |
| 557 }; | 541 }; |
| 558 | 542 |
| 559 #endif | 543 #endif |
| OLD | NEW |