xref: /aosp_15_r20/external/eigen/unsupported/Eigen/CXX11/src/util/MaxSizeVector.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2014 Benoit Steiner <[email protected]>
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   static const size_t alignment = EIGEN_PLAIN_ENUM_MAX(EIGEN_ALIGNOF(T), sizeof(void*));
33  public:
34   // Construct a new MaxSizeVector, reserve n elements.
35   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
MaxSizeVector(size_t n)36   explicit MaxSizeVector(size_t n)
37       : reserve_(n), size_(0),
38         data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {
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::handmade_aligned_malloc(n * sizeof(T), alignment))) {
47     size_t i = 0;
48     EIGEN_TRY
49     {
50       for(; i < size_; ++i) { new (&data_[i]) T(init); }
51     }
52     EIGEN_CATCH(...)
53     {
54       // Construction failed, destruct in reverse order:
55       for(; (i+1) > 0; --i) { data_[i-1].~T(); }
56       internal::handmade_aligned_free(data_);
57       EIGEN_THROW;
58     }
59   }
60 
61   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
~MaxSizeVector()62   ~MaxSizeVector() {
63     for (size_t i = size_; i > 0; --i) {
64       data_[i-1].~T();
65     }
66     internal::handmade_aligned_free(data_);
67   }
68 
resize(size_t n)69   void resize(size_t n) {
70     eigen_assert(n <= reserve_);
71     for (; size_ < n; ++size_) {
72       new (&data_[size_]) T;
73     }
74     for (; size_ > n; --size_) {
75       data_[size_-1].~T();
76     }
77     eigen_assert(size_ == n);
78   }
79 
80   // Append new elements (up to reserved size).
81   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
push_back(const T & t)82   void push_back(const T& t) {
83     eigen_assert(size_ < reserve_);
84     new (&data_[size_++]) T(t);
85   }
86 
87   // For C++03 compatibility this only takes one argument
88   template<class X>
89   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
emplace_back(const X & x)90   void emplace_back(const X& x) {
91     eigen_assert(size_ < reserve_);
92     new (&data_[size_++]) T(x);
93   }
94 
95 
96   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
97   const T& operator[] (size_t i) const {
98     eigen_assert(i < size_);
99     return data_[i];
100   }
101 
102   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
103   T& operator[] (size_t i) {
104     eigen_assert(i < size_);
105     return data_[i];
106   }
107 
108   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
back()109   T& back() {
110     eigen_assert(size_ > 0);
111     return data_[size_ - 1];
112   }
113 
114   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
back()115   const T& back() const {
116     eigen_assert(size_ > 0);
117     return data_[size_ - 1];
118   }
119 
120   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
pop_back()121   void pop_back() {
122     eigen_assert(size_ > 0);
123     data_[--size_].~T();
124   }
125 
126   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
size()127   size_t size() const { return size_; }
128 
129   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
empty()130   bool empty() const { return size_ == 0; }
131 
132   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
data()133   T* data() { return data_; }
134 
135   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
data()136   const T* data() const { return data_; }
137 
138   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
begin()139   T* begin() { return data_; }
140 
141   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
end()142   T* end() { return data_ + size_; }
143 
144   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
begin()145   const T* begin() const { return data_; }
146 
147   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
end()148   const T* end() const { return data_ + size_; }
149 
150  private:
151   size_t reserve_;
152   size_t size_;
153   T* data_;
154 };
155 
156 }  // namespace Eigen
157 
158 #endif  // EIGEN_FIXEDSIZEVECTOR_H
159