SkTArray.h revision d51041469a9a45562d88e9ff137c6726562e8c40
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com#ifndef SkTArray_DEFINED 949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com#define SkTArray_DEFINED 10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include <new> 1249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com#include "SkTypes.h" 1349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com#include "SkTemplates.h" 14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 15a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate <typename T, bool MEM_COPY = false> class SkTArray; 16a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 17a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comnamespace SkTArrayExt { 18a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 19a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate<typename T> 20a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.cominline void copy(SkTArray<T, true>* self, const T* array) { 21a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com memcpy(self->fMemArray, array, self->fCount * sizeof(T)); 22a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com} 23a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate<typename T> 24a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.cominline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) { 25a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com memcpy(newMemArray, self->fMemArray, self->fCount * sizeof(T)); 26a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com} 27a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 28a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate<typename T> 29a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.cominline void copy(SkTArray<T, false>* self, const T* array) { 30a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com for (int i = 0; i < self->fCount; ++i) { 31b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org SkNEW_PLACEMENT_ARGS(self->fItemArray + i, T, (array[i])); 32a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com } 33a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com} 34a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate<typename T> 35a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.cominline void copyAndDelete(SkTArray<T, false>* self, char* newMemArray) { 36a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com for (int i = 0; i < self->fCount; ++i) { 37b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org SkNEW_PLACEMENT_ARGS(newMemArray + sizeof(T) * i, T, (self->fItemArray[i])); 38a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com self->fItemArray[i].~T(); 39a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com } 40a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com} 41a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 42a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com} 43a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 44d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.comtemplate <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_COPY>*, int); 45d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 46a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com/** When MEM_COPY is true T will be bit copied when moved. 47a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com When MEM_COPY is false, T will be copy constructed / destructed. 48a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com In all cases T's constructor will be called on allocation, 49a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com and its destructor will be called from this object's destructor. 50a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com*/ 51a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate <typename T, bool MEM_COPY> class SkTArray { 52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.compublic: 5349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 5449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Creates an empty array with no initial storage 5549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 5649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkTArray() { 57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount = 0; 5849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com fReserveCount = gMIN_ALLOC_COUNT; 59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAllocCount = 0; 60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fMemArray = NULL; 61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fPreAllocMemArray = NULL; 62ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 63ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 6449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 65fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Creates an empty array that will preallocate space for reserveCount 6649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * elements. 6749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 6849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com explicit SkTArray(int reserveCount) { 6992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(NULL, 0, NULL, reserveCount); 70ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 71fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 7249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 7349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Copies one array to another. The new array will be heap allocated. 7449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 7549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com explicit SkTArray(const SkTArray& array) { 7692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array.fItemArray, array.fCount, NULL, 0); 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 7949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 80fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Creates a SkTArray by copying contents of a standard C array. The new 8149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * array will be heap allocated. Be careful not to use this constructor 8249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * when you really want the (void*, int) version. 8349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 8449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkTArray(const T* array, int count) { 8592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array, count, NULL, 0); 86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 8849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 8949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * assign copy of array to this 9049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 9149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkTArray& operator =(const SkTArray& array) { 921c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < fCount; ++i) { 93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fItemArray[i].~T(); 94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount = 0; 96d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com this->checkRealloc((int)array.count()); 97ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount = array.count(); 98a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray)); 99ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return *this; 100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 10292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com virtual ~SkTArray() { 1031c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < fCount; ++i) { 104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fItemArray[i].~T(); 105ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 106ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fMemArray != fPreAllocMemArray) { 10749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com sk_free(fMemArray); 108ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 109ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 110ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 11149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 11249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Resets to count() == 0 11349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 114d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com void reset() { this->pop_back_n(fCount); } 115d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 11649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 117b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org * Resets to count() = n newly constructed T objects. 118b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org */ 119b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org void reset(int n) { 120b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org SkASSERT(n >= 0); 121b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org for (int i = 0; i < fCount; ++i) { 122b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org fItemArray[i].~T(); 123b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org } 124b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org // set fCount to 0 before calling checkRealloc so that no copy cons. are called. 125b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org fCount = 0; 126b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(n); 127b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org fCount = n; 128b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org for (int i = 0; i < fCount; ++i) { 129b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org SkNEW_PLACEMENT(fItemArray + i, T); 130b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org } 131b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org } 132b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org 133b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org /** 134054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com * Resets to a copy of a C array. 135054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com */ 136054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com void reset(const T* array, int count) { 137054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com for (int i = 0; i < fCount; ++i) { 138054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com fItemArray[i].~T(); 139054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com } 140054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com int delta = count - fCount; 141054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com this->checkRealloc(delta); 142054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com fCount = count; 143054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com for (int i = 0; i < count; ++i) { 144054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com SkTArrayExt::copy(this, array); 145054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com } 146054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com } 147054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 148054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com /** 14949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Number of elements in the array. 15049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 1511c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int count() const { return fCount; } 152ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 15349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 15449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Is the array empty. 15549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bool empty() const { return !fCount; } 157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 158a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com /** 159a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * Adds 1 new default-constructed T value and returns in by reference. Note 160a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * the reference only remains valid until the next call that adds or removes 161a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * elements. 162a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com */ 163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com T& push_back() { 164d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newT = reinterpret_cast<T*>(this->push_back_raw(1)); 165d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkNEW_PLACEMENT(newT, T); 166d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return *newT; 167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 169a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com /** 1704fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * Version of above that uses a copy constructor to initialize the new item 1714fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com */ 1724fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com T& push_back(const T& t) { 173d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newT = reinterpret_cast<T*>(this->push_back_raw(1)); 174d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkNEW_PLACEMENT_ARGS(newT, T, (t)); 175d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return *newT; 1764fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 1774fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 1784fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com /** 179a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * Allocates n more default T values, and returns the address of the start 180a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * of that new range. Note: this address is only valid until the next API 181a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * call made on the array that might add or remove elements. 182a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com */ 183a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com T* push_back_n(int n) { 18449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(n >= 0); 185d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newTs = reinterpret_cast<T*>(this->push_back_raw(n)); 1861c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < n; ++i) { 187d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkNEW_PLACEMENT(newTs + i, T); 188ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 189d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return newTs; 190ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 191ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 19249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 1934fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * Version of above that uses a copy constructor to initialize all n items 1944fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * to the same T. 1954fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com */ 1964fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com T* push_back_n(int n, const T& t) { 1974fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com SkASSERT(n >= 0); 198d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newTs = reinterpret_cast<T*>(this->push_back_raw(n)); 1994fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com for (int i = 0; i < n; ++i) { 200d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkNEW_PLACEMENT_ARGS(newTs[i], T, (t)); 2014fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 202d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return newTs; 2034fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 2044fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 2054fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com /** 2064fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * Version of above that uses a copy constructor to initialize the n items 2074fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * to separate T values. 2084fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com */ 2094fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com T* push_back_n(int n, const T t[]) { 2104fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com SkASSERT(n >= 0); 211b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(n); 2124fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com for (int i = 0; i < n; ++i) { 213b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t[i])); 2144fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 2154fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com fCount += n; 2164fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com return fItemArray + fCount - n; 2174fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 2184fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 2194fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com /** 22049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Removes the last element. Not safe to call when count() == 0. 22149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 222ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void pop_back() { 22349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fCount > 0); 224ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com --fCount; 225ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fItemArray[fCount].~T(); 226b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(0); 227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 22949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 23049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Removes the last n elements. Not safe to call when count() < n. 23149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2321c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com void pop_back_n(int n) { 23349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(n >= 0); 23449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fCount >= n); 235ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount -= n; 2361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < n; ++i) { 237d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fItemArray[fCount + i].~T(); 238ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 239b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(0); 240ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 241ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 24249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 24349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Pushes or pops from the back to resize. Pushes will be default 24449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * initialized. 24549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com void resize_back(int newCount) { 24749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(newCount >= 0); 2481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 249ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (newCount > fCount) { 250b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->push_back_n(newCount - fCount); 251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else if (newCount < fCount) { 252b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->pop_back_n(fCount - newCount); 253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 254ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2569b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com T* begin() { 2579b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray; 2589b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2599b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com const T* begin() const { 2609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray; 2619b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2629b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com T* end() { 2639b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray ? fItemArray + fCount : NULL; 2649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2659b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com const T* end() const { 2669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray ? fItemArray + fCount : NULL;; 2679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2689b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 2699b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com /** 27049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Get the i^th element. 27149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2721c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com T& operator[] (int i) { 27349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 27449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 275ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[i]; 276ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 277ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2781c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com const T& operator[] (int i) const { 27949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 28049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 281ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[i]; 282ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 283ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 28449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 28549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * equivalent to operator[](0) 28649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 28749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com T& front() { SkASSERT(fCount > 0); return fItemArray[0];} 288ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 28949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com const T& front() const { SkASSERT(fCount > 0); return fItemArray[0];} 290ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 29149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 29249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * equivalent to operator[](count() - 1) 29349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 29449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com T& back() { SkASSERT(fCount); return fItemArray[fCount - 1];} 295ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 29649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com const T& back() const { SkASSERT(fCount > 0); return fItemArray[fCount - 1];} 297ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 29849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 29949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * equivalent to operator[](count()-1-i) 30049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 3011c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com T& fromBack(int i) { 30249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 30349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 304ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[fCount - i - 1]; 305ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 306ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3071c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com const T& fromBack(int i) const { 30849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 30949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 310ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[fCount - i - 1]; 311ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 312ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 313ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org bool operator==(const SkTArray<T, MEM_COPY>& right) const { 314ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org int leftCount = this->count(); 315ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (leftCount != right.count()) { 316ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return false; 317ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 318ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org for (int index = 0; index < leftCount; ++index) { 319ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (fItemArray[index] != right.fItemArray[index]) { 320ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return false; 321ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 322ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 323ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return true; 324ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 325ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 326ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org bool operator!=(const SkTArray<T, MEM_COPY>& right) const { 327ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return !(*this == right); 328ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 329ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 33092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprotected: 33192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com /** 33292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Creates an empty array that will use the passed storage block until it 33392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * is insufficiently large to hold the entire array. 33492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 33592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com template <int N> 33692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkTArray(SkAlignedSTStorage<N,T>* storage) { 33792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(NULL, 0, storage->get(), N); 33892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 33992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 34092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com /** 34192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Copy another array, using preallocated storage if preAllocCount >= 34292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * array.count(). Otherwise storage will only be used when array shrinks 34392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * to fit. 34492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 34592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com template <int N> 34692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkTArray(const SkTArray& array, SkAlignedSTStorage<N,T>* storage) { 34792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array.fItemArray, array.fCount, storage->get(), N); 34892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 34992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 35092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com /** 35192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Copy a C array, using preallocated storage if preAllocCount >= 35292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * count. Otherwise storage will only be used when array shrinks 35392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * to fit. 35492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 35592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com template <int N> 35692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) { 35792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array, count, storage->get(), N); 35892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 35992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 36092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com void init(const T* array, int count, 36192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com void* preAllocStorage, int preAllocOrReserveCount) { 362d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org SkASSERT(count >= 0); 363d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org SkASSERT(preAllocOrReserveCount >= 0); 36492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fCount = count; 36592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fReserveCount = (preAllocOrReserveCount > 0) ? 36692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com preAllocOrReserveCount : 36792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com gMIN_ALLOC_COUNT; 36892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fPreAllocMemArray = preAllocStorage; 36992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com if (fReserveCount >= fCount && 37092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com NULL != preAllocStorage) { 37192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fAllocCount = fReserveCount; 37292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fMemArray = preAllocStorage; 37392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } else { 374d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org fAllocCount = SkMax32(fCount, fReserveCount); 375d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); 37692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 37792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 378a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com SkTArrayExt::copy(this, array); 37992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 38092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 381ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comprivate: 382ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 38349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com static const int gMIN_ALLOC_COUNT = 8; 3841c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 385d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // Helper function that makes space for n objects, adjusts the count, but does not initialize 386d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // the new objects. 387d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com void* push_back_raw(int n) { 388d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com this->checkRealloc(n); 389d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com void* ptr = fItemArray + fCount; 390d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fCount += n; 391d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return ptr; 392d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 393d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 3941c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com inline void checkRealloc(int delta) { 39549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fCount >= 0); 39649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fAllocCount >= 0); 3971c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 39849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(-delta <= fCount); 399ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4001c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int newCount = fCount + delta; 401a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com int newAllocCount = fAllocCount; 402ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 403137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com if (newCount > fAllocCount || newCount < (fAllocCount / 3)) { 404137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com // whether we're growing or shrinking, we leave at least 50% extra space for future 405137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com // growth (clamped to the reserve count). 406137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com newAllocCount = SkMax32(newCount + ((newCount + 1) >> 1), fReserveCount); 407ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 408a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com if (newAllocCount != fAllocCount) { 409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 410a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com fAllocCount = newAllocCount; 411a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com char* newMemArray; 412ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 413ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) { 414a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com newMemArray = (char*) fPreAllocMemArray; 415ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 416a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T)); 417ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 418ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 419a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com SkTArrayExt::copyAndDelete<T>(this, newMemArray); 420ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 421ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fMemArray != fPreAllocMemArray) { 42249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com sk_free(fMemArray); 423ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 424a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com fMemArray = newMemArray; 425ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 426ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 427ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 428d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com friend void* operator new<T>(size_t, SkTArray*, int); 429d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 430cf385232c45b7692eaf31260fe650457f400521abungeman@google.com template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*); 431cf385232c45b7692eaf31260fe650457f400521abungeman@google.com template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true>* that, char*); 432a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 433cf385232c45b7692eaf31260fe650457f400521abungeman@google.com template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*); 434cf385232c45b7692eaf31260fe650457f400521abungeman@google.com template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, false>* that, char*); 435a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com 4361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int fReserveCount; 4371c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int fCount; 4381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int fAllocCount; 439ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void* fPreAllocMemArray; 440ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com union { 441ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com T* fItemArray; 442ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void* fMemArray; 443ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com }; 444ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 445ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 446d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com// Use the below macro (SkNEW_APPEND_TO_TARRAY) rather than calling this directly 447d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.comtemplate <typename T, bool MEM_COPY> 448d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.comvoid* operator new(size_t, SkTArray<T, MEM_COPY>* array, int atIndex) { 449d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // Currently, we only support adding to the end of the array. When the array class itself 450d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // supports random insertion then this should be updated. 451d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // SkASSERT(atIndex >= 0 && atIndex <= array->count()); 452d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkASSERT(atIndex == array->count()); 453d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return array->push_back_raw(1); 454d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com} 455d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 456d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com// Constructs a new object as the last element of an SkTArray. 457d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com#define SkNEW_APPEND_TO_TARRAY(array_ptr, type_name, args) \ 458d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com (new ((array_ptr), (array_ptr)->count()) type_name args) 459d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 460d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 46192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com/** 46292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Subclass of SkTArray that contains a preallocated memory block for the array. 46392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 464f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.comtemplate <int N, typename T, bool MEM_COPY = false> 465f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.comclass SkSTArray : public SkTArray<T, MEM_COPY> { 46692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprivate: 467f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.com typedef SkTArray<T, MEM_COPY> INHERITED; 46892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 46992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.compublic: 47092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray() : INHERITED(&fStorage) { 47192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 47292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 47392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray(const SkSTArray& array) 47492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com : INHERITED(array, &fStorage) { 47592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 47692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 47792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com explicit SkSTArray(const INHERITED& array) 47892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com : INHERITED(array, &fStorage) { 47992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 48092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 48192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray(const T* array, int count) 48292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com : INHERITED(array, count, &fStorage) { 48392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 48492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 48592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray& operator= (const SkSTArray& array) { 48692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com return *this = *(const INHERITED*)&array; 48792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 48892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 48992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray& operator= (const INHERITED& array) { 49092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com INHERITED::operator=(array); 49192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com return *this; 49292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 49392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 49492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprivate: 49592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkAlignedSTStorage<N,T> fStorage; 49692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com}; 49792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 498ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 499