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 25namespace chre { 26 27template<typename ElementType, size_t kCapacity> 28FixedSizeVector<ElementType, kCapacity>::~FixedSizeVector() { 29 destroy(data(), size()); 30} 31 32template<typename ElementType, size_t kCapacity> 33ElementType& FixedSizeVector<ElementType, kCapacity>::back() { 34 CHRE_ASSERT(mSize > 0); 35 return data()[mSize - 1]; 36} 37 38template<typename ElementType, size_t kCapacity> 39const ElementType& FixedSizeVector<ElementType, kCapacity>::back() const { 40 CHRE_ASSERT(mSize > 0); 41 return data()[mSize - 1]; 42} 43 44template<typename ElementType, size_t kCapacity> 45ElementType& FixedSizeVector<ElementType, kCapacity>::front() { 46 CHRE_ASSERT(mSize > 0); 47 return data()[0]; 48} 49 50template<typename ElementType, size_t kCapacity> 51const ElementType& FixedSizeVector<ElementType, kCapacity>::front() const { 52 CHRE_ASSERT(mSize > 0); 53 return data()[0]; 54} 55 56template<typename ElementType, size_t kCapacity> 57ElementType *FixedSizeVector<ElementType, kCapacity>::data() { 58 return reinterpret_cast<ElementType *>(mData); 59} 60 61template<typename ElementType, size_t kCapacity> 62const ElementType *FixedSizeVector<ElementType, kCapacity>::data() const { 63 return reinterpret_cast<const ElementType *>(mData); 64} 65 66template<typename ElementType, size_t kCapacity> 67size_t FixedSizeVector<ElementType, kCapacity>::size() const { 68 return mSize; 69} 70 71template<typename ElementType, size_t kCapacity> 72size_t FixedSizeVector<ElementType, kCapacity>::capacity() const { 73 return kCapacity; 74} 75 76template<typename ElementType, size_t kCapacity> 77bool FixedSizeVector<ElementType, kCapacity>::empty() const { 78 return (mSize == 0); 79} 80 81template<typename ElementType, size_t kCapacity> 82bool FixedSizeVector<ElementType, kCapacity>::full() const { 83 return (mSize == kCapacity); 84} 85 86template<typename ElementType, size_t kCapacity> 87void 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 95template<typename ElementType, size_t kCapacity> 96template<typename... Args> 97void 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 104template<typename ElementType, size_t kCapacity> 105ElementType& 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 115template<typename ElementType, size_t kCapacity> 116const 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 126template<typename ElementType, size_t kCapacity> 127void 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 139template<typename ElementType, size_t kCapacity> 140void 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 153template<typename ElementType, size_t kCapacity> 154typename FixedSizeVector<ElementType, kCapacity>::iterator 155 FixedSizeVector<ElementType, kCapacity>::begin() { 156 return data(); 157} 158 159template<typename ElementType, size_t kCapacity> 160typename FixedSizeVector<ElementType, kCapacity>::iterator 161 FixedSizeVector<ElementType, kCapacity>::end() { 162 return (data() + mSize); 163} 164 165template<typename ElementType, size_t kCapacity> 166typename FixedSizeVector<ElementType, kCapacity>::const_iterator 167 FixedSizeVector<ElementType, kCapacity>::begin() const { 168 return cbegin(); 169} 170 171template<typename ElementType, size_t kCapacity> 172typename FixedSizeVector<ElementType, kCapacity>::const_iterator 173 FixedSizeVector<ElementType, kCapacity>::end() const { 174 return cend(); 175} 176 177template<typename ElementType, size_t kCapacity> 178typename FixedSizeVector<ElementType, kCapacity>::const_iterator 179 FixedSizeVector<ElementType, kCapacity>::cbegin() const { 180 return data(); 181} 182 183template<typename ElementType, size_t kCapacity> 184typename FixedSizeVector<ElementType, kCapacity>::const_iterator 185 FixedSizeVector<ElementType, kCapacity>::cend() const { 186 return (data() + mSize); 187} 188 189template<typename ElementType, size_t kCapacity> 190void 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