1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkTemplates_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkTemplates_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h" 14562b2e67a29f24db4c258aa2fa59cd7b4ee15174bungeman@google.com#include <limits.h> 157103f182ce61280eacb35f1832df350b642a5381bungeman@google.com#include <new> 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \file SkTemplates.h 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This file contains light-weight template classes for type-safe and exception-safe 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com resource management. 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2391208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com/** 247de18e5c7b4e4a8ad8910b1016688ded902f185bbungeman@google.com * Marks a local variable as known to be unused (to avoid warnings). 257de18e5c7b4e4a8ad8910b1016688ded902f185bbungeman@google.com * Note that this does *not* prevent the local variable from being optimized away. 267de18e5c7b4e4a8ad8910b1016688ded902f185bbungeman@google.com */ 277de18e5c7b4e4a8ad8910b1016688ded902f185bbungeman@google.comtemplate<typename T> inline void sk_ignore_unused_variable(const T&) { } 287de18e5c7b4e4a8ad8910b1016688ded902f185bbungeman@google.com 297de18e5c7b4e4a8ad8910b1016688ded902f185bbungeman@google.com/** 3091208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com * SkTIsConst<T>::value is true if the type T is const. 3191208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com * The type T is constrained not to be an array or reference type. 3291208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com */ 3391208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.comtemplate <typename T> struct SkTIsConst { 3491208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com static T* t; 3591208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com static uint16_t test(const volatile void*); 3691208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com static uint32_t test(volatile void *); 3791208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com static const bool value = (sizeof(uint16_t) == sizeof(test(t))); 3891208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com}; 3991208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com 4091208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com///@{ 4191208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com/** SkTConstType<T, CONST>::type will be 'const T' if CONST is true, 'T' otherwise. */ 4291208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.comtemplate <typename T, bool CONST> struct SkTConstType { 4391208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com typedef T type; 4491208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com}; 4591208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.comtemplate <typename T> struct SkTConstType<T, true> { 4691208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com typedef const T type; 4791208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com}; 4891208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com///@} 4991208922687a33df1d5253928b8d5d7d4685c7acbungeman@google.com 50b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org/** 51b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org * Returns a pointer to a D which comes immediately after S[count]. 52b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org */ 53b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.orgtemplate <typename D, typename S> static D* SkTAfter(S* ptr, size_t count = 1) { 54b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org return reinterpret_cast<D*>(ptr + count); 55b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org} 56b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 57b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org/** 58b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org * Returns a pointer to a D which comes byteOffset bytes after S. 59b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org */ 60b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.orgtemplate <typename D, typename S> static D* SkTAddOffset(S* ptr, size_t byteOffset) { 61b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // The intermediate char* has the same const-ness as D as this produces better error messages. 62b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // This relies on the fact that reinterpret_cast can add constness, but cannot remove it. 63b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org return reinterpret_cast<D*>( 64b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org reinterpret_cast<typename SkTConstType<char, SkTIsConst<D>::value>::type*>(ptr) + byteOffset 65b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org ); 66b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org} 67b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkAutoTCallVProc 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Call a function when this goes out of scope. The template uses two 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parameters, the object, and a function that is to be called in the destructor. 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If detach() is called, the object reference is set to null. If the object 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference is null when the destructor is called, we do not call the 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com function. 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T, void (*P)(T*)> class SkAutoTCallVProc : SkNoncopyable { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoTCallVProc(T* obj): fObj(obj) {} 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkAutoTCallVProc() { if (fObj) P(fObj); } 80a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 81a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman operator T*() const { return fObj; } 82a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman T* operator->() const { SkASSERT(fObj); return fObj; } 83a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* detach() { T* obj = fObj; fObj = NULL; return obj; } 85a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman void reset(T* obj = NULL) { 86a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (fObj != obj) { 87a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (fObj) { 88a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman P(fObj); 89a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 90a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fObj = obj; 91a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 92a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fObj; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkAutoTCallIProc 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comCall a function when this goes out of scope. The template uses two 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comparameters, the object, and a function that is to be called in the destructor. 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comIf detach() is called, the object reference is set to null. If the object 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comreference is null when the destructor is called, we do not call the 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comfunction. 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T, int (*P)(T*)> class SkAutoTCallIProc : SkNoncopyable { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoTCallIProc(T* obj): fObj(obj) {} 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkAutoTCallIProc() { if (fObj) P(fObj); } 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* detach() { T* obj = fObj; fObj = NULL; return obj; } 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fObj; 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 114e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org/** \class SkAutoTDelete 115e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org An SkAutoTDelete<T> is like a T*, except that the destructor of SkAutoTDelete<T> 116e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org automatically deletes the pointer it holds (if any). That is, SkAutoTDelete<T> 117e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org owns the T object that it points to. Like a T*, an SkAutoTDelete<T> may hold 118e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org either NULL or a pointer to a T object. Also like T*, SkAutoTDelete<T> is 119e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org thread-compatible, and once you dereference it, you get the threadsafety 120e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org guarantees of T. 121e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org 122e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org The size of a SkAutoTDelete is small: sizeof(SkAutoTDelete<T>) == sizeof(T*) 123e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org*/ 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T> class SkAutoTDelete : SkNoncopyable { 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1269d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com SkAutoTDelete(T* obj = NULL) : fObj(obj) {} 1271198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com ~SkAutoTDelete() { SkDELETE(fObj); } 12852657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com 12952657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com T* get() const { return fObj; } 1301790e25e1829ed4091fb149764425df7a3c9c0e0halcanary operator T*() { return fObj; } 13152657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com T& operator*() const { SkASSERT(fObj); return *fObj; } 13252657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com T* operator->() const { SkASSERT(fObj); return fObj; } 13352657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com 1349d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com void reset(T* obj) { 1359d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com if (fObj != obj) { 1361198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com SkDELETE(fObj); 1379d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com fObj = obj; 1389d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com } 1399d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com } 1409d1cff124c14e550889a5755ffa5e6537af7c8c8reed@google.com 14152657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com /** 14252657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com * Delete the owned object, setting the internal pointer to NULL. 14352657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com */ 14452657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com void free() { 1451198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com SkDELETE(fObj); 14652657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com fObj = NULL; 14757f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14952657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com /** 15052657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com * Transfer ownership of the object to the caller, setting the internal 15152657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com * pointer to NULL. Note that this differs from get(), which also returns 15252657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com * the pointer, but it does not transfer ownership. 15352657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com */ 15452657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com T* detach() { 15552657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com T* obj = fObj; 15652657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com fObj = NULL; 15752657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com return obj; 15852657c75b5d4c0e72d64ecaec504b26d0d215a33reed@google.com } 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16090313cc36a6f43a3e9d3818aca536cd6631c222bcommit-bot@chromium.org void swap(SkAutoTDelete* that) { 16190313cc36a6f43a3e9d3818aca536cd6631c222bcommit-bot@chromium.org SkTSwap(fObj, that->fObj); 16290313cc36a6f43a3e9d3818aca536cd6631c222bcommit-bot@chromium.org } 16390313cc36a6f43a3e9d3818aca536cd6631c222bcommit-bot@chromium.org 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fObj; 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com// Calls ~T() in the destructor. 169d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.comtemplate <typename T> class SkAutoTDestroy : SkNoncopyable { 170d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.compublic: 171d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com SkAutoTDestroy(T* obj = NULL) : fObj(obj) {} 172d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com ~SkAutoTDestroy() { 17349f085dddff10473b6ebf832a974288300224e60bsalomon if (fObj) { 174d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com fObj->~T(); 175d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com } 176d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com } 177d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com 178d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com T* get() const { return fObj; } 179d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com T& operator*() const { SkASSERT(fObj); return *fObj; } 180d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com T* operator->() const { SkASSERT(fObj); return fObj; } 181d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com 182d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.comprivate: 183d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com T* fObj; 184d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com}; 185d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T> class SkAutoTDeleteArray : SkNoncopyable { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoTDeleteArray(T array[]) : fArray(array) {} 18958b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com ~SkAutoTDeleteArray() { SkDELETE_ARRAY(fArray); } 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* get() const { return fArray; } 19258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com void free() { SkDELETE_ARRAY(fArray); fArray = NULL; } 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* detach() { T* array = fArray; fArray = NULL; return array; } 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 195cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org void reset(T array[]) { 196cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org if (fArray != array) { 197cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org SkDELETE_ARRAY(fArray); 198cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org fArray = array; 199cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org } 200cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org } 201cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fArray; 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Allocate an array of T elements, and free the array in the destructor 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T> class SkAutoTArray : SkNoncopyable { 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2106d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkAutoTArray() { 2116d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com fArray = NULL; 2126d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkDEBUGCODE(fCount = 0;) 2136d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com } 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Allocate count number of T elements 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2166d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com explicit SkAutoTArray(int count) { 2176d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkASSERT(count >= 0); 2186d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com fArray = NULL; 2196d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com if (count) { 2201198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com fArray = SkNEW_ARRAY(T, count); 2216d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com } 2226d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkDEBUGCODE(fCount = count;) 2236d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com } 2246d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com 2256d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com /** Reallocates given a new count. Reallocation occurs even if new count equals old count. 2266d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com */ 2276d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com void reset(int count) { 2281198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com SkDELETE_ARRAY(fArray); 2296d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkASSERT(count >= 0); 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fArray = NULL; 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count) { 2321198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com fArray = SkNEW_ARRAY(T, count); 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fCount = count;) 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkAutoTArray() { 2381198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com SkDELETE_ARRAY(fArray); 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the array of T elements. Will be NULL if count == 0 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* get() const { return fArray; } 244fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the nth element in the array 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T& operator[](int index) const { 2486d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkASSERT((unsigned)index < (unsigned)fCount); 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fArray[index]; 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fArray; 2546d552ee5f56e76da6ba244df0f0df2234f2d8977bsalomon@google.com SkDEBUGCODE(int fCount;) 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Wraps SkAutoTArray, with room for up to N elements preallocated 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 259adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.comtemplate <int N, typename T> class SkAutoSTArray : SkNoncopyable { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 261d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com /** Initialize with no objects */ 262d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkAutoSTArray() { 263d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fArray = NULL; 264d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fCount = 0; 265d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 266d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Allocate count number of T elements 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 269adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com SkAutoSTArray(int count) { 270d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fArray = NULL; 271d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fCount = 0; 272d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com this->reset(count); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 274fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkAutoSTArray() { 276d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com this->reset(0); 277d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 278d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 279d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com /** Destroys previous objects in the array and default constructs count number of objects */ 280adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com void reset(int count) { 2811198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com T* start = fArray; 2821198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com T* iter = start + fCount; 2831198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com while (iter > start) { 2841198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com (--iter)->~T(); 2851198e740d58abba5edc749c14ed088688b3e76cascroggo@google.com } 286d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 287d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com if (fCount != count) { 2884d3767373942c55be893d3bbbfe35e1975c2e1b4robertphillips@google.com if (fCount > N) { 2894d3767373942c55be893d3bbbfe35e1975c2e1b4robertphillips@google.com // 'fArray' was allocated last time so free it now 2904d3767373942c55be893d3bbbfe35e1975c2e1b4robertphillips@google.com SkASSERT((T*) fStorage != fArray); 291d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com sk_free(fArray); 292d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 293d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 294d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com if (count > N) { 295d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fArray = (T*) sk_malloc_throw(count * sizeof(T)); 296d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } else if (count > 0) { 297d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fArray = (T*) fStorage; 298d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } else { 299d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fArray = NULL; 300d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 301d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 302d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com fCount = count; 303d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com } 304d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com 305d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com iter = fArray; 306d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com T* stop = fArray + count; 307d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com while (iter < stop) { 308d51041469a9a45562d88e9ff137c6726562e8c40bsalomon@google.com SkNEW_PLACEMENT(iter++, T); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 311fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the number of T elements in the array 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 314adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com int count() const { return fCount; } 315fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the array of T elements. Will be NULL if count == 0 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* get() const { return fArray; } 319fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the nth element in the array 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T& operator[](int index) const { 323adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com SkASSERT(index < fCount); 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fArray[index]; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 326fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 328adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com int fCount; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fArray; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // since we come right after fArray, fStorage should be properly aligned 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char fStorage[N * sizeof(T)]; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 334b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org/** Manages an array of T elements, freeing the array in the destructor. 335b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org * Does NOT call any constructors/destructors on T (T must be POD). 336b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org */ 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T> class SkAutoTMalloc : SkNoncopyable { 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 339b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org /** Takes ownership of the ptr. The ptr must be a value which can be passed to sk_free. */ 340b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org explicit SkAutoTMalloc(T* ptr = NULL) { 341b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org fPtr = ptr; 342b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } 343b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 344b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org /** Allocates space for 'count' Ts. */ 345b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org explicit SkAutoTMalloc(size_t count) { 34693fabf4847b4784ffabb8d81e722e14d88c92804Mike Klein fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW); 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3483582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 3493582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com ~SkAutoTMalloc() { 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fPtr); 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3523582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 353b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org /** Resize the memory area pointed to by the current ptr preserving contents. */ 354b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org void realloc(size_t count) { 355b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org fPtr = reinterpret_cast<T*>(sk_realloc_throw(fPtr, count * sizeof(T))); 356b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } 357b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 358b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org /** Resize the memory area pointed to by the current ptr without preserving contents. */ 359b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org void reset(size_t count) { 3603582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com sk_free(fPtr); 36193fabf4847b4784ffabb8d81e722e14d88c92804Mike Klein fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW); 3623582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 3633582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* get() const { return fPtr; } 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3663582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com operator T*() { 3673582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr; 3683582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 3693582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 3703582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com operator const T*() const { 3713582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr; 3723582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 3733582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 3743582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com T& operator[](int index) { 3753582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr[index]; 3763582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 3773582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 3783582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com const T& operator[](int index) const { 3793582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr[index]; 3803582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 3813582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 382b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org /** 383b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org * Transfer ownership of the ptr to the caller, setting the internal 384b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org * pointer to NULL. Note that this differs from get(), which also returns 385b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org * the pointer, but it does not transfer ownership. 386b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org */ 387b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org T* detach() { 388b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org T* ptr = fPtr; 389b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org fPtr = NULL; 390b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org return ptr; 391b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } 392b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 394b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org T* fPtr; 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 397ae326bb5ca55b7102e70a8a589adcb7cf78f37e7bungeman@google.comtemplate <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable { 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3997103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com SkAutoSTMalloc() { 4007103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com fPtr = NULL; 4017103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com } 4027103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com 4033582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSTMalloc(size_t count) { 4047103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com if (count > N) { 4057103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP); 4067103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com } else if (count) { 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPtr = fTStorage; 4083582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } else { 4097103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com fPtr = NULL; 4103582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4113582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4123582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4133582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com ~SkAutoSTMalloc() { 4143582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com if (fPtr != fTStorage) { 4153582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com sk_free(fPtr); 4163582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4183582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4193582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com // doesn't preserve contents 4204e05fd25c88bea64a988ededfc810770095ed97creed@google.com T* reset(size_t count) { 4213582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com if (fPtr != fTStorage) { 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fPtr); 4233582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4247103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com if (count > N) { 4257103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP); 4267103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com } else if (count) { 4273582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com fPtr = fTStorage; 4283582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } else { 4297103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com fPtr = NULL; 4303582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4314e05fd25c88bea64a988ededfc810770095ed97creed@google.com return fPtr; 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4333582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* get() const { return fPtr; } 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4363582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com operator T*() { 4373582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr; 4383582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4393582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4403582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com operator const T*() const { 4413582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr; 4423582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4433582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4443582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com T& operator[](int index) { 4453582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr[index]; 4463582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4473582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4483582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com const T& operator[](int index) const { 4493582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com return fPtr[index]; 4503582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com } 4513582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T* fPtr; 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com union { 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t fStorage32[(N*sizeof(T) + 3) >> 2]; 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T fTStorage[1]; // do NOT want to invoke T::T() 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 46049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com/** 46149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Reserves memory that is aligned on double and pointer boundaries. 46249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Hopefully this is sufficient for all practical purposes. 46349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 46449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.comtemplate <size_t N> class SkAlignedSStorage : SkNoncopyable { 46549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.compublic: 46649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com void* get() { return fData; } 46749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.comprivate: 46849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com union { 46949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com void* fPtr; 47049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com double fDouble; 47149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com char fData[N]; 47249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com }; 47349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com}; 47449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com 47549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com/** 47649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Reserves memory that is aligned on double and pointer boundaries. 47749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Hopefully this is sufficient for all practical purposes. Otherwise, 47849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * we have to do some arcane trickery to determine alignment of non-POD 47949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * types. Lifetime of the memory is the lifetime of the object. 48049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 48149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.comtemplate <int N, typename T> class SkAlignedSTStorage : SkNoncopyable { 48249313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.compublic: 48349313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com /** 48449313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * Returns void* because this object does not initialize the 48549313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com * memory. Use placement new for types that require a cons. 48649313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com */ 48749313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com void* get() { return fStorage.get(); } 48849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.comprivate: 48949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com SkAlignedSStorage<sizeof(T)*N> fStorage; 49049313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com}; 49149313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 493