EmulateArray.h
Go to the documentation of this file.
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_EMULATE_ARRAY_H
11 #define EIGEN_EMULATE_ARRAY_H
12 
13 // CUDA doesn't support the STL containers, so we use our own instead.
14 #if defined(EIGEN_GPUCC) || defined(EIGEN_AVOID_STL_ARRAY)
15 
16 namespace Eigen {
17 template <typename T, size_t n>
18 class array {
19  public:
20  typedef T value_type;
21  typedef T* iterator;
22  typedef const T* const_iterator;
23 
24  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE iterator begin() { return values; }
25  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_iterator begin() const { return values; }
26 
27  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE iterator end() { return values + n; }
28  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_iterator end() const { return values + n; }
29 
30  typedef std::reverse_iterator<iterator> reverse_iterator;
31  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
32 
33  EIGEN_STRONG_INLINE reverse_iterator rbegin() { return reverse_iterator(end()); }
34  EIGEN_STRONG_INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
35 
36  EIGEN_STRONG_INLINE reverse_iterator rend() { return reverse_iterator(begin()); }
37  EIGEN_STRONG_INLINE const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
38 
39  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t index) {
40  eigen_internal_assert(index < size());
41  return values[index];
42  }
43  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t index) const {
44  eigen_internal_assert(index < size());
45  return values[index];
46  }
47 
48  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& at(size_t index) {
49  eigen_assert(index < size());
50  return values[index];
51  }
52  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& at(size_t index) const {
53  eigen_assert(index < size());
54  return values[index];
55  }
56 
57  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& front() { return values[0]; }
58  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
59 
60  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() { return values[n - 1]; }
61  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const { return values[n - 1]; }
62 
63  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static std::size_t size() { return n; }
64 
65  T values[n];
66 
69  EIGEN_STATIC_ASSERT(n == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
70  values[0] = v;
71  }
73  EIGEN_STATIC_ASSERT(n == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
74  values[0] = v1;
75  values[1] = v2;
76  }
77  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
78  EIGEN_STATIC_ASSERT(n == 3, YOU_MADE_A_PROGRAMMING_MISTAKE)
79  values[0] = v1;
80  values[1] = v2;
81  values[2] = v3;
82  }
83  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4) {
84  EIGEN_STATIC_ASSERT(n == 4, YOU_MADE_A_PROGRAMMING_MISTAKE)
85  values[0] = v1;
86  values[1] = v2;
87  values[2] = v3;
88  values[3] = v4;
89  }
90  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) {
91  EIGEN_STATIC_ASSERT(n == 5, YOU_MADE_A_PROGRAMMING_MISTAKE)
92  values[0] = v1;
93  values[1] = v2;
94  values[2] = v3;
95  values[3] = v4;
96  values[4] = v5;
97  }
98  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
99  const T& v6) {
100  EIGEN_STATIC_ASSERT(n == 6, YOU_MADE_A_PROGRAMMING_MISTAKE)
101  values[0] = v1;
102  values[1] = v2;
103  values[2] = v3;
104  values[3] = v4;
105  values[4] = v5;
106  values[5] = v6;
107  }
108  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
109  const T& v6, const T& v7) {
110  EIGEN_STATIC_ASSERT(n == 7, YOU_MADE_A_PROGRAMMING_MISTAKE)
111  values[0] = v1;
112  values[1] = v2;
113  values[2] = v3;
114  values[3] = v4;
115  values[4] = v5;
116  values[5] = v6;
117  values[6] = v7;
118  }
119  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
120  const T& v6, const T& v7, const T& v8) {
121  EIGEN_STATIC_ASSERT(n == 8, YOU_MADE_A_PROGRAMMING_MISTAKE)
122  values[0] = v1;
123  values[1] = v2;
124  values[2] = v3;
125  values[3] = v4;
126  values[4] = v5;
127  values[5] = v6;
128  values[6] = v7;
129  values[7] = v8;
130  }
131 
132  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
133  eigen_assert(l.size() == n);
134  internal::smart_copy(l.begin(), l.end(), values);
135  }
136 };
137 
138 // Specialize array for zero size
139 template <typename T>
140 class array<T, 0> {
141  public:
142  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t) {
143  eigen_assert(false && "Can't index a zero size array");
144  return dummy;
145  }
146  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t) const {
147  eigen_assert(false && "Can't index a zero size array");
148  return dummy;
149  }
150 
152  eigen_assert(false && "Can't index a zero size array");
153  return dummy;
154  }
155  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& front() const {
156  eigen_assert(false && "Can't index a zero size array");
157  return dummy;
158  }
160  eigen_assert(false && "Can't index a zero size array");
161  return dummy;
162  }
163  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const {
164  eigen_assert(false && "Can't index a zero size array");
165  return dummy;
166  }
167 
168  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
169 
171 
172  EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
174  eigen_assert(l.size() == 0);
175  }
176 
177  private:
178  T dummy;
179 };
180 
181 // Comparison operator
182 // Todo: implement !=, <, <=, >, and >=
183 template <class T, std::size_t N>
184 EIGEN_DEVICE_FUNC bool operator==(const array<T, N>& lhs, const array<T, N>& rhs) {
185  for (std::size_t i = 0; i < N; ++i) {
186  if (lhs[i] != rhs[i]) {
187  return false;
188  }
189  }
190  return true;
191 }
192 
193 namespace internal {
194 template <std::size_t I_, class T, std::size_t N>
196  return a[I_];
197 }
198 template <std::size_t I_, class T, std::size_t N>
199 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T, N>& a) {
200  return a[I_];
201 }
202 
203 template <class T, std::size_t N>
204 struct array_size<array<T, N> > {
205  static constexpr Index value = N;
206 };
207 template <class T, std::size_t N>
208 struct array_size<array<T, N>&> {
209  static constexpr Index value = N;
210 };
211 template <class T, std::size_t N>
212 struct array_size<const array<T, N> > {
213  static constexpr Index value = N;
214 };
215 template <class T, std::size_t N>
216 struct array_size<const array<T, N>&> {
217  static constexpr Index value = N;
218 };
219 
220 } // end namespace internal
221 } // end namespace Eigen
222 
223 #else
224 
225 // The compiler supports c++11, and we're not targeting cuda: use std::array as Eigen::array
226 #include <array>
227 
228 namespace Eigen {
229 
230 template <typename T, std::size_t N>
231 using array = std::array<T, N>;
232 
233 namespace internal {
234 /* std::get is only constexpr in C++14, not yet in C++11
235  * - libstdc++ from version 4.7 onwards has it nevertheless,
236  * so use that
237  * - libstdc++ older versions: use _M_instance directly
238  * - libc++ all versions so far: use __elems_ directly
239  * - all other libs: use std::get to be portable, but
240  * this may not be constexpr
241  */
242 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
243 #define STD_GET_ARR_HACK a._M_instance[I_]
244 #elif defined(_LIBCPP_VERSION)
245 #define STD_GET_ARR_HACK a.__elems_[I_]
246 #else
247 #define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
248 #endif
249 
250 template <std::size_t I_, class T, std::size_t N>
251 constexpr inline T& array_get(std::array<T, N>& a) {
252  return (T&)STD_GET_ARR_HACK;
253 }
254 template <std::size_t I_, class T, std::size_t N>
255 constexpr inline T&& array_get(std::array<T, N>&& a) {
256  return (T&&)STD_GET_ARR_HACK;
257 }
258 template <std::size_t I_, class T, std::size_t N>
259 constexpr inline T const& array_get(std::array<T, N> const& a) {
260  return (T const&)STD_GET_ARR_HACK;
261 }
262 
263 #undef STD_GET_ARR_HACK
264 
265 } // end namespace internal
266 } // end namespace Eigen
267 
268 #endif
269 
270 #endif // EIGEN_EMULATE_ARRAY_H
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
#define STD_GET_ARR_HACK
Definition: EmulateArray.h:247
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:845
#define eigen_internal_assert(x)
Definition: Macros.h:916
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:966
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
Map< RowVectorXf > v2(M2.data(), M2.size())
M1<< 1, 2, 3, 4, 5, 6, 7, 8, 9;Map< RowVectorXf > v1(M1.data(), M1.size())
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
@ N
Definition: constructor.cpp:22
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
const Scalar * a
Definition: level2_cplx_impl.h:32
constexpr T & array_get(std::array< T, N > &a)
Definition: EmulateArray.h:251
EIGEN_DEVICE_FUNC void smart_copy(const T *start, const T *end, T *target)
Definition: Memory.h:569
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
std::array< T, N > array
Definition: EmulateArray.h:231
squared absolute value
Definition: GlobalFunctions.h:87
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator==(const Pair< U, V > &x, const Pair< U, V > &y)
Definition: TensorMeta.h:227
Definition: Eigen_Colamd.h:49
static constexpr Index value
Definition: Meta.h:306