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 * In the following move methods, 'src' is destroyed leaving behind uniniti
alized raw storage. |
| 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 |