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