Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: include/core/SkTArray.h

Issue 16951004: Enhancements and a fix to templated containers. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fix recycle Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | include/core/SkTemplates.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 23 matching lines...) Expand all
34 template<typename T> 34 template<typename T>
35 inline void copyAndDelete(SkTArray<T, false>* self, char* newMemArray) { 35 inline void copyAndDelete(SkTArray<T, false>* self, char* newMemArray) {
36 for (int i = 0; i < self->fCount; ++i) { 36 for (int i = 0; i < self->fCount; ++i) {
37 SkNEW_PLACEMENT_ARGS(newMemArray + sizeof(T) * i, T, (self->fItemArray[i ])); 37 SkNEW_PLACEMENT_ARGS(newMemArray + sizeof(T) * i, T, (self->fItemArray[i ]));
38 self->fItemArray[i].~T(); 38 self->fItemArray[i].~T();
39 } 39 }
40 } 40 }
41 41
42 } 42 }
43 43
44 template <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_ COPY>*, int);
45
44 /** When MEM_COPY is true T will be bit copied when moved. 46 /** When MEM_COPY is true T will be bit copied when moved.
45 When MEM_COPY is false, T will be copy constructed / destructed. 47 When MEM_COPY is false, T will be copy constructed / destructed.
46 In all cases T's constructor will be called on allocation, 48 In all cases T's constructor will be called on allocation,
47 and its destructor will be called from this object's destructor. 49 and its destructor will be called from this object's destructor.
48 */ 50 */
49 template <typename T, bool MEM_COPY> class SkTArray { 51 template <typename T, bool MEM_COPY> class SkTArray {
50 public: 52 public:
51 /** 53 /**
52 * Creates an empty array with no initial storage 54 * Creates an empty array with no initial storage
53 */ 55 */
(...skipping 30 matching lines...) Expand all
84 } 86 }
85 87
86 /** 88 /**
87 * assign copy of array to this 89 * assign copy of array to this
88 */ 90 */
89 SkTArray& operator =(const SkTArray& array) { 91 SkTArray& operator =(const SkTArray& array) {
90 for (int i = 0; i < fCount; ++i) { 92 for (int i = 0; i < fCount; ++i) {
91 fItemArray[i].~T(); 93 fItemArray[i].~T();
92 } 94 }
93 fCount = 0; 95 fCount = 0;
94 checkRealloc((int)array.count()); 96 this->checkRealloc((int)array.count());
95 fCount = array.count(); 97 fCount = array.count();
96 SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray)); 98 SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray));
97 return *this; 99 return *this;
98 } 100 }
99 101
100 virtual ~SkTArray() { 102 virtual ~SkTArray() {
101 for (int i = 0; i < fCount; ++i) { 103 for (int i = 0; i < fCount; ++i) {
102 fItemArray[i].~T(); 104 fItemArray[i].~T();
103 } 105 }
104 if (fMemArray != fPreAllocMemArray) { 106 if (fMemArray != fPreAllocMemArray) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 * Is the array empty. 154 * Is the array empty.
153 */ 155 */
154 bool empty() const { return !fCount; } 156 bool empty() const { return !fCount; }
155 157
156 /** 158 /**
157 * Adds 1 new default-constructed T value and returns in by reference. Note 159 * Adds 1 new default-constructed T value and returns in by reference. Note
158 * the reference only remains valid until the next call that adds or removes 160 * the reference only remains valid until the next call that adds or removes
159 * elements. 161 * elements.
160 */ 162 */
161 T& push_back() { 163 T& push_back() {
162 this->checkRealloc(1); 164 T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
163 SkNEW_PLACEMENT((char*)fMemArray + sizeof(T) * fCount, T); 165 SkNEW_PLACEMENT(newT, T);
164 ++fCount; 166 return *newT;
165 return fItemArray[fCount-1];
166 } 167 }
167 168
168 /** 169 /**
169 * Version of above that uses a copy constructor to initialize the new item 170 * Version of above that uses a copy constructor to initialize the new item
170 */ 171 */
171 T& push_back(const T& t) { 172 T& push_back(const T& t) {
172 this->checkRealloc(1); 173 T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
173 SkNEW_PLACEMENT_ARGS((char*)fMemArray + sizeof(T) * fCount, T, (t)); 174 SkNEW_PLACEMENT_ARGS(newT, T, (t));
174 ++fCount; 175 return *newT;
175 return fItemArray[fCount-1];
176 } 176 }
177 177
178 /** 178 /**
179 * Allocates n more default T values, and returns the address of the start 179 * Allocates n more default T values, and returns the address of the start
180 * of that new range. Note: this address is only valid until the next API 180 * of that new range. Note: this address is only valid until the next API
181 * call made on the array that might add or remove elements. 181 * call made on the array that might add or remove elements.
182 */ 182 */
183 T* push_back_n(int n) { 183 T* push_back_n(int n) {
184 SkASSERT(n >= 0); 184 SkASSERT(n >= 0);
185 this->checkRealloc(n); 185 T* newTs = reinterpret_cast<T*>(this->push_back_raw(n));
186 for (int i = 0; i < n; ++i) { 186 for (int i = 0; i < n; ++i) {
187 SkNEW_PLACEMENT(fItemArray + fCount + i, T); 187 SkNEW_PLACEMENT(newTs + i, T);
188 } 188 }
189 fCount += n; 189 return newTs;
190 return fItemArray + fCount - n;
191 } 190 }
192 191
193 /** 192 /**
194 * Version of above that uses a copy constructor to initialize all n items 193 * Version of above that uses a copy constructor to initialize all n items
195 * to the same T. 194 * to the same T.
196 */ 195 */
197 T* push_back_n(int n, const T& t) { 196 T* push_back_n(int n, const T& t) {
198 SkASSERT(n >= 0); 197 SkASSERT(n >= 0);
199 this->checkRealloc(n); 198 T* newTs = reinterpret_cast<T*>(this->push_back_raw(n));
200 for (int i = 0; i < n; ++i) { 199 for (int i = 0; i < n; ++i) {
201 SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t)); 200 SkNEW_PLACEMENT_ARGS(newTs[i], T, (t));
202 } 201 }
203 fCount += n; 202 return newTs;
204 return fItemArray + fCount - n;
205 } 203 }
206 204
207 /** 205 /**
208 * Version of above that uses a copy constructor to initialize the n items 206 * Version of above that uses a copy constructor to initialize the n items
209 * to separate T values. 207 * to separate T values.
210 */ 208 */
211 T* push_back_n(int n, const T t[]) { 209 T* push_back_n(int n, const T t[]) {
212 SkASSERT(n >= 0); 210 SkASSERT(n >= 0);
213 this->checkRealloc(n); 211 this->checkRealloc(n);
214 for (int i = 0; i < n; ++i) { 212 for (int i = 0; i < n; ++i) {
(...skipping 14 matching lines...) Expand all
229 } 227 }
230 228
231 /** 229 /**
232 * Removes the last n elements. Not safe to call when count() < n. 230 * Removes the last n elements. Not safe to call when count() < n.
233 */ 231 */
234 void pop_back_n(int n) { 232 void pop_back_n(int n) {
235 SkASSERT(n >= 0); 233 SkASSERT(n >= 0);
236 SkASSERT(fCount >= n); 234 SkASSERT(fCount >= n);
237 fCount -= n; 235 fCount -= n;
238 for (int i = 0; i < n; ++i) { 236 for (int i = 0; i < n; ++i) {
239 fItemArray[i].~T(); 237 fItemArray[fCount + i].~T();
240 } 238 }
241 this->checkRealloc(0); 239 this->checkRealloc(0);
242 } 240 }
243 241
244 /** 242 /**
245 * Pushes or pops from the back to resize. Pushes will be default 243 * Pushes or pops from the back to resize. Pushes will be default
246 * initialized. 244 * initialized.
247 */ 245 */
248 void resize_back(int newCount) { 246 void resize_back(int newCount) {
249 SkASSERT(newCount >= 0); 247 SkASSERT(newCount >= 0);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); 375 fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
378 } 376 }
379 377
380 SkTArrayExt::copy(this, array); 378 SkTArrayExt::copy(this, array);
381 } 379 }
382 380
383 private: 381 private:
384 382
385 static const int gMIN_ALLOC_COUNT = 8; 383 static const int gMIN_ALLOC_COUNT = 8;
386 384
385 // Helper function that makes space for n objects, adjusts the count, but do es not initialize
386 // the new objects.
387 void* push_back_raw(int n) {
388 this->checkRealloc(n);
389 void* ptr = fItemArray + fCount;
390 fCount += n;
391 return ptr;
392 }
393
387 inline void checkRealloc(int delta) { 394 inline void checkRealloc(int delta) {
388 SkASSERT(fCount >= 0); 395 SkASSERT(fCount >= 0);
389 SkASSERT(fAllocCount >= 0); 396 SkASSERT(fAllocCount >= 0);
390 397
391 SkASSERT(-delta <= fCount); 398 SkASSERT(-delta <= fCount);
392 399
393 int newCount = fCount + delta; 400 int newCount = fCount + delta;
394 int newAllocCount = fAllocCount; 401 int newAllocCount = fAllocCount;
395 402
396 if (newCount > fAllocCount || newCount < (fAllocCount / 3)) { 403 if (newCount > fAllocCount || newCount < (fAllocCount / 3)) {
(...skipping 14 matching lines...) Expand all
411 418
412 SkTArrayExt::copyAndDelete<T>(this, newMemArray); 419 SkTArrayExt::copyAndDelete<T>(this, newMemArray);
413 420
414 if (fMemArray != fPreAllocMemArray) { 421 if (fMemArray != fPreAllocMemArray) {
415 sk_free(fMemArray); 422 sk_free(fMemArray);
416 } 423 }
417 fMemArray = newMemArray; 424 fMemArray = newMemArray;
418 } 425 }
419 } 426 }
420 427
428 friend void* operator new<T>(size_t, SkTArray*, int);
429
421 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*); 430 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*);
422 template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true >* that, char*); 431 template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true >* that, char*);
423 432
424 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*); 433 template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*);
425 template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, fals e>* that, char*); 434 template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, fals e>* that, char*);
426 435
427 int fReserveCount; 436 int fReserveCount;
428 int fCount; 437 int fCount;
429 int fAllocCount; 438 int fAllocCount;
430 void* fPreAllocMemArray; 439 void* fPreAllocMemArray;
431 union { 440 union {
432 T* fItemArray; 441 T* fItemArray;
433 void* fMemArray; 442 void* fMemArray;
434 }; 443 };
435 }; 444 };
436 445
446 // Use the below macro (SkNEW_APPEND_TO_TARRAY) rather than calling this directl y
447 template <typename T, bool MEM_COPY>
448 void* operator new(size_t, SkTArray<T, MEM_COPY>* array, int atIndex) {
449 // Currently, we only support adding to the end of the array. When the array class itself
450 // supports random insertion then this should be updated.
451 // SkASSERT(atIndex >= 0 && atIndex <= array->count());
452 SkASSERT(atIndex == array->count());
453 return array->push_back_raw(1);
454 }
455
456 // Constructs a new object as the last element of an SkTArray.
457 #define SkNEW_APPEND_TO_TARRAY(array_ptr, type_name, args) \
458 (new ((array_ptr), (array_ptr)->count()) type_name args)
459
460
437 /** 461 /**
438 * Subclass of SkTArray that contains a preallocated memory block for the array. 462 * Subclass of SkTArray that contains a preallocated memory block for the array.
439 */ 463 */
440 template <int N, typename T, bool MEM_COPY = false> 464 template <int N, typename T, bool MEM_COPY = false>
441 class SkSTArray : public SkTArray<T, MEM_COPY> { 465 class SkSTArray : public SkTArray<T, MEM_COPY> {
442 private: 466 private:
443 typedef SkTArray<T, MEM_COPY> INHERITED; 467 typedef SkTArray<T, MEM_COPY> INHERITED;
444 468
445 public: 469 public:
446 SkSTArray() : INHERITED(&fStorage) { 470 SkSTArray() : INHERITED(&fStorage) {
(...skipping 18 matching lines...) Expand all
465 SkSTArray& operator= (const INHERITED& array) { 489 SkSTArray& operator= (const INHERITED& array) {
466 INHERITED::operator=(array); 490 INHERITED::operator=(array);
467 return *this; 491 return *this;
468 } 492 }
469 493
470 private: 494 private:
471 SkAlignedSTStorage<N,T> fStorage; 495 SkAlignedSTStorage<N,T> fStorage;
472 }; 496 };
473 497
474 #endif 498 #endif
OLDNEW
« no previous file with comments | « no previous file | include/core/SkTemplates.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698