1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef CHRE_UTIL_FIXED_SIZE_VECTOR_IMPL_H_
18 #define CHRE_UTIL_FIXED_SIZE_VECTOR_IMPL_H_
19
20 #include <new>
21
22 #include "chre/platform/assert.h"
23 #include "chre/util/memory.h"
24
25 namespace chre {
26
27 template<typename ElementType, size_t kCapacity>
data()28 ElementType *FixedSizeVector<ElementType, kCapacity>::data() {
29 return reinterpret_cast<ElementType *>(mData);
30 }
31
32 template<typename ElementType, size_t kCapacity>
data()33 const ElementType *FixedSizeVector<ElementType, kCapacity>::data() const {
34 return reinterpret_cast<const ElementType *>(mData);
35 }
36
37 template<typename ElementType, size_t kCapacity>
size()38 size_t FixedSizeVector<ElementType, kCapacity>::size() const {
39 return mSize;
40 }
41
42 template<typename ElementType, size_t kCapacity>
capacity()43 size_t FixedSizeVector<ElementType, kCapacity>::capacity() const {
44 return kCapacity;
45 }
46
47 template<typename ElementType, size_t kCapacity>
empty()48 bool FixedSizeVector<ElementType, kCapacity>::empty() const {
49 return (mSize == 0);
50 }
51
52 template<typename ElementType, size_t kCapacity>
full()53 bool FixedSizeVector<ElementType, kCapacity>::full() const {
54 return (mSize == kCapacity);
55 }
56
57 template<typename ElementType, size_t kCapacity>
push_back(const ElementType & element)58 void FixedSizeVector<ElementType, kCapacity>::push_back(
59 const ElementType& element) {
60 CHRE_ASSERT(!full());
61 if (!full()) {
62 new (&data()[mSize++]) ElementType(element);
63 }
64 }
65
66 template<typename ElementType, size_t kCapacity>
67 template<typename... Args>
emplace_back(Args &&...args)68 void FixedSizeVector<ElementType, kCapacity>::emplace_back(Args&&... args) {
69 CHRE_ASSERT(!full());
70 if (!full()) {
71 new (&data()[mSize++]) ElementType(std::forward<Args>(args)...);
72 }
73 }
74
75 template<typename ElementType, size_t kCapacity>
76 ElementType& FixedSizeVector<ElementType, kCapacity>::operator[](
77 size_t index) {
78 CHRE_ASSERT(index < mSize);
79 if (index >= mSize) {
80 index = mSize - 1;
81 }
82
83 return data()[index];
84 }
85
86 template<typename ElementType, size_t kCapacity>
87 const ElementType& FixedSizeVector<ElementType, kCapacity>::operator[](
88 size_t index) const {
89 CHRE_ASSERT(index < mSize);
90 if (index >= mSize) {
91 index = mSize - 1;
92 }
93
94 return data()[index];
95 }
96
97 template<typename ElementType, size_t kCapacity>
erase(size_t index)98 void FixedSizeVector<ElementType, kCapacity>::erase(size_t index) {
99 CHRE_ASSERT(index < mSize);
100 if (index < mSize) {
101 mSize--;
102 for (size_t i = index; i < mSize; i++) {
103 moveOrCopyAssign(data()[i], data()[i + 1]);
104 }
105
106 data()[mSize].~ElementType();
107 }
108 }
109
110 template<typename ElementType, size_t kCapacity>
swap(size_t index0,size_t index1)111 void FixedSizeVector<ElementType, kCapacity>::swap(size_t index0,
112 size_t index1) {
113 CHRE_ASSERT(index0 < mSize && index1 < mSize);
114 if (index0 < mSize && index1 < mSize && index0 != index1) {
115 typename std::aligned_storage<sizeof(ElementType),
116 alignof(ElementType)>::type tempStorage;
117 ElementType& temp = *reinterpret_cast<ElementType *>(&tempStorage);
118 uninitializedMoveOrCopy(&data()[index0], 1, &temp);
119 moveOrCopyAssign(data()[index0], data()[index1]);
120 moveOrCopyAssign(data()[index1], temp);
121 }
122 }
123
124 template<typename ElementType, size_t kCapacity>
125 typename FixedSizeVector<ElementType, kCapacity>::iterator
begin()126 FixedSizeVector<ElementType, kCapacity>::begin() {
127 return data();
128 }
129
130 template<typename ElementType, size_t kCapacity>
131 typename FixedSizeVector<ElementType, kCapacity>::iterator
end()132 FixedSizeVector<ElementType, kCapacity>::end() {
133 return (data() + mSize);
134 }
135
136 template<typename ElementType, size_t kCapacity>
137 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
begin()138 FixedSizeVector<ElementType, kCapacity>::begin() const {
139 return cbegin();
140 }
141
142 template<typename ElementType, size_t kCapacity>
143 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
end()144 FixedSizeVector<ElementType, kCapacity>::end() const {
145 return cend();
146 }
147
148 template<typename ElementType, size_t kCapacity>
149 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
cbegin()150 FixedSizeVector<ElementType, kCapacity>::cbegin() const {
151 return data();
152 }
153
154 template<typename ElementType, size_t kCapacity>
155 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
cend()156 FixedSizeVector<ElementType, kCapacity>::cend() const {
157 return (data() + mSize);
158 }
159
160 template<typename ElementType, size_t kCapacity>
resize(size_t newSize)161 void FixedSizeVector<ElementType, kCapacity>::resize(size_t newSize) {
162 CHRE_ASSERT(newSize <= kCapacity);
163 if (newSize > kCapacity) {
164 newSize = kCapacity;
165 }
166
167 if (newSize > size()) {
168 for (size_t i = size(); i < newSize; i++) {
169 emplace_back();
170 }
171 } else {
172 for (size_t i = newSize; i < size(); i++) {
173 data()[i].~ElementType();
174 }
175
176 mSize = newSize;
177 }
178 }
179
180 } // namespace chre
181
182 #endif // CHRE_UTIL_FIXED_SIZE_VECTOR_IMPL_H_
183