// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2014 Benoit Steiner // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FIXEDSIZEVECTOR_H #define EIGEN_FIXEDSIZEVECTOR_H namespace Eigen { /** \class MaxSizeVector * \ingroup Core * * \brief The MaxSizeVector class. * * The %MaxSizeVector provides a subset of std::vector functionality. * * The goal is to provide basic std::vector operations when using * std::vector is not an option (e.g. on GPU or when compiling using * FMA/AVX, as this can cause either compilation failures or illegal * instruction failures). * * Beware: The constructors are not API compatible with these of * std::vector. */ template class MaxSizeVector { public: // Construct a new MaxSizeVector, reserve n elements. EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit MaxSizeVector(size_t n) : reserve_(n), size_(0), data_(static_cast(internal::aligned_malloc(n * sizeof(T)))) { for (size_t i = 0; i < n; ++i) { new (&data_[i]) T; } } // Construct a new MaxSizeVector, reserve and resize to n. // Copy the init value to all elements. EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MaxSizeVector(size_t n, const T& init) : reserve_(n), size_(n), data_(static_cast(internal::aligned_malloc(n * sizeof(T)))) { for (size_t i = 0; i < n; ++i) { new (&data_[i]) T(init); } } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~MaxSizeVector() { for (size_t i = 0; i < size_; ++i) { data_[i].~T(); } internal::aligned_free(data_); } void resize(size_t n) { eigen_assert(n <= reserve_); for (size_t i = size_; i < n; ++i) { new (&data_[i]) T; } for (size_t i = n; i < size_; ++i) { data_[i].~T(); } size_ = n; } // Append new elements (up to reserved size). EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void push_back(const T& t) { eigen_assert(size_ < reserve_); data_[size_++] = t; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[] (size_t i) const { eigen_assert(i < size_); return data_[i]; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[] (size_t i) { eigen_assert(i < size_); return data_[i]; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() { eigen_assert(size_ > 0); return data_[size_ - 1]; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const { eigen_assert(size_ > 0); return data_[size_ - 1]; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pop_back() { // NOTE: This does not destroy the value at the end the way // std::vector's version of pop_back() does. That happens when // the Vector is destroyed. eigen_assert(size_ > 0); size_--; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t size() const { return size_; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool empty() const { return size_ == 0; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* data() { return data_; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* data() const { return data_; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* begin() { return data_; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* end() { return data_ + size_; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* begin() const { return data_; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* end() const { return data_ + size_; } private: size_t reserve_; size_t size_; T* data_; }; } // namespace Eigen #endif // EIGEN_FIXEDSIZEVECTOR_H