1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_FIXEDSIZEVECTOR_H 11 #define EIGEN_FIXEDSIZEVECTOR_H 12 13 namespace Eigen { 14 15 /** \class MaxSizeVector 16 * \ingroup Core 17 * 18 * \brief The MaxSizeVector class. 19 * 20 * The %MaxSizeVector provides a subset of std::vector functionality. 21 * 22 * The goal is to provide basic std::vector operations when using 23 * std::vector is not an option (e.g. on GPU or when compiling using 24 * FMA/AVX, as this can cause either compilation failures or illegal 25 * instruction failures). 26 * 27 * Beware: The constructors are not API compatible with these of 28 * std::vector. 29 */ 30 template <typename T> 31 class MaxSizeVector { 32 public: 33 // Construct a new MaxSizeVector, reserve n elements. 34 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MaxSizeVector(size_t n)35 explicit MaxSizeVector(size_t n) 36 : reserve_(n), size_(0), 37 data_(static_cast<T*>(internal::aligned_malloc(n * sizeof(T)))) { 38 for (size_t i = 0; i < n; ++i) { new (&data_[i]) T; } 39 } 40 41 // Construct a new MaxSizeVector, reserve and resize to n. 42 // Copy the init value to all elements. 43 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MaxSizeVector(size_t n,const T & init)44 MaxSizeVector(size_t n, const T& init) 45 : reserve_(n), size_(n), 46 data_(static_cast<T*>(internal::aligned_malloc(n * sizeof(T)))) { 47 for (size_t i = 0; i < n; ++i) { new (&data_[i]) T(init); } 48 } 49 50 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~MaxSizeVector()51 ~MaxSizeVector() { 52 for (size_t i = 0; i < size_; ++i) { 53 data_[i].~T(); 54 } 55 internal::aligned_free(data_); 56 } 57 resize(size_t n)58 void resize(size_t n) { 59 eigen_assert(n <= reserve_); 60 for (size_t i = size_; i < n; ++i) { 61 new (&data_[i]) T; 62 } 63 for (size_t i = n; i < size_; ++i) { 64 data_[i].~T(); 65 } 66 size_ = n; 67 } 68 69 // Append new elements (up to reserved size). 70 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE push_back(const T & t)71 void push_back(const T& t) { 72 eigen_assert(size_ < reserve_); 73 data_[size_++] = t; 74 } 75 76 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 77 const T& operator[] (size_t i) const { 78 eigen_assert(i < size_); 79 return data_[i]; 80 } 81 82 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 83 T& operator[] (size_t i) { 84 eigen_assert(i < size_); 85 return data_[i]; 86 } 87 88 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE back()89 T& back() { 90 eigen_assert(size_ > 0); 91 return data_[size_ - 1]; 92 } 93 94 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE back()95 const T& back() const { 96 eigen_assert(size_ > 0); 97 return data_[size_ - 1]; 98 } 99 100 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE pop_back()101 void pop_back() { 102 // NOTE: This does not destroy the value at the end the way 103 // std::vector's version of pop_back() does. That happens when 104 // the Vector is destroyed. 105 eigen_assert(size_ > 0); 106 size_--; 107 } 108 109 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size()110 size_t size() const { return size_; } 111 112 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE empty()113 bool empty() const { return size_ == 0; } 114 115 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE data()116 T* data() { return data_; } 117 118 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE data()119 const T* data() const { return data_; } 120 121 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE begin()122 T* begin() { return data_; } 123 124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE end()125 T* end() { return data_ + size_; } 126 127 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE begin()128 const T* begin() const { return data_; } 129 130 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE end()131 const T* end() const { return data_ + size_; } 132 133 private: 134 size_t reserve_; 135 size_t size_; 136 T* data_; 137 }; 138 139 } // namespace Eigen 140 141 #endif // EIGEN_FIXEDSIZEVECTOR_H 142