blob: eafe2f13c16da2a64781a0fe255ec257784cd2b3 [file] [log] [blame]
Chris Craik76ace112015-10-29 12:46:19 -07001/*
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>
Doris Liu30bcf692015-11-04 14:56:24 -080032#include <stdlib.h>
Chris Craik76ace112015-10-29 12:46:19 -070033#include <utils/Log.h>
John Reck1bcacfd2017-11-03 10:12:19 -070034#include <type_traits>
Chris Craik76ace112015-10-29 12:46:19 -070035
36#include <vector>
37
38namespace android {
39namespace uirenderer {
40
41template <typename T, size_t SIZE>
42class InlineStdAllocator {
43public:
44 struct Allocation {
45 PREVENT_COPY_AND_ASSIGN(Allocation);
John Reck1bcacfd2017-11-03 10:12:19 -070046
Chris Craik76ace112015-10-29 12:46:19 -070047 public:
John Reck1bcacfd2017-11-03 10:12:19 -070048 Allocation(){};
Chris Craik76ace112015-10-29 12:46:19 -070049 // 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
John Reck1bcacfd2017-11-03 10:12:19 -070054 typedef T value_type; // needed to implement std::allocator
55 typedef T* pointer; // needed to implement std::allocator
Chris Craik76ace112015-10-29 12:46:19 -070056
John Reck1bcacfd2017-11-03 10:12:19 -070057 explicit InlineStdAllocator(Allocation& allocation) : mAllocation(allocation) {}
58 InlineStdAllocator(const InlineStdAllocator& other) : mAllocation(other.mAllocation) {}
Chris Craik76ace112015-10-29 12:46:19 -070059 ~InlineStdAllocator() {}
60
61 T* allocate(size_t num, const void* = 0) {
62 if (!mAllocation.inUse && num <= SIZE) {
63 mAllocation.inUse = true;
John Reck1bcacfd2017-11-03 10:12:19 -070064 return (T*)mAllocation.array;
Chris Craik76ace112015-10-29 12:46:19 -070065 } else {
John Reck1bcacfd2017-11-03 10:12:19 -070066 return (T*)malloc(num * sizeof(T));
Chris Craik76ace112015-10-29 12:46:19 -070067 }
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 */
87template <typename T, size_t SIZE>
88class FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> {
89public:
John Reck1bcacfd2017-11-03 10:12:19 -070090 FatVector()
91 : std::vector<T, InlineStdAllocator<T, SIZE>>(
92 InlineStdAllocator<T, SIZE>(mAllocation)) {
Chris Craik76ace112015-10-29 12:46:19 -070093 this->reserve(SIZE);
94 }
Chris Craik8d2cf942015-11-02 14:52:21 -080095
John Reck1bcacfd2017-11-03 10:12:19 -070096 explicit FatVector(size_t capacity) : FatVector() { this->resize(capacity); }
Doris Liu30bcf692015-11-04 14:56:24 -080097
Chris Craik76ace112015-10-29 12:46:19 -070098private:
99 typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
100};
101
John Reck1bcacfd2017-11-03 10:12:19 -0700102}; // namespace uirenderer
103}; // namespace android
Chris Craik76ace112015-10-29 12:46:19 -0700104
John Reck1bcacfd2017-11-03 10:12:19 -0700105#endif // ANDROID_FAT_VECTOR_H