1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkTRefArray.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,112 @@ 1.4 +// 1.5 +// SkTRefArray.h 1.6 +// core 1.7 +// 1.8 +// Created by Mike Reed on 7/17/12. 1.9 +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. 1.10 +// 1.11 + 1.12 +#ifndef SkTRefArray_DEFINED 1.13 +#define SkTRefArray_DEFINED 1.14 + 1.15 +#include "SkRefCnt.h" 1.16 +#include <new> 1.17 + 1.18 +/** 1.19 + * Wrapper to manage thread-safe sharing of an array of T objects. The array 1.20 + * cannot be grown or shrunk. 1.21 + */ 1.22 +template <typename T> class SkTRefArray : public SkRefCnt { 1.23 + /* 1.24 + * Shared factory to allocate the space needed for our instance plus N 1.25 + * T entries at the end. We call our constructor, but not the constructors 1.26 + * for the elements. Those are called by the proper Create method. 1.27 + */ 1.28 + static SkTRefArray<T>* Alloc(int count) { 1.29 + // space for us, and our [count] elements 1.30 + size_t size = sizeof(SkTRefArray<T>) + count * sizeof(T); 1.31 + SkTRefArray<T>* obj = (SkTRefArray<T>*)sk_malloc_throw(size); 1.32 + 1.33 + SkNEW_PLACEMENT(obj, SkTRefArray<T>); 1.34 + obj->fCount = count; 1.35 + return obj; 1.36 + } 1.37 + 1.38 +public: 1.39 + /** 1.40 + * Return a new array with 'count' elements, initialized to their default 1.41 + * value. To change them to some other value, use writableBegin/End or 1.42 + * writableAt(), but do that before this array is given to another thread. 1.43 + */ 1.44 + static SkTRefArray<T>* Create(int count) { 1.45 + SkTRefArray<T>* obj = Alloc(count); 1.46 + T* array = const_cast<T*>(obj->begin()); 1.47 + for (int i = 0; i < count; ++i) { 1.48 + SkNEW_PLACEMENT(&array[i], T); 1.49 + } 1.50 + return obj; 1.51 + } 1.52 + 1.53 + /** 1.54 + * Return a new array with 'count' elements, initialized from the provided 1.55 + * src array. To change them to some other value, use writableBegin/End or 1.56 + * writableAt(), but do that before this array is given to another thread. 1.57 + */ 1.58 + static SkTRefArray<T>* Create(const T src[], int count) { 1.59 + SkTRefArray<T>* obj = Alloc(count); 1.60 + T* array = const_cast<T*>(obj->begin()); 1.61 + for (int i = 0; i < count; ++i) { 1.62 + SkNEW_PLACEMENT_ARGS(&array[i], T, (src[i])); 1.63 + } 1.64 + return obj; 1.65 + } 1.66 + 1.67 + int count() const { return fCount; } 1.68 + const T* begin() const { return (const T*)(this + 1); } 1.69 + const T* end() const { return this->begin() + fCount; } 1.70 + const T& at(int index) const { 1.71 + SkASSERT((unsigned)index < (unsigned)fCount); 1.72 + return this->begin()[index]; 1.73 + } 1.74 + const T& operator[](int index) const { return this->at(index); } 1.75 + 1.76 + // For the writable methods, we assert that we are the only owner if we 1.77 + // call these, since other owners are not informed if we change an element. 1.78 + 1.79 + T* writableBegin() { 1.80 + SkASSERT(this->unique()); 1.81 + return (T*)(this + 1); 1.82 + } 1.83 + T* writableEnd() { 1.84 + return this->writableBegin() + fCount; 1.85 + } 1.86 + T& writableAt(int index) { 1.87 + SkASSERT((unsigned)index < (unsigned)fCount); 1.88 + return this->writableBegin()[index]; 1.89 + } 1.90 + 1.91 +protected: 1.92 + virtual void internal_dispose() const SK_OVERRIDE { 1.93 + T* array = const_cast<T*>(this->begin()); 1.94 + int n = fCount; 1.95 + 1.96 + for (int i = 0; i < n; ++i) { 1.97 + array->~T(); 1.98 + array += 1; 1.99 + } 1.100 + 1.101 + this->internal_dispose_restore_refcnt_to_1(); 1.102 + this->~SkTRefArray<T>(); 1.103 + sk_free((void*)this); 1.104 + } 1.105 + 1.106 +private: 1.107 + int fCount; 1.108 + 1.109 + // hide this 1.110 + virtual ~SkTRefArray() {} 1.111 + 1.112 + typedef SkRefCnt INHERITED; 1.113 +}; 1.114 + 1.115 +#endif