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 <utils/Log.h>
     34 #include <type_traits>
     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 
     47     public:
     48         Allocation(){};
     49         // char array instead of T array, so memory is uninitialized, with no destructors run
     50         char array[sizeof(T) * SIZE];
     51         bool inUse = false;
     52     };
     53 
     54     typedef T value_type;  // needed to implement std::allocator
     55     typedef T* pointer;    // needed to implement std::allocator
     56 
     57     explicit InlineStdAllocator(Allocation& allocation) : mAllocation(allocation) {}
     58     InlineStdAllocator(const InlineStdAllocator& other) : mAllocation(other.mAllocation) {}
     59     ~InlineStdAllocator() {}
     60 
     61     T* allocate(size_t num, const void* = 0) {
     62         if (!mAllocation.inUse && num <= SIZE) {
     63             mAllocation.inUse = true;
     64             return (T*)mAllocation.array;
     65         } else {
     66             return (T*)malloc(num * sizeof(T));
     67         }
     68     }
     69 
     70     void deallocate(pointer p, size_t num) {
     71         if (p == (T*)mAllocation.array) {
     72             mAllocation.inUse = false;
     73         } else {
     74             // 'free' instead of delete here - destruction handled separately
     75             free(p);
     76         }
     77     }
     78     Allocation& mAllocation;
     79 };
     80 
     81 /**
     82  * std::vector with SIZE elements preallocated into an internal buffer.
     83  *
     84  * Useful for avoiding the cost of malloc in cases where only SIZE or
     85  * fewer elements are needed in the common case.
     86  */
     87 template <typename T, size_t SIZE>
     88 class FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> {
     89 public:
     90     FatVector()
     91             : std::vector<T, InlineStdAllocator<T, SIZE>>(
     92                       InlineStdAllocator<T, SIZE>(mAllocation)) {
     93         this->reserve(SIZE);
     94     }
     95 
     96     explicit FatVector(size_t capacity) : FatVector() { this->resize(capacity); }
     97 
     98 private:
     99     typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
    100 };
    101 
    102 };  // namespace uirenderer
    103 };  // namespace android
    104 
    105 #endif  // ANDROID_FAT_VECTOR_H
    106