Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright 2015, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef ANDROID_FAT_VECTOR_H
     27 #define ANDROID_FAT_VECTOR_H
     28 
     29 #include "utils/Macros.h"
     30 
     31 #include <stddef.h>
     32 #include <stdlib.h>
     33 #include <type_traits>
     34 #include <utils/Log.h>
     35 
     36 #include <vector>
     37 
     38 namespace android {
     39 namespace uirenderer {
     40 
     41 template <typename T, size_t SIZE>
     42 class InlineStdAllocator {
     43 public:
     44     struct Allocation {
     45         PREVENT_COPY_AND_ASSIGN(Allocation);
     46     public:
     47         Allocation() {};
     48         // char array instead of T array, so memory is uninitialized, with no destructors run
     49         char array[sizeof(T) * SIZE];
     50         bool inUse = false;
     51     };
     52 
     53     typedef T value_type; // needed to implement std::allocator
     54     typedef T* pointer; // needed to implement std::allocator
     55 
     56     explicit InlineStdAllocator(Allocation& allocation)
     57             : mAllocation(allocation) {}
     58     InlineStdAllocator(const InlineStdAllocator& other)
     59             : mAllocation(other.mAllocation) {}
     60     ~InlineStdAllocator() {}
     61 
     62     T* allocate(size_t num, const void* = 0) {
     63         if (!mAllocation.inUse && num <= SIZE) {
     64             mAllocation.inUse = true;
     65             return (T*) mAllocation.array;
     66         } else {
     67             return (T*) malloc(num * sizeof(T));
     68         }
     69     }
     70 
     71     void deallocate(pointer p, size_t num) {
     72         if (p == (T*)mAllocation.array) {
     73             mAllocation.inUse = false;
     74         } else {
     75             // 'free' instead of delete here - destruction handled separately
     76             free(p);
     77         }
     78     }
     79     Allocation& mAllocation;
     80 };
     81 
     82 /**
     83  * std::vector with SIZE elements preallocated into an internal buffer.
     84  *
     85  * Useful for avoiding the cost of malloc in cases where only SIZE or
     86  * fewer elements are needed in the common case.
     87  */
     88 template <typename T, size_t SIZE>
     89 class FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> {
     90 public:
     91     FatVector() : std::vector<T, InlineStdAllocator<T, SIZE>>(
     92             InlineStdAllocator<T, SIZE>(mAllocation)) {
     93         this->reserve(SIZE);
     94     }
     95 
     96     explicit FatVector(size_t capacity) : FatVector() {
     97         this->resize(capacity);
     98     }
     99 
    100 private:
    101     typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
    102 };
    103 
    104 }; // namespace uirenderer
    105 }; // namespace android
    106 
    107 #endif // ANDROID_FAT_VECTOR_H
    108