176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik/* 276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * Copyright 2015, The Android Open Source Project 376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * 476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * Redistribution and use in source and binary forms, with or without 576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * modification, are permitted provided that the following conditions 676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * are met: 776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * * Redistributions of source code must retain the above copyright 876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * notice, this list of conditions and the following disclaimer. 976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * * Redistributions in binary form must reproduce the above copyright 1076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * notice, this list of conditions and the following disclaimer in the 1176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * documentation and/or other materials provided with the distribution. 1276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * 1376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 1476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 1776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 2176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik */ 2576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 2676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#ifndef ANDROID_FAT_VECTOR_H 2776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#define ANDROID_FAT_VECTOR_H 2876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 2976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#include "utils/Macros.h" 3076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 3176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#include <stddef.h> 3230bcf69df9cfae40b621335958656cb0e4afd7d5Doris Liu#include <stdlib.h> 3376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#include <type_traits> 3476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#include <utils/Log.h> 3576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 3676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#include <vector> 3776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 3876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craiknamespace android { 3976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craiknamespace uirenderer { 4076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 4176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craiktemplate <typename T, size_t SIZE> 4276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikclass InlineStdAllocator { 4376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikpublic: 4476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik struct Allocation { 4576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik PREVENT_COPY_AND_ASSIGN(Allocation); 4676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik public: 4776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik Allocation() {}; 4876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik // char array instead of T array, so memory is uninitialized, with no destructors run 4976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik char array[sizeof(T) * SIZE]; 5076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik bool inUse = false; 5176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik }; 5276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 5376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik typedef T value_type; // needed to implement std::allocator 5476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik typedef T* pointer; // needed to implement std::allocator 5576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 5676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik InlineStdAllocator(Allocation& allocation) 5776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik : mAllocation(allocation) {} 5876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik InlineStdAllocator(const InlineStdAllocator& other) 5976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik : mAllocation(other.mAllocation) {} 6076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik ~InlineStdAllocator() {} 6176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 6276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik T* allocate(size_t num, const void* = 0) { 6376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik if (!mAllocation.inUse && num <= SIZE) { 6476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik mAllocation.inUse = true; 6576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik return (T*) mAllocation.array; 6676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } else { 6776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik return (T*) malloc(num * sizeof(T)); 6876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 6976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 7076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 7176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik void deallocate(pointer p, size_t num) { 7276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik if (p == (T*)mAllocation.array) { 7376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik mAllocation.inUse = false; 7476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } else { 7576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik // 'free' instead of delete here - destruction handled separately 7676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik free(p); 7776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 7876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 7976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik Allocation& mAllocation; 8076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik}; 8176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 8276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik/** 8376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * std::vector with SIZE elements preallocated into an internal buffer. 8476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * 8576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * Useful for avoiding the cost of malloc in cases where only SIZE or 8676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * fewer elements are needed in the common case. 8776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik */ 8876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craiktemplate <typename T, size_t SIZE> 8976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikclass FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> { 9076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikpublic: 9176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik FatVector() : std::vector<T, InlineStdAllocator<T, SIZE>>( 9276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik InlineStdAllocator<T, SIZE>(mAllocation)) { 9376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik this->reserve(SIZE); 9476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 958d2cf943d9c7292e54726399faefdec4a01c084bChris Craik 968d2cf943d9c7292e54726399faefdec4a01c084bChris Craik FatVector(size_t capacity) : FatVector() { 978d2cf943d9c7292e54726399faefdec4a01c084bChris Craik this->resize(capacity); 988d2cf943d9c7292e54726399faefdec4a01c084bChris Craik } 9930bcf69df9cfae40b621335958656cb0e4afd7d5Doris Liu 10076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikprivate: 10176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik typename InlineStdAllocator<T, SIZE>::Allocation mAllocation; 10276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik}; 10376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 10476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik}; // namespace uirenderer 10576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik}; // namespace android 10676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 10776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik#endif // ANDROID_FAT_VECTOR_H 108