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