• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
empty()75 bool FixedSizeVector<ElementType, kCapacity>::empty() const {
76   return (mSize == 0);
77 }
78 
79 template <typename ElementType, size_t kCapacity>
full()80 bool FixedSizeVector<ElementType, kCapacity>::full() const {
81   return (mSize == kCapacity);
82 }
83 
84 template <typename ElementType, size_t kCapacity>
push_back(const ElementType & element)85 void FixedSizeVector<ElementType, kCapacity>::push_back(
86     const ElementType &element) {
87   CHRE_ASSERT(!full());
88   if (!full()) {
89     new (&data()[mSize++]) ElementType(element);
90   }
91 }
92 
93 template <typename ElementType, size_t kCapacity>
push_back(ElementType && element)94 void FixedSizeVector<ElementType, kCapacity>::push_back(ElementType &&element) {
95   CHRE_ASSERT(!full());
96   if (!full()) {
97     new (&data()[mSize++]) ElementType(std::move(element));
98   }
99 }
100 
101 template <typename ElementType, size_t kCapacity>
102 template <typename... Args>
emplace_back(Args &&...args)103 void FixedSizeVector<ElementType, kCapacity>::emplace_back(Args &&... args) {
104   CHRE_ASSERT(!full());
105   if (!full()) {
106     new (&data()[mSize++]) ElementType(std::forward<Args>(args)...);
107   }
108 }
109 
110 template <typename ElementType, size_t kCapacity>
pop_back()111 void FixedSizeVector<ElementType, kCapacity>::pop_back() {
112   CHRE_ASSERT(!empty());
113   erase(mSize - 1);
114 }
115 
116 template <typename ElementType, size_t kCapacity>
117 ElementType &FixedSizeVector<ElementType, kCapacity>::operator[](size_t index) {
118   CHRE_ASSERT(index < mSize);
119   if (index >= kCapacity) {
120     index = kCapacity - 1;
121   }
122 
123   return data()[index];
124 }
125 
126 template <typename ElementType, size_t kCapacity>
127 const ElementType &FixedSizeVector<ElementType, kCapacity>::operator[](
128     size_t index) const {
129   CHRE_ASSERT(index < mSize);
130   if (index >= kCapacity) {
131     index = kCapacity - 1;
132   }
133 
134   return data()[index];
135 }
136 
137 template <typename ElementType, size_t kCapacity>
erase(size_t index)138 void FixedSizeVector<ElementType, kCapacity>::erase(size_t index) {
139   CHRE_ASSERT(index < mSize);
140   if (index < mSize) {
141     mSize--;
142     for (size_t i = index; i < mSize; i++) {
143       moveOrCopyAssign(data()[i], data()[i + 1]);
144     }
145 
146     data()[mSize].~ElementType();
147   }
148 }
149 
150 template <typename ElementType, size_t kCapacity>
swap(size_t index0,size_t index1)151 void FixedSizeVector<ElementType, kCapacity>::swap(size_t index0,
152                                                    size_t index1) {
153   CHRE_ASSERT(index0 < mSize && index1 < mSize);
154   if (index0 < mSize && index1 < mSize && index0 != index1) {
155     typename std::aligned_storage<sizeof(ElementType),
156                                   alignof(ElementType)>::type tempStorage;
157     ElementType &temp = *reinterpret_cast<ElementType *>(&tempStorage);
158     uninitializedMoveOrCopy(&data()[index0], 1, &temp);
159     moveOrCopyAssign(data()[index0], data()[index1]);
160     moveOrCopyAssign(data()[index1], temp);
161   }
162 }
163 
164 template <typename ElementType, size_t kCapacity>
165 typename FixedSizeVector<ElementType, kCapacity>::iterator
begin()166 FixedSizeVector<ElementType, kCapacity>::begin() {
167   return data();
168 }
169 
170 template <typename ElementType, size_t kCapacity>
171 typename FixedSizeVector<ElementType, kCapacity>::iterator
end()172 FixedSizeVector<ElementType, kCapacity>::end() {
173   return (data() + mSize);
174 }
175 
176 template <typename ElementType, size_t kCapacity>
177 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
begin()178 FixedSizeVector<ElementType, kCapacity>::begin() const {
179   return cbegin();
180 }
181 
182 template <typename ElementType, size_t kCapacity>
183 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
end()184 FixedSizeVector<ElementType, kCapacity>::end() const {
185   return cend();
186 }
187 
188 template <typename ElementType, size_t kCapacity>
189 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
cbegin()190 FixedSizeVector<ElementType, kCapacity>::cbegin() const {
191   return data();
192 }
193 
194 template <typename ElementType, size_t kCapacity>
195 typename FixedSizeVector<ElementType, kCapacity>::const_iterator
cend()196 FixedSizeVector<ElementType, kCapacity>::cend() const {
197   return (data() + mSize);
198 }
199 
200 template <typename ElementType, size_t kCapacity>
resize(size_t newSize)201 void FixedSizeVector<ElementType, kCapacity>::resize(size_t newSize) {
202   CHRE_ASSERT(newSize <= kCapacity);
203   if (newSize > kCapacity) {
204     newSize = kCapacity;
205   }
206 
207   if (newSize > size()) {
208     for (size_t i = size(); i < newSize; i++) {
209       emplace_back();
210     }
211   } else {
212     for (size_t i = newSize; i < size(); i++) {
213       data()[i].~ElementType();
214     }
215 
216     mSize = newSize;
217   }
218 }
219 
220 }  // namespace chre
221 
222 #endif  // CHRE_UTIL_FIXED_SIZE_VECTOR_IMPL_H_
223