1d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// Copyright 2014 The Android Open Source Project 2d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 3d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// This software is licensed under the terms of the GNU General Public 4d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// License version 2, as published by the Free Software Foundation, and 5d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// may be copied, distributed, and modified under those terms. 6d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 7d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// This program is distributed in the hope that it will be useful, 8d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of 9d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// GNU General Public License for more details. 11d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 12d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#ifndef ANDROID_BASE_CONTAINERS_POD_VECTOR_H 13d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#define ANDROID_BASE_CONTAINERS_POD_VECTOR_H 14d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 15d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#include <android/base/Limits.h> 16d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#include <android/base/Log.h> 17d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 18d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#include <stddef.h> 19d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#include <stdint.h> 20d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 21d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnernamespace android { 22d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnernamespace base { 23d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 24d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// A PodVector is a templated vector-like type that is used to store 25d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// POD-struct compatible items only. This allows the implementation to 26d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// use ::memmove() to move items, and also malloc_usable_size() to 27d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// determine the best capacity. 28d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 29d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// std::vector<> is capable of doing this in theory, using horrible 30d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// templating tricks that make error messages very difficult to 31d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// understand. 32d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 33d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// Note that a PodVector can be used to store items that contain pointers, 34d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// as long as these do not point to items in the same container. 35d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 36d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// The PodVector provides methods that also follow the std::vector<> 37d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// conventions, i.e. push_back() is an alias for append(). 38d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 39d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 40d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// PodVectorBase is a base, non-templated, implementation class that all 41d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// PodVector instances derive from. This is used to reduce template 42d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// specialization. Do not use directly, i..e it's an implementation detail. 43d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerclass PodVectorBase { 44d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerprotected: 45d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase() : mBegin(NULL), mEnd(NULL), mLimit(NULL) {} 46d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner explicit PodVectorBase(const PodVectorBase& other); 47d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase& operator=(const PodVectorBase& other); 48d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner ~PodVectorBase(); 49d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 50d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner bool empty() const { return mEnd == mBegin; } 51d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 52d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner size_t byteSize() const { return mEnd - mBegin; } 53d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 54d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner size_t byteCapacity() const { return mLimit - mBegin; } 55d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 56d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void* begin() { return mBegin; } 57d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const void* begin() const { return mBegin; } 58d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void* end() { return mEnd; } 59d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const void* end() const { return mEnd; } 60d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 61d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void* itemAt(size_t pos, size_t itemSize) { 62d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const size_t kMaxCapacity = SIZE_MAX / itemSize; 63d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner DCHECK(pos <= kMaxCapacity); 64d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return mBegin + pos * itemSize; 65d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 66d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 67d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const void* itemAt(size_t pos, size_t itemSize) const { 68d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const size_t kMaxCapacity = SIZE_MAX / itemSize; 69d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner DCHECK(pos <= kMaxCapacity); 70d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return mBegin + pos * itemSize; 71d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 72d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 73d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void assignFrom(const PodVectorBase& other); 74d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 75d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner inline size_t itemCount(size_t itemSize) const { 76d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner DCHECK(itemSize > 0) << "Item size cannot be 0!"; 77d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return byteSize() / itemSize; 78d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 79d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 80d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner inline size_t itemCapacity(size_t itemSize) const { 81d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner DCHECK(itemSize > 0) << "Item size cannot be 0!"; 82d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return byteCapacity() / itemSize; 83d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 84d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 85d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner inline size_t maxItemCapacity(size_t itemSize) const { 86d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner DCHECK(itemSize > 0) << "Item size cannot be 0!"; 87d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return SIZE_MAX / itemSize; 88d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 89d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 90d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void resize(size_t newSize, size_t itemSize); 91d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void reserve(size_t newSize, size_t itemSize); 92d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 93d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void removeAt(size_t index, size_t itemSize); 94d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void* insertAt(size_t index, size_t itemSize); 95d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void swapAll(PodVectorBase* other); 96d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 97d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner char* mBegin; 98d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner char* mEnd; 99d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner char* mLimit; 100d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 101d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerprivate: 102d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void initFrom(const void* from, size_t fromLen); 103d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner}; 104d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 105d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 106d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// A PodVector<T> holds a vector (dynamically resizable array) or items 107d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// that must be POD-struct compatible (i.e. they cannot have constructors, 108d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// destructors, or virtual members). This allows the implementation to be 109d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// small, fast and efficient, memory-wise. 110d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 111d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// If you want to implement a vector of C++ objects, consider using 112d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// std::vector<> instead, but keep in mind that this implies a non-trivial 113d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// cost when appending, inserting, removing items in the collection. 114d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// 115d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnertemplate <typename T> 116d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerclass PodVector : public PodVectorBase { 117d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerpublic: 118d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Default constructor for an empty PodVector<T> 119d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVector() : PodVectorBase() {} 120d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 121d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Copy constructor. This copies all items from |other| into 122d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // the new instance with ::memmove(). 123d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVector(const PodVector& other) : PodVectorBase(other) {} 124d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 125d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Assignment operator. 126d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVector& operator=(const PodVector& other) { 127d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner this->assignFrom(other); 128d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return *this; 129d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 130d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 131d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Destructor, this simply releases the internal storage block that 132d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // holds all the items, but doesn't touch them otherwise. 133d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner ~PodVector() {} 134d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 135d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return true iff the PodVector<T> instance is empty, i.e. does not 136d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // have any items. 137d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner bool empty() const { return PodVectorBase::empty(); } 138d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 139d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return the number of items in the current PodVector<T> instance. 140d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner size_t size() const { return PodVectorBase::itemCount(sizeof(T)); } 141d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 142d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return the current capacity in the current PodVector<T> instance. 143d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Do not use directly, except if you know what you're doing. Try to 144d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // use resize() or reserve() instead. 145d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner size_t capacity() const { 146d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return PodVectorBase::itemCapacity(sizeof(T)); 147d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 148d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 149d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return the maximum capacity of any PodVector<T> instance. 150d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner static inline size_t maxCapacity() { return SIZE_MAX / sizeof(T); } 151d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 152d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Resize the vector to ensure it can hold |newSize| 153d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // items. This may or may not call reserve() under the hood. 154d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // It's a fatal error to try to resize above maxCapacity(). 155d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void resize(size_t newSize) { 156d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::resize(newSize, sizeof(T)); 157d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 158d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 159d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Resize the vector's storage array to ensure that it can hold at 160d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // least |newSize| items. It's a fatal error to try to resize above 161d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // maxCapacity(). 162d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void reserve(size_t newSize) { 163d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::reserve(newSize, sizeof(T)); 164d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 165d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 166d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return a pointer to the first item in the vector. This is only 167d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // valid until the next call to any function that changes the size 168d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // or capacity of the vector. Can be NULL if the vector is empty. 169d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner T* begin() { 170d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return reinterpret_cast<T*>(PodVectorBase::begin()); 171d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 172d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 173d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return a constant pointer to the first item in the vector. This is 174d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // only valid until the next call to any function that changes the 175d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // size of capacity of the vector. 176d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const T* begin() const { 177d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return reinterpret_cast<T*>(PodVectorBase::begin()); 178d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 179d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 180d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return a pointer past the last item in the vector. I.e. if the 181d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // result is not NULL, then |result - 1| points to the last item. 182d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Can be NULL if the vector is empty. 183d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner T* end() { 184d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return reinterpret_cast<T*>(PodVectorBase::end()); 185d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 186d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 187d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Return a constant pointer past the last item in the vector. I.e. if 188d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // the result is not NULL, then |result - 1| points to the last item. 189d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Can be NULL if the vector is empty. 190d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const T* end() const { 191d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return reinterpret_cast<T*>(PodVectorBase::end()); 192d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 193d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 194d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Returns a reference to the item a position |index| in the vector. 195d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // It may be a fatal error to access an out-of-bounds position. 196d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner T& operator[](size_t index) { 197d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return *reinterpret_cast<T*>( 198d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::itemAt(index, sizeof(T))); 199d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 200d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 201d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner const T& operator[](size_t index) const { 202d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return *reinterpret_cast<const T*>( 203d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::itemAt(index, sizeof(T))); 204d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 205d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 206d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Increase the vector's size by 1, then move all items past a given 207d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // position to the right. Return the position of the insertion point 208d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // to let the caller copy the content it desires there. It's preferrable 209d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // to use insert() directly, which will do the item copy for you. 210d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner T* emplace(size_t index) { 211d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner return reinterpret_cast<T*>( 212d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::insertAt(index, sizeof(T))); 213d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 214d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 215d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Insert an item at a given position. |index| is the insertion position 216d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // which must be between 0 and size() included, or a fatal error may 217d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // occur. |item| is a reference to an item to copy into the array, 218d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // byte-by-byte. 219d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void insert(size_t index, const T& item) { 220d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner *(this->emplace(index)) = item; 221d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 222d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 223d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Prepend an item at the start of a vector. This moves all vector items 224d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // to the right, and is thus costly. |item| is a reference to an item 225d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // to copy to the start of the vector. 226d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void prepend(const T& item) { 227d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner *(this->emplace(0U)) = item; 228d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 229d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 230d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Append an item at the end of a vector. Specialized version of insert() 231d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // which always uses size() as the insertion position. 232d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void append(const T& item) { 233d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner *(this->emplace(this->size())) = item; 234d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 235d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 236d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Remove the item at a given position. |index| is the position of the 237d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // item to delete. It must be between 0 and size(), included, or 238d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // a fatal error may occur. Deleting the item at position size() 239d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // doesn't do anything. 240d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void remove(size_t index) { 241d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::removeAt(index, sizeof(T)); 242d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 243d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 244d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void swap(PodVector* other) { 245d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner PodVectorBase::swapAll(other); 246d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner } 247d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 248d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner // Compatibility methods for std::vector<> 249d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void push_back(const T& item) { append(item); } 250d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner void pop() { remove(0U); } 251d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 252d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner typedef T* iterator; 253d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner typedef const T* const_iterator; 254d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner}; 255d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 256d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner} // namespace base 257d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner} // namespace android 258d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 259d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner 260d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#endif // ANDROID_BASE_VECTOR_H 261