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