| OLD | NEW |
| (Empty) |
| 1 // | |
| 2 // SkTRefArray.h | |
| 3 // core | |
| 4 // | |
| 5 // Created by Mike Reed on 7/17/12. | |
| 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. | |
| 7 // | |
| 8 | |
| 9 #ifndef SkTRefArray_DEFINED | |
| 10 #define SkTRefArray_DEFINED | |
| 11 | |
| 12 #include "SkRefCnt.h" | |
| 13 #include <new> | |
| 14 | |
| 15 /** | |
| 16 * Wrapper to manage thread-safe sharing of an array of T objects. The array | |
| 17 * cannot be grown or shrunk. | |
| 18 */ | |
| 19 template <typename T> class SkTRefArray : public SkRefCnt { | |
| 20 /* | |
| 21 * Shared factory to allocate the space needed for our instance plus N | |
| 22 * T entries at the end. We call our constructor, but not the constructors | |
| 23 * for the elements. Those are called by the proper Create method. | |
| 24 */ | |
| 25 static SkTRefArray<T>* Alloc(int count) { | |
| 26 // space for us, and our [count] elements | |
| 27 size_t size = sizeof(SkTRefArray<T>) + count * sizeof(T); | |
| 28 SkTRefArray<T>* obj = (SkTRefArray<T>*)sk_malloc_throw(size); | |
| 29 | |
| 30 SkNEW_PLACEMENT(obj, SkTRefArray<T>); | |
| 31 obj->fCount = count; | |
| 32 return obj; | |
| 33 } | |
| 34 | |
| 35 public: | |
| 36 /** | |
| 37 * Return a new array with 'count' elements, initialized to their default | |
| 38 * value. To change them to some other value, use writableBegin/End or | |
| 39 * writableAt(), but do that before this array is given to another thread. | |
| 40 */ | |
| 41 static SkTRefArray<T>* Create(int count) { | |
| 42 SkTRefArray<T>* obj = Alloc(count); | |
| 43 T* array = const_cast<T*>(obj->begin()); | |
| 44 for (int i = 0; i < count; ++i) { | |
| 45 SkNEW_PLACEMENT(&array[i], T); | |
| 46 } | |
| 47 return obj; | |
| 48 } | |
| 49 | |
| 50 /** | |
| 51 * Return a new array with 'count' elements, initialized from the provided | |
| 52 * src array. To change them to some other value, use writableBegin/End or | |
| 53 * writableAt(), but do that before this array is given to another thread. | |
| 54 */ | |
| 55 static SkTRefArray<T>* Create(const T src[], int count) { | |
| 56 SkTRefArray<T>* obj = Alloc(count); | |
| 57 T* array = const_cast<T*>(obj->begin()); | |
| 58 for (int i = 0; i < count; ++i) { | |
| 59 SkNEW_PLACEMENT_ARGS(&array[i], T, (src[i])); | |
| 60 } | |
| 61 return obj; | |
| 62 } | |
| 63 | |
| 64 int count() const { return fCount; } | |
| 65 const T* begin() const { return (const T*)(this + 1); } | |
| 66 const T* end() const { return this->begin() + fCount; } | |
| 67 const T& at(int index) const { | |
| 68 SkASSERT((unsigned)index < (unsigned)fCount); | |
| 69 return this->begin()[index]; | |
| 70 } | |
| 71 const T& operator[](int index) const { return this->at(index); } | |
| 72 | |
| 73 // For the writable methods, we assert that we are the only owner if we | |
| 74 // call these, since other owners are not informed if we change an element. | |
| 75 | |
| 76 T* writableBegin() { | |
| 77 SkASSERT(this->unique()); | |
| 78 return (T*)(this + 1); | |
| 79 } | |
| 80 T* writableEnd() { | |
| 81 return this->writableBegin() + fCount; | |
| 82 } | |
| 83 T& writableAt(int index) { | |
| 84 SkASSERT((unsigned)index < (unsigned)fCount); | |
| 85 return this->writableBegin()[index]; | |
| 86 } | |
| 87 | |
| 88 protected: | |
| 89 virtual void internal_dispose() const SK_OVERRIDE { | |
| 90 T* array = const_cast<T*>(this->begin()); | |
| 91 int n = fCount; | |
| 92 | |
| 93 for (int i = 0; i < n; ++i) { | |
| 94 array->~T(); | |
| 95 array += 1; | |
| 96 } | |
| 97 | |
| 98 this->internal_dispose_restore_refcnt_to_1(); | |
| 99 this->~SkTRefArray<T>(); | |
| 100 sk_free((void*)this); | |
| 101 } | |
| 102 | |
| 103 private: | |
| 104 int fCount; | |
| 105 | |
| 106 // hide this | |
| 107 virtual ~SkTRefArray() {} | |
| 108 | |
| 109 typedef SkRefCnt INHERITED; | |
| 110 }; | |
| 111 | |
| 112 #endif | |
| OLD | NEW |