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 11918090c819109585f8fd2295039385a60eb0b572bungeman#include "../private/SkTLogic.h" 12f3c15b7cfc4eed2528f7db87ea6c1444b55ee856bungeman#include "../private/SkTemplates.h" 1349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com#include "SkTypes.h" 14f3c15b7cfc4eed2528f7db87ea6c1444b55ee856bungeman 15f3c15b7cfc4eed2528f7db87ea6c1444b55ee856bungeman#include <new> 16221524de3be1fc343ad328c5e99562f32b5cad9cbungeman#include <utility> 17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 18a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com/** When MEM_COPY is true T will be bit copied when moved. 19a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com When MEM_COPY is false, T will be copy constructed / destructed. 20d58a856418ba3b3ecdc5e94629c911ec0034dfb1bungeman@google.com In all cases T will be default-initialized on allocation, 21a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com and its destructor will be called from this object's destructor. 22a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com*/ 2385dc359f749c349bbd8e0ba56825b9457f654237bungemantemplate <typename T, bool MEM_COPY = false> class SkTArray { 24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.compublic: 2549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 2649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Creates an empty array with no initial storage 2749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkTArray() { 29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount = 0; 3049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com fReserveCount = gMIN_ALLOC_COUNT; 31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAllocCount = 0; 32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fMemArray = NULL; 33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fPreAllocMemArray = NULL; 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 37fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Creates an empty array that will preallocate space for reserveCount 3849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * elements. 3949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 4049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com explicit SkTArray(int reserveCount) { 4192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(NULL, 0, NULL, reserveCount); 42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 43fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 4549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Copies one array to another. The new array will be heap allocated. 4649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 4749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com explicit SkTArray(const SkTArray& array) { 4892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array.fItemArray, array.fCount, NULL, 0); 49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 5149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 52fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Creates a SkTArray by copying contents of a standard C array. The new 5349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * array will be heap allocated. Be careful not to use this constructor 5449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * when you really want the (void*, int) version. 5549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 5649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkTArray(const T* array, int count) { 5792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array, count, NULL, 0); 58ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 6049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 6149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * assign copy of array to this 6249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 6349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkTArray& operator =(const SkTArray& array) { 641c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < fCount; ++i) { 65ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fItemArray[i].~T(); 66ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 67ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount = 0; 68d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com this->checkRealloc((int)array.count()); 69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount = array.count(); 70918090c819109585f8fd2295039385a60eb0b572bungeman this->copy(static_cast<const T*>(array.fMemArray)); 71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return *this; 72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 74383ff1047f64192a8d7231a9e20d90126f85997dbsalomon ~SkTArray() { 751c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < fCount; ++i) { 76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fItemArray[i].~T(); 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fMemArray != fPreAllocMemArray) { 7949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com sk_free(fMemArray); 80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 8349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 8449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Resets to count() == 0 8549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 86d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com void reset() { this->pop_back_n(fCount); } 87d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 8849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 89b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org * Resets to count() = n newly constructed T objects. 90b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org */ 91b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org void reset(int n) { 92b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org SkASSERT(n >= 0); 93b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org for (int i = 0; i < fCount; ++i) { 94b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org fItemArray[i].~T(); 95b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org } 96b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org // set fCount to 0 before calling checkRealloc so that no copy cons. are called. 97b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org fCount = 0; 98b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(n); 99b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org fCount = n; 100b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org for (int i = 0; i < fCount; ++i) { 101385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (fItemArray + i) T; 102b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org } 103b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org } 104b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org 105b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org /** 106054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com * Resets to a copy of a C array. 107054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com */ 108054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com void reset(const T* array, int count) { 109054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com for (int i = 0; i < fCount; ++i) { 110054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com fItemArray[i].~T(); 111054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com } 112054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com int delta = count - fCount; 113054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com this->checkRealloc(delta); 114054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com fCount = count; 115918090c819109585f8fd2295039385a60eb0b572bungeman this->copy(array); 11695ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com } 11795ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com 11895ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com void removeShuffle(int n) { 11995ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com SkASSERT(n < fCount); 12095ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com int newCount = fCount - 1; 12195ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com fCount = newCount; 12295ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com fItemArray[n].~T(); 12395ebd17cf4f66952862289882ee5ac00da31cb8abungeman@google.com if (n != newCount) { 124918090c819109585f8fd2295039385a60eb0b572bungeman this->move(n, newCount); 125054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com } 126054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com } 127054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 128054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com /** 12949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Number of elements in the array. 13049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 1311c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int count() const { return fCount; } 132ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 13349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 13449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Is the array empty. 13549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 136ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bool empty() const { return !fCount; } 137ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 138a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com /** 139d58a856418ba3b3ecdc5e94629c911ec0034dfb1bungeman@google.com * Adds 1 new default-initialized T value and returns it by reference. Note 140a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * the reference only remains valid until the next call that adds or removes 141a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com * elements. 142a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com */ 143ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com T& push_back() { 144d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newT = reinterpret_cast<T*>(this->push_back_raw(1)); 145385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (newT) T; 146d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return *newT; 147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 149a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com /** 1504fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * Version of above that uses a copy constructor to initialize the new item 1514fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com */ 1524fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com T& push_back(const T& t) { 153d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newT = reinterpret_cast<T*>(this->push_back_raw(1)); 154385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (newT) T(t); 155d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return *newT; 1564fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 1574fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 1584fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com /** 159f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary * Construct a new T at the back of this array. 160f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary */ 161f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary template<class... Args> T& emplace_back(Args&&... args) { 162f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary T* newT = reinterpret_cast<T*>(this->push_back_raw(1)); 163221524de3be1fc343ad328c5e99562f32b5cad9cbungeman return *new (newT) T(std::forward<Args>(args)...); 164f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary } 165f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary 166f12a1673f024d30d30f06b9f88b5cc072b8a2d1ehalcanary /** 167d58a856418ba3b3ecdc5e94629c911ec0034dfb1bungeman@google.com * Allocates n more default-initialized T values, and returns the address of 168d58a856418ba3b3ecdc5e94629c911ec0034dfb1bungeman@google.com * the start of that new range. Note: this address is only valid until the 169d58a856418ba3b3ecdc5e94629c911ec0034dfb1bungeman@google.com * next API call made on the array that might add or remove elements. 170a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com */ 171a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com T* push_back_n(int n) { 17249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(n >= 0); 173d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newTs = reinterpret_cast<T*>(this->push_back_raw(n)); 1741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < n; ++i) { 175385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (newTs + i) T; 176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 177d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return newTs; 178ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 179ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 18049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 1814fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * Version of above that uses a copy constructor to initialize all n items 1824fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * to the same T. 1834fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com */ 1844fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com T* push_back_n(int n, const T& t) { 1854fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com SkASSERT(n >= 0); 186d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* newTs = reinterpret_cast<T*>(this->push_back_raw(n)); 1874fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com for (int i = 0; i < n; ++i) { 188385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (newTs[i]) T(t); 1894fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 190d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return newTs; 1914fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 1924fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 1934fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com /** 1944fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * Version of above that uses a copy constructor to initialize the n items 1954fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com * to separate T values. 1964fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com */ 1974fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com T* push_back_n(int n, const T t[]) { 1984fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com SkASSERT(n >= 0); 199b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(n); 2004fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com for (int i = 0; i < n; ++i) { 201385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (fItemArray + fCount + i) T(t[i]); 2024fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 2034fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com fCount += n; 2044fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com return fItemArray + fCount - n; 2054fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com } 2064fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 2074fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com /** 20849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Removes the last element. Not safe to call when count() == 0. 20949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void pop_back() { 21149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fCount > 0); 212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com --fCount; 213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fItemArray[fCount].~T(); 214b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(0); 215ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 216ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 21749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 21849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Removes the last n elements. Not safe to call when count() < n. 21949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2201c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com void pop_back_n(int n) { 22149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(n >= 0); 22249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fCount >= n); 223ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCount -= n; 2241c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com for (int i = 0; i < n; ++i) { 225d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fItemArray[fCount + i].~T(); 226ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 227b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->checkRealloc(0); 228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 23049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 23149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Pushes or pops from the back to resize. Pushes will be default 23249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * initialized. 23349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2341c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com void resize_back(int newCount) { 23549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(newCount >= 0); 2361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (newCount > fCount) { 238b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->push_back_n(newCount - fCount); 239ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else if (newCount < fCount) { 240b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org this->pop_back_n(fCount - newCount); 241ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 24423e619cf462b2a8a500f3ca750e099f79601f508bsalomon /** Swaps the contents of this array with that array. Does a pointer swap if possible, 24523e619cf462b2a8a500f3ca750e099f79601f508bsalomon otherwise copies the T values. */ 24623e619cf462b2a8a500f3ca750e099f79601f508bsalomon void swap(SkTArray* that) { 2473632f8473a7842b6f1351694d9b4071a66529224bsalomon if (this == that) { 2483632f8473a7842b6f1351694d9b4071a66529224bsalomon return; 2493632f8473a7842b6f1351694d9b4071a66529224bsalomon } 25023e619cf462b2a8a500f3ca750e099f79601f508bsalomon if (this->fPreAllocMemArray != this->fItemArray && 25123e619cf462b2a8a500f3ca750e099f79601f508bsalomon that->fPreAllocMemArray != that->fItemArray) { 25223e619cf462b2a8a500f3ca750e099f79601f508bsalomon // If neither is using a preallocated array then just swap. 25323e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkTSwap(fItemArray, that->fItemArray); 25423e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkTSwap(fCount, that->fCount); 25523e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkTSwap(fAllocCount, that->fAllocCount); 25623e619cf462b2a8a500f3ca750e099f79601f508bsalomon } else { 25723e619cf462b2a8a500f3ca750e099f79601f508bsalomon // This could be more optimal... 25823e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkTArray copy(*that); 25923e619cf462b2a8a500f3ca750e099f79601f508bsalomon *that = *this; 26023e619cf462b2a8a500f3ca750e099f79601f508bsalomon *this = copy; 26123e619cf462b2a8a500f3ca750e099f79601f508bsalomon } 26223e619cf462b2a8a500f3ca750e099f79601f508bsalomon } 26323e619cf462b2a8a500f3ca750e099f79601f508bsalomon 2649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com T* begin() { 2659b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray; 2669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com const T* begin() const { 2689b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray; 2699b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com T* end() { 2719b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com return fItemArray ? fItemArray + fCount : NULL; 2729b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2739b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com const T* end() const { 274567ff2f6143ecb993dbedede402a43feb71c420atfarina return fItemArray ? fItemArray + fCount : NULL; 2759b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com } 2769b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 2779b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com /** 27849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Get the i^th element. 27949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 2801c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com T& operator[] (int i) { 28149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 28249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 283ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[i]; 284ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 285ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2861c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com const T& operator[] (int i) const { 28749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 28849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 289ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[i]; 290ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 291ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 29249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 29349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * equivalent to operator[](0) 29449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 29549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com T& front() { SkASSERT(fCount > 0); return fItemArray[0];} 296ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 29749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com const T& front() const { SkASSERT(fCount > 0); return fItemArray[0];} 298ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 29949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 30049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * equivalent to operator[](count() - 1) 30149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 30249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com T& back() { SkASSERT(fCount); return fItemArray[fCount - 1];} 303ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 30449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com const T& back() const { SkASSERT(fCount > 0); return fItemArray[fCount - 1];} 305ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 30649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 30749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * equivalent to operator[](count()-1-i) 30849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 3091c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com T& fromBack(int i) { 31049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 31149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 312ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[fCount - i - 1]; 313ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 314ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3151c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com const T& fromBack(int i) const { 31649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i >= 0); 31749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(i < fCount); 318ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fItemArray[fCount - i - 1]; 319ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 320ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 321ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org bool operator==(const SkTArray<T, MEM_COPY>& right) const { 322ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org int leftCount = this->count(); 323ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (leftCount != right.count()) { 324ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return false; 325ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 326ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org for (int index = 0; index < leftCount; ++index) { 327ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (fItemArray[index] != right.fItemArray[index]) { 328ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return false; 329ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 330ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 331ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return true; 332ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 333ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 334ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org bool operator!=(const SkTArray<T, MEM_COPY>& right) const { 335ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return !(*this == right); 336ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 337ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 33892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprotected: 33992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com /** 34092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Creates an empty array that will use the passed storage block until it 34192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * is insufficiently large to hold the entire array. 34292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 34392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com template <int N> 34492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkTArray(SkAlignedSTStorage<N,T>* storage) { 34592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(NULL, 0, storage->get(), N); 34692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 34792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 34892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com /** 34992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Copy another array, using preallocated storage if preAllocCount >= 35092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * array.count(). Otherwise storage will only be used when array shrinks 35192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * to fit. 35292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 35392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com template <int N> 35492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkTArray(const SkTArray& array, SkAlignedSTStorage<N,T>* storage) { 35592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array.fItemArray, array.fCount, storage->get(), N); 35692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 35792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 35892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com /** 35992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Copy a C array, using preallocated storage if preAllocCount >= 36092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * count. Otherwise storage will only be used when array shrinks 36192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * to fit. 36292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 36392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com template <int N> 36492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) { 36592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com this->init(array, count, storage->get(), N); 36692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 36792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 36892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com void init(const T* array, int count, 36923e619cf462b2a8a500f3ca750e099f79601f508bsalomon void* preAllocStorage, int preAllocOrReserveCount) { 370d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org SkASSERT(count >= 0); 371d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org SkASSERT(preAllocOrReserveCount >= 0); 37292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fCount = count; 37392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fReserveCount = (preAllocOrReserveCount > 0) ? 37492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com preAllocOrReserveCount : 37592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com gMIN_ALLOC_COUNT; 37692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fPreAllocMemArray = preAllocStorage; 37792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com if (fReserveCount >= fCount && 37849f085dddff10473b6ebf832a974288300224e60bsalomon preAllocStorage) { 37992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fAllocCount = fReserveCount; 38092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com fMemArray = preAllocStorage; 38192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } else { 382d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org fAllocCount = SkMax32(fCount, fReserveCount); 383d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); 38492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 38592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 386918090c819109585f8fd2295039385a60eb0b572bungeman this->copy(array); 38792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 38892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 389ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comprivate: 390918090c819109585f8fd2295039385a60eb0b572bungeman /** In the following move and copy methods, 'dst' is assumed to be uninitialized raw storage. 391918090c819109585f8fd2295039385a60eb0b572bungeman * In the following move methods, 'src' is destroyed leaving behind uninitialized raw storage. 392918090c819109585f8fd2295039385a60eb0b572bungeman */ 393918090c819109585f8fd2295039385a60eb0b572bungeman template <bool E = MEM_COPY> SK_WHEN(E, void) copy(const T* src) { 394918090c819109585f8fd2295039385a60eb0b572bungeman sk_careful_memcpy(fMemArray, src, fCount * sizeof(T)); 395918090c819109585f8fd2295039385a60eb0b572bungeman } 396918090c819109585f8fd2295039385a60eb0b572bungeman template <bool E = MEM_COPY> SK_WHEN(E, void) move(int dst, int src) { 397918090c819109585f8fd2295039385a60eb0b572bungeman memcpy(&fItemArray[dst], &fItemArray[src], sizeof(T)); 398918090c819109585f8fd2295039385a60eb0b572bungeman } 399918090c819109585f8fd2295039385a60eb0b572bungeman template <bool E = MEM_COPY> SK_WHEN(E, void) move(char* dst) { 400918090c819109585f8fd2295039385a60eb0b572bungeman sk_careful_memcpy(dst, fMemArray, fCount * sizeof(T)); 401918090c819109585f8fd2295039385a60eb0b572bungeman } 402918090c819109585f8fd2295039385a60eb0b572bungeman 403918090c819109585f8fd2295039385a60eb0b572bungeman template <bool E = MEM_COPY> SK_WHEN(!E, void) copy(const T* src) { 404918090c819109585f8fd2295039385a60eb0b572bungeman for (int i = 0; i < fCount; ++i) { 405918090c819109585f8fd2295039385a60eb0b572bungeman new (fItemArray + i) T(src[i]); 406918090c819109585f8fd2295039385a60eb0b572bungeman } 407918090c819109585f8fd2295039385a60eb0b572bungeman } 408918090c819109585f8fd2295039385a60eb0b572bungeman template <bool E = MEM_COPY> SK_WHEN(!E, void) move(int dst, int src) { 409918090c819109585f8fd2295039385a60eb0b572bungeman new (&fItemArray[dst]) T(std::move(fItemArray[src])); 410918090c819109585f8fd2295039385a60eb0b572bungeman fItemArray[src].~T(); 411918090c819109585f8fd2295039385a60eb0b572bungeman } 412918090c819109585f8fd2295039385a60eb0b572bungeman template <bool E = MEM_COPY> SK_WHEN(!E, void) move(char* dst) { 413918090c819109585f8fd2295039385a60eb0b572bungeman for (int i = 0; i < fCount; ++i) { 414918090c819109585f8fd2295039385a60eb0b572bungeman new (dst + sizeof(T) * i) T(std::move(fItemArray[i])); 415918090c819109585f8fd2295039385a60eb0b572bungeman fItemArray[i].~T(); 416918090c819109585f8fd2295039385a60eb0b572bungeman } 417918090c819109585f8fd2295039385a60eb0b572bungeman } 418ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 41949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com static const int gMIN_ALLOC_COUNT = 8; 4201c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 421d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // Helper function that makes space for n objects, adjusts the count, but does not initialize 422d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com // the new objects. 423d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com void* push_back_raw(int n) { 424d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com this->checkRealloc(n); 425d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com void* ptr = fItemArray + fCount; 426d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fCount += n; 427d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com return ptr; 428d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 429d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 4301c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com inline void checkRealloc(int delta) { 43149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fCount >= 0); 43249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(fAllocCount >= 0); 4331c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 43449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkASSERT(-delta <= fCount); 435ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int newCount = fCount + delta; 437a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com int newAllocCount = fAllocCount; 438ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 439137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com if (newCount > fAllocCount || newCount < (fAllocCount / 3)) { 440137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com // whether we're growing or shrinking, we leave at least 50% extra space for future 441137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com // growth (clamped to the reserve count). 442137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com newAllocCount = SkMax32(newCount + ((newCount + 1) >> 1), fReserveCount); 443ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 444a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com if (newAllocCount != fAllocCount) { 445ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 446a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com fAllocCount = newAllocCount; 447a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com char* newMemArray; 448ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 44949f085dddff10473b6ebf832a974288300224e60bsalomon if (fAllocCount == fReserveCount && fPreAllocMemArray) { 450a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com newMemArray = (char*) fPreAllocMemArray; 451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 452a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T)); 453ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 454ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 455918090c819109585f8fd2295039385a60eb0b572bungeman this->move(newMemArray); 456ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 457ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fMemArray != fPreAllocMemArray) { 45849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com sk_free(fMemArray); 459ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 460a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com fMemArray = newMemArray; 461ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 462ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 463ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 46423e619cf462b2a8a500f3ca750e099f79601f508bsalomon int fReserveCount; 46523e619cf462b2a8a500f3ca750e099f79601f508bsalomon int fCount; 46623e619cf462b2a8a500f3ca750e099f79601f508bsalomon int fAllocCount; 46723e619cf462b2a8a500f3ca750e099f79601f508bsalomon void* fPreAllocMemArray; 468ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com union { 469ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com T* fItemArray; 470ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void* fMemArray; 471ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com }; 472ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 473ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 47492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com/** 47592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Subclass of SkTArray that contains a preallocated memory block for the array. 47692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */ 477f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.comtemplate <int N, typename T, bool MEM_COPY = false> 478f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.comclass SkSTArray : public SkTArray<T, MEM_COPY> { 47992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprivate: 480f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.com typedef SkTArray<T, MEM_COPY> INHERITED; 48192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 48292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.compublic: 48392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray() : INHERITED(&fStorage) { 48492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 48592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 48692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray(const SkSTArray& array) 48792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com : INHERITED(array, &fStorage) { 48892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 48992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 49092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com explicit SkSTArray(const INHERITED& array) 49192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com : INHERITED(array, &fStorage) { 49292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 49392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 4943390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org explicit SkSTArray(int reserveCount) 4953390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org : INHERITED(reserveCount) { 4963390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org } 4973390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org 49892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray(const T* array, int count) 49992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com : INHERITED(array, count, &fStorage) { 50092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 50192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 50292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray& operator= (const SkSTArray& array) { 50392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com return *this = *(const INHERITED*)&array; 50492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 50592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 50692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkSTArray& operator= (const INHERITED& array) { 50792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com INHERITED::operator=(array); 50892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com return *this; 50992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com } 51092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 51192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprivate: 51292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com SkAlignedSTStorage<N,T> fStorage; 51392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com}; 51492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com 515ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 516