• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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