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 <utils/Log.h> 341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include <type_traits> 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); 461bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck 4776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik public: 481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck Allocation(){}; 4976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik // char array instead of T array, so memory is uninitialized, with no destructors run 5076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik char array[sizeof(T) * SIZE]; 5176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik bool inUse = false; 5276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik }; 5376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 541bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck typedef T value_type; // needed to implement std::allocator 551bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck typedef T* pointer; // needed to implement std::allocator 5676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 571bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck explicit InlineStdAllocator(Allocation& allocation) : mAllocation(allocation) {} 581bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck InlineStdAllocator(const InlineStdAllocator& other) : mAllocation(other.mAllocation) {} 5976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik ~InlineStdAllocator() {} 6076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 6176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik T* allocate(size_t num, const void* = 0) { 6276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik if (!mAllocation.inUse && num <= SIZE) { 6376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik mAllocation.inUse = true; 641bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck return (T*)mAllocation.array; 6576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } else { 661bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck return (T*)malloc(num * sizeof(T)); 6776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 6876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 6976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 7076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik void deallocate(pointer p, size_t num) { 7176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik if (p == (T*)mAllocation.array) { 7276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik mAllocation.inUse = false; 7376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } else { 7476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik // 'free' instead of delete here - destruction handled separately 7576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik free(p); 7676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 7776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 7876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik Allocation& mAllocation; 7976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik}; 8076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 8176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik/** 8276ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * std::vector with SIZE elements preallocated into an internal buffer. 8376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * 8476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * Useful for avoiding the cost of malloc in cases where only SIZE or 8576ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik * fewer elements are needed in the common case. 8676ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik */ 8776ace115f7870fed9899a9db7d3852e21b5fb258Chris Craiktemplate <typename T, size_t SIZE> 8876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikclass FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> { 8976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikpublic: 901bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck FatVector() 911bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck : std::vector<T, InlineStdAllocator<T, SIZE>>( 921bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck InlineStdAllocator<T, SIZE>(mAllocation)) { 9376ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik this->reserve(SIZE); 9476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik } 958d2cf943d9c7292e54726399faefdec4a01c084bChris Craik 961bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck explicit FatVector(size_t capacity) : FatVector() { this->resize(capacity); } 9730bcf69df9cfae40b621335958656cb0e4afd7d5Doris Liu 9876ace115f7870fed9899a9db7d3852e21b5fb258Chris Craikprivate: 9976ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik typename InlineStdAllocator<T, SIZE>::Allocation mAllocation; 10076ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik}; 10176ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 1021bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace uirenderer 1031bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace android 10476ace115f7870fed9899a9db7d3852e21b5fb258Chris Craik 1051bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#endif // ANDROID_FAT_VECTOR_H 106