SkTArray.h revision b4a8d97b4c68896da363e7f365354ab8ddbb7fc1
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
44a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com/** When MEM_COPY is true T will be bit copied when moved.
45a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com    When MEM_COPY is false, T will be copy constructed / destructed.
46a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com    In all cases T's constructor will be called on allocation,
47a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com    and its destructor will be called from this object's destructor.
48a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com*/
49a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.comtemplate <typename T, bool MEM_COPY> class SkTArray {
50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.compublic:
5149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
5249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Creates an empty array with no initial storage
5349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
5449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    SkTArray() {
55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fCount = 0;
5649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        fReserveCount = gMIN_ALLOC_COUNT;
57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fAllocCount = 0;
58ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fMemArray = NULL;
59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fPreAllocMemArray = NULL;
60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
6249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
63fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Creates an empty array that will preallocate space for reserveCount
6449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * elements.
6549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
6649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    explicit SkTArray(int reserveCount) {
6792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        this->init(NULL, 0, NULL, reserveCount);
68ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
69fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
7149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Copies one array to another. The new array will be heap allocated.
7249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
7349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    explicit SkTArray(const SkTArray& array) {
7492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        this->init(array.fItemArray, array.fCount, NULL, 0);
75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
7749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
78fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Creates a SkTArray by copying contents of a standard C array. The new
7949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * array will be heap allocated. Be careful not to use this constructor
8049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * when you really want the (void*, int) version.
8149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
8249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    SkTArray(const T* array, int count) {
8392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        this->init(array, count, NULL, 0);
84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
8649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
8749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * assign copy of array to this
8849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
8949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    SkTArray& operator =(const SkTArray& array) {
901c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        for (int i = 0; i < fCount; ++i) {
91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            fItemArray[i].~T();
92ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fCount = 0;
94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        checkRealloc((int)array.count());
95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fCount = array.count();
96a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com        SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray));
97ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return *this;
98ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
99ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
10092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    virtual ~SkTArray() {
1011c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        for (int i = 0; i < fCount; ++i) {
102ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            fItemArray[i].~T();
103ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (fMemArray != fPreAllocMemArray) {
10549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com            sk_free(fMemArray);
106ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
107ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
108ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
10949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
11049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Resets to count() == 0
11149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
112d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    void reset() { this->pop_back_n(fCount); }
113d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
11449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
115b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org     * Resets to count() = n newly constructed T objects.
116b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org     */
117b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org    void reset(int n) {
118b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        SkASSERT(n >= 0);
119b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        for (int i = 0; i < fCount; ++i) {
120b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            fItemArray[i].~T();
121b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        }
122b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        // set fCount to 0 before calling checkRealloc so that no copy cons. are called.
123b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        fCount = 0;
124b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(n);
125b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        fCount = n;
126b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        for (int i = 0; i < fCount; ++i) {
127b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            SkNEW_PLACEMENT(fItemArray + i, T);
128b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        }
129b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org    }
130b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org
131b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org    /**
132054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * Resets to a copy of a C array.
133054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     */
134054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    void reset(const T* array, int count) {
135054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        for (int i = 0; i < fCount; ++i) {
136054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com            fItemArray[i].~T();
137054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        }
138054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        int delta = count - fCount;
139054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        this->checkRealloc(delta);
140054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        fCount = count;
141054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        for (int i = 0; i < count; ++i) {
142054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com            SkTArrayExt::copy(this, array);
143054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        }
144054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
145054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com
146054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    /**
14749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Number of elements in the array.
14849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
1491c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    int count() const { return fCount; }
150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
15149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
15249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Is the array empty.
15349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    bool empty() const { return !fCount; }
155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
156a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com    /**
157a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com     * Adds 1 new default-constructed T value and returns in by reference. Note
158a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com     * the reference only remains valid until the next call that adds or removes
159a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com     * elements.
160a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com     */
161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    T& push_back() {
162b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(1);
163b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        SkNEW_PLACEMENT((char*)fMemArray + sizeof(T) * fCount, T);
164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        ++fCount;
165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return fItemArray[fCount-1];
166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
168a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com    /**
1694fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     * Version of above that uses a copy constructor to initialize the new item
1704fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     */
1714fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com    T& push_back(const T& t) {
172b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(1);
173b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        SkNEW_PLACEMENT_ARGS((char*)fMemArray + sizeof(T) * fCount, T, (t));
1744fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        ++fCount;
1754fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        return fItemArray[fCount-1];
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);
185b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(n);
1861c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        for (int i = 0; i < n; ++i) {
187b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            SkNEW_PLACEMENT(fItemArray + fCount + i, T);
188ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
189ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fCount += n;
190a996fec40444e8b914cd84c17037f0c84301f717bsalomon@google.com        return fItemArray + fCount - n;
191ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
19349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
1944fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     * Version of above that uses a copy constructor to initialize all n items
1954fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     * to the same T.
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) {
201b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t));
2024fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        }
2034fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        fCount += n;
2044fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        return fItemArray + fCount - n;
2054fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com    }
2064fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com
2074fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com    /**
2084fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     * Version of above that uses a copy constructor to initialize the n items
2094fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     * to separate T values.
2104fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com     */
2114fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com    T* push_back_n(int n, const T t[]) {
2124fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        SkASSERT(n >= 0);
213b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(n);
2144fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        for (int i = 0; i < n; ++i) {
215b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t[i]));
2164fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        }
2174fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        fCount += n;
2184fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com        return fItemArray + fCount - n;
2194fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com    }
2204fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com
2214fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com    /**
22249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Removes the last element. Not safe to call when count() == 0.
22349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
224ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    void pop_back() {
22549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(fCount > 0);
226ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        --fCount;
227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fItemArray[fCount].~T();
228b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(0);
229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
230ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
23149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
23249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Removes the last n elements. Not safe to call when count() < n.
23349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
2341c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    void pop_back_n(int n) {
23549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(n >= 0);
23649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(fCount >= n);
237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fCount -= n;
2381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        for (int i = 0; i < n; ++i) {
239ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            fItemArray[i].~T();
240ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
241b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org        this->checkRealloc(0);
242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
24449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
24549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Pushes or pops from the back to resize. Pushes will be default
24649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * initialized.
24749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
2481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    void resize_back(int newCount) {
24949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(newCount >= 0);
2501c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (newCount > fCount) {
252b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            this->push_back_n(newCount - fCount);
253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else if (newCount < fCount) {
254b4a8d97b4c68896da363e7f365354ab8ddbb7fc1commit-bot@chromium.org            this->pop_back_n(fCount - newCount);
255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
256ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
257ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2589b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    T* begin() {
2599b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        return fItemArray;
2609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    }
2619b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    const T* begin() const {
2629b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        return fItemArray;
2639b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    }
2649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    T* end() {
2659b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        return fItemArray ? fItemArray + fCount : NULL;
2669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    }
2679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    const T* end() const {
2689b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        return fItemArray ? fItemArray + fCount : NULL;;
2699b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    }
2709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2719b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com   /**
27249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * Get the i^th element.
27349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
2741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    T& operator[] (int i) {
27549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(i < fCount);
27649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(i >= 0);
277ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return fItemArray[i];
278ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
279ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2801c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    const T& operator[] (int i) const {
28149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(i < fCount);
28249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(i >= 0);
283ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return fItemArray[i];
284ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
285ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
28649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
28749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * equivalent to operator[](0)
28849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
28949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    T& front() { SkASSERT(fCount > 0); return fItemArray[0];}
290ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
29149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    const T& front() const { SkASSERT(fCount > 0); return fItemArray[0];}
292ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
29349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
29449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * equivalent to operator[](count() - 1)
29549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
29649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    T& back() { SkASSERT(fCount); return fItemArray[fCount - 1];}
297ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
29849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    const T& back() const { SkASSERT(fCount > 0); return fItemArray[fCount - 1];}
299ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
30049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    /**
30149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     * equivalent to operator[](count()-1-i)
30249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com     */
3031c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    T& fromBack(int i) {
30449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(i >= 0);
30549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(i < fCount);
306ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return fItemArray[fCount - i - 1];
307ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
308ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3091c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    const T& fromBack(int i) const {
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
315ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    bool operator==(const SkTArray<T, MEM_COPY>& right) const {
316ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        int leftCount = this->count();
317ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        if (leftCount != right.count()) {
318ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org            return false;
319ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        }
320ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        for (int index = 0; index < leftCount; ++index) {
321ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org            if (fItemArray[index] != right.fItemArray[index]) {
322ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org                return false;
323ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org            }
324ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        }
325ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        return true;
326ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    }
327ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
328ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    bool operator!=(const SkTArray<T, MEM_COPY>& right) const {
329ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        return !(*this == right);
330ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    }
331ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
33292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprotected:
33392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    /**
33492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * Creates an empty array that will use the passed storage block until it
33592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * is insufficiently large to hold the entire array.
33692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     */
33792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    template <int N>
33892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkTArray(SkAlignedSTStorage<N,T>* storage) {
33992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        this->init(NULL, 0, storage->get(), N);
34092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
34192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
34292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    /**
34392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * Copy another array, using preallocated storage if preAllocCount >=
34492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * array.count(). Otherwise storage will only be used when array shrinks
34592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * to fit.
34692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     */
34792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    template <int N>
34892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkTArray(const SkTArray& array, SkAlignedSTStorage<N,T>* storage) {
34992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        this->init(array.fItemArray, array.fCount, storage->get(), N);
35092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
35192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
35292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    /**
35392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * Copy a C array, using preallocated storage if preAllocCount >=
35492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * count. Otherwise storage will only be used when array shrinks
35592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     * to fit.
35692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com     */
35792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    template <int N>
35892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) {
35992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        this->init(array, count, storage->get(), N);
36092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
36192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
36292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    void init(const T* array, int count,
36392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com               void* preAllocStorage, int preAllocOrReserveCount) {
364d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org        SkASSERT(count >= 0);
365d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org        SkASSERT(preAllocOrReserveCount >= 0);
36692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        fCount              = count;
36792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        fReserveCount       = (preAllocOrReserveCount > 0) ?
36892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com                                    preAllocOrReserveCount :
36992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com                                    gMIN_ALLOC_COUNT;
37092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        fPreAllocMemArray   = preAllocStorage;
37192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        if (fReserveCount >= fCount &&
37292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com            NULL != preAllocStorage) {
37392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com            fAllocCount = fReserveCount;
37492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com            fMemArray = preAllocStorage;
37592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        } else {
376d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org            fAllocCount = SkMax32(fCount, fReserveCount);
377d80a509eb773cdca6c7a9d3af4ac44a6dd24c567junov@chromium.org            fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
37892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        }
37992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
380a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com        SkTArrayExt::copy(this, array);
38192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
38292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
383ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comprivate:
384ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
38549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com    static const int gMIN_ALLOC_COUNT = 8;
3861c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
3871c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    inline void checkRealloc(int delta) {
38849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(fCount >= 0);
38949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(fAllocCount >= 0);
3901c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
39149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com        SkASSERT(-delta <= fCount);
392ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3931c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int newCount = fCount + delta;
394a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com        int newAllocCount = fAllocCount;
395ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
396137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com        if (newCount > fAllocCount || newCount < (fAllocCount / 3)) {
397137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com            // whether we're growing or shrinking, we leave at least 50% extra space for future
398137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com            // growth (clamped to the reserve count).
399137209f9f4b6ee08ca59a135909185cb0caf6d91bsalomon@google.com            newAllocCount = SkMax32(newCount + ((newCount + 1) >> 1), fReserveCount);
400ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
401a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com        if (newAllocCount != fAllocCount) {
402ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
403a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com            fAllocCount = newAllocCount;
404a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com            char* newMemArray;
405ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
406ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) {
407a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com                newMemArray = (char*) fPreAllocMemArray;
408ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            } else {
409a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com                newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T));
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            }
411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
412a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com            SkTArrayExt::copyAndDelete<T>(this, newMemArray);
413ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
414ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            if (fMemArray != fPreAllocMemArray) {
41549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com                sk_free(fMemArray);
416ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            }
417a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com            fMemArray = newMemArray;
418ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
419ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
420ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
421cf385232c45b7692eaf31260fe650457f400521abungeman@google.com    template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*);
422cf385232c45b7692eaf31260fe650457f400521abungeman@google.com    template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true>* that, char*);
423a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com
424cf385232c45b7692eaf31260fe650457f400521abungeman@google.com    template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*);
425cf385232c45b7692eaf31260fe650457f400521abungeman@google.com    template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, false>* that, char*);
426a12cc7fda00236549961d7b8e2d708cfe3cfa4e6bungeman@google.com
4271c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    int fReserveCount;
4281c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    int fCount;
4291c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    int fAllocCount;
430ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    void*    fPreAllocMemArray;
431ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    union {
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        T*       fItemArray;
433ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        void*    fMemArray;
434ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    };
435ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com};
436ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
43792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com/**
43892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com * Subclass of SkTArray that contains a preallocated memory block for the array.
43992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com */
440f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.comtemplate <int N, typename T, bool MEM_COPY = false>
441f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.comclass SkSTArray : public SkTArray<T, MEM_COPY> {
44292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprivate:
443f47dd74da3c7454af46aa0abe052d3fc6f02b9b2bsalomon@google.com    typedef SkTArray<T, MEM_COPY> INHERITED;
44492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
44592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.compublic:
44692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkSTArray() : INHERITED(&fStorage) {
44792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
44892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
44992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkSTArray(const SkSTArray& array)
45092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        : INHERITED(array, &fStorage) {
45192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
45292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
45392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    explicit SkSTArray(const INHERITED& array)
45492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        : INHERITED(array, &fStorage) {
45592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
45692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
45792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkSTArray(const T* array, int count)
45892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        : INHERITED(array, count, &fStorage) {
45992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
46092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
46192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkSTArray& operator= (const SkSTArray& array) {
46292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        return *this = *(const INHERITED*)&array;
46392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
46492669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
46592669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkSTArray& operator= (const INHERITED& array) {
46692669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        INHERITED::operator=(array);
46792669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com        return *this;
46892669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    }
46992669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
47092669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.comprivate:
47192669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com    SkAlignedSTStorage<N,T> fStorage;
47292669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com};
47392669014aa7ab821cdc09cc9ad610316eb16b490bsalomon@google.com
474ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
475