xref: /aosp_15_r20/system/chre/util/include/chre/util/fixed_size_vector_impl.h (revision 84e339476a462649f82315436d70fd732297a399)
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 // IWYU pragma: private
21 #include "chre/util/fixed_size_vector.h"
22 
23 #include <new>
24 
25 #include "chre/util/container_support.h"
26 #include "chre/util/memory.h"
27 
28 namespace chre {
29 
30 template <typename ElementType, size_t kCapacity>
~FixedSizeVector()31 FixedSizeVector<ElementType, kCapacity>::~FixedSizeVector() {
32   destroy(data(), size());
33 }
34 
35 template <typename ElementType, size_t kCapacity>
back()36 ElementType &FixedSizeVector<ElementType, kCapacity>::back() {
37   CHRE_ASSERT(mSize > 0);
38   return data()[mSize - 1];
39 }
40 
41 template <typename ElementType, size_t kCapacity>
back()42 const ElementType &FixedSizeVector<ElementType, kCapacity>::back() const {
43   CHRE_ASSERT(mSize > 0);
44   return data()[mSize - 1];
45 }
46 
47 template <typename ElementType, size_t kCapacity>
front()48 ElementType &FixedSizeVector<ElementType, kCapacity>::front() {
49   CHRE_ASSERT(mSize > 0);
50   return data()[0];
51 }
52 
53 template <typename ElementType, size_t kCapacity>
front()54 const ElementType &FixedSizeVector<ElementType, kCapacity>::front() const {
55   CHRE_ASSERT(mSize > 0);
56   return data()[0];
57 }
58 
59 template <typename ElementType, size_t kCapacity>
data()60 ElementType *FixedSizeVector<ElementType, kCapacity>::data() {
61   return mData.data();
62 }
63 
64 template <typename ElementType, size_t kCapacity>
data()65 const ElementType *FixedSizeVector<ElementType, kCapacity>::data() const {
66   return mData.data();
67 }
68 
69 template <typename ElementType, size_t kCapacity>
size()70 size_t FixedSizeVector<ElementType, kCapacity>::size() const {
71   return mSize;
72 }
73 
74 template <typename ElementType, size_t kCapacity>
capacity()75 size_t FixedSizeVector<ElementType, kCapacity>::capacity() const {
76   return kCapacity;
77 }
78 
79 template <typename ElementType, size_t kCapacity>
empty()80 bool FixedSizeVector<ElementType, kCapacity>::empty() const {
81   return (mSize == 0);
82 }
83 
84 template <typename ElementType, size_t kCapacity>
full()85 bool FixedSizeVector<ElementType, kCapacity>::full() const {
86   return (mSize == kCapacity);
87 }
88 
89 template <typename ElementType, size_t kCapacity>
push_back(const ElementType & element)90 void FixedSizeVector<ElementType, kCapacity>::push_back(
91     const ElementType &element) {
92   CHRE_ASSERT(!full());
93   if (!full()) {
94     new (&data()[mSize++]) ElementType(element);
95   }
96 }
97 
98 template <typename ElementType, size_t kCapacity>
push_back(ElementType && element)99 void FixedSizeVector<ElementType, kCapacity>::push_back(ElementType &&element) {
100   CHRE_ASSERT(!full());
101   if (!full()) {
102     new (&data()[mSize++]) ElementType(std::move(element));
103   }
104 }
105 
106 template <typename ElementType, size_t kCapacity>
107 template <typename... Args>
emplace_back(Args &&...args)108 void FixedSizeVector<ElementType, kCapacity>::emplace_back(Args &&... args) {
109   CHRE_ASSERT(!full());
110   if (!full()) {
111     new (&data()[mSize++]) ElementType(std::forward<Args>(args)...);
112   }
113 }
114 
115 template <typename ElementType, size_t kCapacity>
pop_back()116 void FixedSizeVector<ElementType, kCapacity>::pop_back() {
117   CHRE_ASSERT(!empty());
118   erase(mSize - 1);
119 }
120 
121 template <typename ElementType, size_t kCapacity>
122 ElementType &FixedSizeVector<ElementType, kCapacity>::operator[](size_t index) {
123   CHRE_ASSERT(index < mSize);
124   if (index >= kCapacity) {
125     index = kCapacity - 1;
126   }
127 
128   return data()[index];
129 }
130 
131 template <typename ElementType, size_t kCapacity>
132 const ElementType &FixedSizeVector<ElementType, kCapacity>::operator[](
133     size_t index) const {
134   CHRE_ASSERT(index < mSize);
135   if (index >= kCapacity) {
136     index = kCapacity - 1;
137   }
138 
139   return data()[index];
140 }
141 
142 template <typename ElementType, size_t kCapacity>
erase(size_t index)143 void FixedSizeVector<ElementType, kCapacity>::erase(size_t index) {
144   CHRE_ASSERT(index < mSize);
145   if (index < mSize) {
146     mSize--;
147     for (size_t i = index; i < mSize; i++) {
148       moveOrCopyAssign(data()[i], data()[i + 1]);
149     }
150 
151     data()[mSize].~ElementType();
152   }
153 }
154 
155 template <typename ElementType, size_t kCapacity>
swap(size_t index0,size_t index1)156 void FixedSizeVector<ElementType, kCapacity>::swap(size_t index0,
157                                                    size_t index1) {
158   CHRE_ASSERT(index0 < mSize && index1 < mSize);
159   if (index0 < mSize && index1 < mSize && index0 != index1) {
160     typename std::aligned_storage<sizeof(ElementType),
161                                   alignof(ElementType)>::type tempStorage;
162     ElementType &temp = *reinterpret_cast<ElementType *>(&tempStorage);
163     uninitializedMoveOrCopy(&data()[index0], 1, &temp);
164     moveOrCopyAssign(data()[index0], data()[index1]);
165     moveOrCopyAssign(data()[index1], temp);
166   }
167 }
168 
169 template <typename ElementType, size_t kCapacity>
170 typename FixedSizeVector<ElementType, kCapacity>::iterator
begin()171 FixedSizeVector<ElementType, kCapacity>::begin() {
172   return data();
173 }
174 
175 template <typename ElementType, size_t kCapacity>
176 typename FixedSizeVector<ElementType, kCapacity>::iterator
end()177 FixedSizeVector<ElementType, kCapacity>::end() {
178   return (data() + mSize);
179 }
180 
181 template <typename ElementType, size_t kCapacity>
182 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
begin()183 FixedSizeVector<ElementType, kCapacity>::begin() const {
184   return cbegin();
185 }
186 
187 template <typename ElementType, size_t kCapacity>
188 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
end()189 FixedSizeVector<ElementType, kCapacity>::end() const {
190   return cend();
191 }
192 
193 template <typename ElementType, size_t kCapacity>
194 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
cbegin()195 FixedSizeVector<ElementType, kCapacity>::cbegin() const {
196   return data();
197 }
198 
199 template <typename ElementType, size_t kCapacity>
200 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
cend()201 FixedSizeVector<ElementType, kCapacity>::cend() const {
202   return (data() + mSize);
203 }
204 
205 template <typename ElementType, size_t kCapacity>
resize(size_t newSize)206 void FixedSizeVector<ElementType, kCapacity>::resize(size_t newSize) {
207   CHRE_ASSERT(newSize <= kCapacity);
208   if (newSize > kCapacity) {
209     newSize = kCapacity;
210   }
211 
212   if (newSize > size()) {
213     for (size_t i = size(); i < newSize; i++) {
214       emplace_back();
215     }
216   } else {
217     for (size_t i = newSize; i < size(); i++) {
218       data()[i].~ElementType();
219     }
220 
221     mSize = newSize;
222   }
223 }
224 
225 }  // namespace chre
226 
227 #endif  // CHRE_UTIL_FIXED_SIZE_VECTOR_IMPL_H_
228