Home | History | Annotate | Download | only in util
      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 (at) 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
     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
     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
     51   ~MaxSizeVector() {
     52     for (size_t i = 0; i < size_; ++i) {
     53       data_[i].~T();
     54     }
     55     internal::aligned_free(data_);
     56   }
     57 
     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
     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
     89   T& back() {
     90     eigen_assert(size_ > 0);
     91     return data_[size_ - 1];
     92   }
     93 
     94   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     95   const T& back() const {
     96     eigen_assert(size_ > 0);
     97     return data_[size_ - 1];
     98   }
     99 
    100   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    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
    110   size_t size() const { return size_; }
    111 
    112   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    113   bool empty() const { return size_ == 0; }
    114 
    115   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    116   T* data() { return data_; }
    117 
    118   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    119   const T* data() const { return data_; }
    120 
    121   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    122   T* begin() { return data_; }
    123 
    124   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    125   T* end() { return data_ + size_; }
    126 
    127   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    128   const T* begin() const { return data_; }
    129 
    130   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    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