1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkTArray_DEFINED 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkTArray_DEFINED 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "../private/SkTLogic.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "../private/SkTemplates.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypes.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <new> 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <utility> 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** When MEM_MOVE is true T will be bit copied when moved. 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot When MEM_MOVE is false, T will be copy constructed / destructed. 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot In all cases T will be default-initialized on allocation, 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot and its destructor will be called from this object's destructor. 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/ 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename T, bool MEM_MOVE = false> class SkTArray { 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Creates an empty array with no initial storage 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray() { this->init(); } 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Creates an empty array that will preallocate space for reserveCount 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * elements. 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SkTArray(int reserveCount) { this->init(0, reserveCount); } 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copies one array to another. The new array will be heap allocated. 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SkTArray(const SkTArray& that) { 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->init(that.fCount); 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->copy(that.fItemArray); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SkTArray(SkTArray&& that) { 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO: If 'that' owns its memory why don't we just steal the pointer? 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->init(that.fCount); 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that.move(fMemArray); 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that.fCount = 0; 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Creates a SkTArray by copying contents of a standard C array. The new 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * array will be heap allocated. Be careful not to use this constructor 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * when you really want the (void*, int) version. 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray(const T* array, int count) { 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->init(count); 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->copy(array); 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray& operator=(const SkTArray& that) { 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this == &that) { 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[i].~T(); 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = 0; 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(that.count()); 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = that.count(); 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->copy(that.fItemArray); 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray& operator=(SkTArray&& that) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this == &that) { 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[i].~T(); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = 0; 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(that.count()); 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = that.count(); 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that.move(fMemArray); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that.fCount = 0; 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ~SkTArray() { 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[i].~T(); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fOwnMemory) { 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_free(fMemArray); 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Resets to count() == 0 and resets any reserve count. 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void reset() { 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->pop_back_n(fCount); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Resets to count() = n newly constructed T objects and resets any reserve count. 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void reset(int n) { 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[i].~T(); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Set fCount to 0 before calling checkRealloc so that no elements are moved. 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = 0; 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(n); 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = n; 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (fItemArray + i) T; 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Resets to a copy of a C array and resets any reserve count. 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void reset(const T* array, int count) { 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[i].~T(); 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = 0; 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(count); 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = count; 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->copy(array); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Ensures there is enough reserved space for n additional elements. The is guaranteed at least 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * until the array size grows above n and subsequently shrinks below n, any version of reset() 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * is called, or reserve() is called again. 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void reserve(int n) { 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (n > 0) { 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(n); 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = fOwnMemory; 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void removeShuffle(int n) { 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n < fCount); 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int newCount = fCount - 1; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = newCount; 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[n].~T(); 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (n != newCount) { 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->move(n, newCount); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Number of elements in the array. 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count() const { return fCount; } 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Is the array empty. 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool empty() const { return !fCount; } 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Adds 1 new default-initialized T value and returns it by reference. Note 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the reference only remains valid until the next call that adds or removes 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * elements. 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& push_back() { 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newT = this->push_back_raw(1); 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *new (newT) T; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Version of above that uses a copy constructor to initialize the new item 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& push_back(const T& t) { 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newT = this->push_back_raw(1); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *new (newT) T(t); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Version of above that uses a move constructor to initialize the new item 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& push_back(T&& t) { 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newT = this->push_back_raw(1); 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *new (newT) T(std::move(t)); 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Construct a new T at the back of this array. 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template<class... Args> T& emplace_back(Args&&... args) { 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newT = this->push_back_raw(1); 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *new (newT) T(std::forward<Args>(args)...); 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Allocates n more default-initialized T values, and returns the address of 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the start of that new range. Note: this address is only valid until the 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * next API call made on the array that might add or remove elements. 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* push_back_n(int n) { 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newTs = this->push_back_raw(n); 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (static_cast<char*>(newTs) + i * sizeof(T)) T; 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return static_cast<T*>(newTs); 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Version of above that uses a copy constructor to initialize all n items 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * to the same T. 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* push_back_n(int n, const T& t) { 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newTs = this->push_back_raw(n); 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (static_cast<char*>(newTs) + i * sizeof(T)) T(t); 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return static_cast<T*>(newTs); 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Version of above that uses a copy constructor to initialize the n items 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * to separate T values. 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* push_back_n(int n, const T t[]) { 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(n); 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (fItemArray + fCount + i) T(t[i]); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount += n; 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray + fCount - n; 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Version of above that uses the move constructor to set n items. 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* move_back_n(int n, T* t) { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(n); 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (fItemArray + fCount + i) T(std::move(t[i])); 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount += n; 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray + fCount - n; 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Removes the last element. Not safe to call when count() == 0. 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void pop_back() { 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fCount > 0); 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --fCount; 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[fCount].~T(); 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(0); 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Removes the last n elements. Not safe to call when count() < n. 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void pop_back_n(int n) { 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(n >= 0); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fCount >= n); 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount -= n; 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[fCount + i].~T(); 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(0); 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Pushes or pops from the back to resize. Pushes will be default 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * initialized. 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void resize_back(int newCount) { 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(newCount >= 0); 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (newCount > fCount) { 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->push_back_n(newCount - fCount); 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (newCount < fCount) { 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->pop_back_n(fCount - newCount); 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** Swaps the contents of this array with that array. Does a pointer swap if possible, 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot otherwise copies the T values. */ 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void swap(SkTArray* that) { 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this == that) { 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fOwnMemory && that->fOwnMemory) { 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTSwap(fItemArray, that->fItemArray); 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTSwap(fCount, that->fCount); 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTSwap(fAllocCount, that->fAllocCount); 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This could be more optimal... 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray copy(std::move(*that)); 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *that = std::move(*this); 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *this = std::move(copy); 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* begin() { 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray; 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const T* begin() const { 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray; 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* end() { 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray ? fItemArray + fCount : nullptr; 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const T* end() const { 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray ? fItemArray + fCount : nullptr; 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Get the i^th element. 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& operator[] (int i) { 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i < fCount); 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i >= 0); 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray[i]; 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const T& operator[] (int i) const { 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i < fCount); 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i >= 0); 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray[i]; 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * equivalent to operator[](0) 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& front() { SkASSERT(fCount > 0); return fItemArray[0];} 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const T& front() const { SkASSERT(fCount > 0); return fItemArray[0];} 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * equivalent to operator[](count() - 1) 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& back() { SkASSERT(fCount); return fItemArray[fCount - 1];} 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const T& back() const { SkASSERT(fCount > 0); return fItemArray[fCount - 1];} 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * equivalent to operator[](count()-1-i) 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T& fromBack(int i) { 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i >= 0); 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i < fCount); 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray[fCount - i - 1]; 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const T& fromBack(int i) const { 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i >= 0); 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(i < fCount); 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fItemArray[fCount - i - 1]; 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool operator==(const SkTArray<T, MEM_MOVE>& right) const { 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int leftCount = this->count(); 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (leftCount != right.count()) { 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int index = 0; index < leftCount; ++index) { 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fItemArray[index] != right.fItemArray[index]) { 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool operator!=(const SkTArray<T, MEM_MOVE>& right) const { 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return !(*this == right); 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot inline int allocCntForTest() const; 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Creates an empty array that will use the passed storage block until it 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * is insufficiently large to hold the entire array. 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <int N> 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray(SkAlignedSTStorage<N,T>* storage) { 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->initWithPreallocatedStorage(0, storage->get(), N); 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copy another array, using preallocated storage if preAllocCount >= 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * array.count(). Otherwise storage will only be used when array shrinks 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * to fit. 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <int N> 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray(const SkTArray& array, SkAlignedSTStorage<N,T>* storage) { 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->initWithPreallocatedStorage(array.fCount, storage->get(), N); 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->copy(array.fItemArray); 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Move another array, using preallocated storage if preAllocCount >= 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * array.count(). Otherwise storage will only be used when array shrinks 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * to fit. 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <int N> 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray(SkTArray&& array, SkAlignedSTStorage<N,T>* storage) { 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->initWithPreallocatedStorage(array.fCount, storage->get(), N); 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot array.move(fMemArray); 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot array.fCount = 0; 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copy a C array, using preallocated storage if preAllocCount >= 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * count. Otherwise storage will only be used when array shrinks 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * to fit. 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <int N> 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) { 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->initWithPreallocatedStorage(count, storage->get(), N); 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->copy(array); 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void init(int count = 0, int reserveCount = 0) { 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(count >= 0); 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(reserveCount >= 0); 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = count; 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!count && !reserveCount) { 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllocCount = 0; 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMemArray = nullptr; 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOwnMemory = true; 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllocCount = SkTMax(count, SkTMax(kMinHeapAllocCount, reserveCount)); 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMemArray = sk_malloc_throw(fAllocCount, sizeof(T)); 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOwnMemory = true; 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = reserveCount > 0; 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void initWithPreallocatedStorage(int count, void* preallocStorage, int preallocCount) { 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(count >= 0); 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(preallocCount > 0); 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(preallocStorage); 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount = count; 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMemArray = nullptr; 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (count > preallocCount) { 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllocCount = SkTMax(count, kMinHeapAllocCount); 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMemArray = sk_malloc_throw(fAllocCount, sizeof(T)); 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOwnMemory = true; 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllocCount = preallocCount; 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMemArray = preallocStorage; 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOwnMemory = false; 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** In the following move and copy methods, 'dst' is assumed to be uninitialized raw storage. 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * In the following move methods, 'src' is destroyed leaving behind uninitialized raw storage. 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void copy(const T* src) { 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Some types may be trivially copyable, in which case we *could* use memcopy; but 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // MEM_MOVE == true implies that the type is trivially movable, and not necessarily 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // trivially copyable (think sk_sp<>). So short of adding another template arg, we 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // must be conservative and use copy construction. 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (fItemArray + i) T(src[i]); 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <bool E = MEM_MOVE> SK_WHEN(E, void) move(int dst, int src) { 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memcpy(&fItemArray[dst], &fItemArray[src], sizeof(T)); 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <bool E = MEM_MOVE> SK_WHEN(E, void) move(void* dst) { 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_careful_memcpy(dst, fMemArray, fCount * sizeof(T)); 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <bool E = MEM_MOVE> SK_WHEN(!E, void) move(int dst, int src) { 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (&fItemArray[dst]) T(std::move(fItemArray[src])); 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[src].~T(); 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot template <bool E = MEM_MOVE> SK_WHEN(!E, void) move(void* dst) { 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fCount; ++i) { 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (static_cast<char*>(dst) + sizeof(T) * i) T(std::move(fItemArray[i])); 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fItemArray[i].~T(); 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr int kMinHeapAllocCount = 8; 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Helper function that makes space for n objects, adjusts the count, but does not initialize 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the new objects. 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* push_back_raw(int n) { 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->checkRealloc(n); 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* ptr = fItemArray + fCount; 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCount += n; 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return ptr; 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void checkRealloc(int delta) { 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fCount >= 0); 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fAllocCount >= 0); 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(-delta <= fCount); 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int newCount = fCount + delta; 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We allow fAllocCount to be in the range [newCount, 3*newCount]. We also never shrink 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // when we're currently using preallocated memory, would allocate less than 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // kMinHeapAllocCount, or a reserve count was specified that has yet to be exceeded. 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool mustGrow = newCount > fAllocCount; 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool shouldShrink = fAllocCount > 3 * newCount && fOwnMemory && !fReserved; 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!mustGrow && !shouldShrink) { 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Whether we're growing or shrinking, we leave at least 50% extra space for future growth. 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int newAllocCount = newCount + ((newCount + 1) >> 1); 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Align the new allocation count to kMinHeapAllocCount. 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_assert(SkIsPow2(kMinHeapAllocCount), "min alloc count not power of two."); 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newAllocCount = (newAllocCount + (kMinHeapAllocCount - 1)) & ~(kMinHeapAllocCount - 1); 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // At small sizes the old and new alloc count can both be kMinHeapAllocCount. 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (newAllocCount == fAllocCount) { 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllocCount = newAllocCount; 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* newMemArray = sk_malloc_throw(fAllocCount, sizeof(T)); 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->move(newMemArray); 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fOwnMemory) { 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_free(fMemArray); 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMemArray = newMemArray; 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOwnMemory = true; 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fReserved = false; 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot union { 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot T* fItemArray; 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* fMemArray; 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fCount; 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fAllocCount; 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fOwnMemory : 1; 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fReserved : 1; 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate<typename T, bool MEM_MOVE> constexpr int SkTArray<T, MEM_MOVE>::kMinHeapAllocCount; 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Subclass of SkTArray that contains a preallocated memory block for the array. 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <int N, typename T, bool MEM_MOVE= false> 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkSTArray : public SkTArray<T, MEM_MOVE> { 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef SkTArray<T, MEM_MOVE> INHERITED; 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray() : INHERITED(&fStorage) { 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray(const SkSTArray& array) 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(array, &fStorage) { 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray(SkSTArray&& array) 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(std::move(array), &fStorage) { 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SkSTArray(const INHERITED& array) 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(array, &fStorage) { 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SkSTArray(INHERITED&& array) 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(std::move(array), &fStorage) { 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SkSTArray(int reserveCount) 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(reserveCount) { 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray(const T* array, int count) 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(array, count, &fStorage) { 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray& operator=(const SkSTArray& array) { 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot INHERITED::operator=(array); 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray& operator=(SkSTArray&& array) { 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot INHERITED::operator=(std::move(array)); 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray& operator=(const INHERITED& array) { 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot INHERITED::operator=(array); 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray& operator=(INHERITED&& array) { 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot INHERITED::operator=(std::move(array)); 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return *this; 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAlignedSTStorage<N,T> fStorage; 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 624