blob: df8cb076e763dcf7fcc44098ce270887548eecb7 [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 <type_traits>
34#include <utils/Log.h>
35
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);
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
Chih-Hung Hsieha619ec72016-08-29 14:52:43 -070056 explicit InlineStdAllocator(Allocation& allocation)
Chris Craik76ace112015-10-29 12:46:19 -070057 : 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 */
88template <typename T, size_t SIZE>
89class FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> {
90public:
91 FatVector() : std::vector<T, InlineStdAllocator<T, SIZE>>(
92 InlineStdAllocator<T, SIZE>(mAllocation)) {
93 this->reserve(SIZE);
94 }
Chris Craik8d2cf942015-11-02 14:52:21 -080095
Chih-Hung Hsieha619ec72016-08-29 14:52:43 -070096 explicit FatVector(size_t capacity) : FatVector() {
Chris Craik8d2cf942015-11-02 14:52:21 -080097 this->resize(capacity);
98 }
Doris Liu30bcf692015-11-04 14:56:24 -080099
Chris Craik76ace112015-10-29 12:46:19 -0700100private:
101 typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
102};
103
104}; // namespace uirenderer
105}; // namespace android
106
107#endif // ANDROID_FAT_VECTOR_H