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> class array {
18 
19  public:
20  typedef T value_type;
21  typedef T* iterator;
22  typedef const T* const_iterator;
23 
25  EIGEN_STRONG_INLINE iterator begin() { return values; }
27  EIGEN_STRONG_INLINE const_iterator begin() const { return values; }
28 
30  EIGEN_STRONG_INLINE iterator end() { return values + n; }
32  EIGEN_STRONG_INLINE const_iterator end() const { return values + n; }
33 
34 
35 #if !defined(EIGEN_GPUCC)
36  typedef std::reverse_iterator<iterator> reverse_iterator;
37  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
38 
40  EIGEN_STRONG_INLINE reverse_iterator rbegin() { return reverse_iterator(end());}
42  EIGEN_STRONG_INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
43 
45  EIGEN_STRONG_INLINE reverse_iterator rend() { return reverse_iterator(begin()); }
47  EIGEN_STRONG_INLINE const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
48 #endif
49 
51  EIGEN_STRONG_INLINE T& operator[] (size_t index) { eigen_internal_assert(index < size()); return values[index]; }
53  EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { eigen_internal_assert(index < size()); return values[index]; }
54 
56  EIGEN_STRONG_INLINE T& at(size_t index) { eigen_assert(index < size()); return values[index]; }
58  EIGEN_STRONG_INLINE const T& at(size_t index) const { eigen_assert(index < size()); return values[index]; }
59 
61  EIGEN_STRONG_INLINE T& front() { return values[0]; }
63  EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
64 
66  EIGEN_STRONG_INLINE T& back() { return values[n-1]; }
68  EIGEN_STRONG_INLINE const T& back() const { return values[n-1]; }
69 
70 
72  static std::size_t size() { return n; }
73 
74  T values[n];
75 
77  EIGEN_STRONG_INLINE array() { }
79  EIGEN_STRONG_INLINE array(const T& v) {
80  EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
81  values[0] = v;
82  }
84  EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
85  EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
86  values[0] = v1;
87  values[1] = v2;
88  }
90  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
91  EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE)
92  values[0] = v1;
93  values[1] = v2;
94  values[2] = v3;
95  }
97  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3,
98  const T& v4) {
99  EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE)
100  values[0] = v1;
101  values[1] = v2;
102  values[2] = v3;
103  values[3] = v4;
104  }
106  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
107  const T& v5) {
108  EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE)
109  values[0] = v1;
110  values[1] = v2;
111  values[2] = v3;
112  values[3] = v4;
113  values[4] = v5;
114  }
116  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
117  const T& v5, const T& v6) {
118  EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE)
119  values[0] = v1;
120  values[1] = v2;
121  values[2] = v3;
122  values[3] = v4;
123  values[4] = v5;
124  values[5] = v6;
125  }
127  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
128  const T& v5, const T& v6, const T& v7) {
129  EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE)
130  values[0] = v1;
131  values[1] = v2;
132  values[2] = v3;
133  values[3] = v4;
134  values[4] = v5;
135  values[5] = v6;
136  values[6] = v7;
137  }
139  EIGEN_STRONG_INLINE array(
140  const T& v1, const T& v2, const T& v3, const T& v4,
141  const T& v5, const T& v6, const T& v7, const T& v8) {
142  EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE)
143  values[0] = v1;
144  values[1] = v2;
145  values[2] = v3;
146  values[3] = v4;
147  values[4] = v5;
148  values[5] = v6;
149  values[6] = v7;
150  values[7] = v8;
151  }
152 
154  EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
155  eigen_assert(l.size() == n);
156  internal::smart_copy(l.begin(), l.end(), values);
157  }
158 };
159 
160 
161 // Specialize array for zero size
162 template <typename T> class array<T, 0> {
163  public:
165  EIGEN_STRONG_INLINE T& operator[] (size_t) {
166  eigen_assert(false && "Can't index a zero size array");
167  return dummy;
168  }
170  EIGEN_STRONG_INLINE const T& operator[] (size_t) const {
171  eigen_assert(false && "Can't index a zero size array");
172  return dummy;
173  }
174 
176  EIGEN_STRONG_INLINE T& front() {
177  eigen_assert(false && "Can't index a zero size array");
178  return dummy;
179  }
181  EIGEN_STRONG_INLINE const T& front() const {
182  eigen_assert(false && "Can't index a zero size array");
183  return dummy;
184  }
186  EIGEN_STRONG_INLINE T& back() {
187  eigen_assert(false && "Can't index a zero size array");
188  return dummy;
189  }
191  EIGEN_STRONG_INLINE const T& back() const {
192  eigen_assert(false && "Can't index a zero size array");
193  return dummy;
194  }
195 
196  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
197 
199  EIGEN_STRONG_INLINE array() : dummy() { }
200 
201  EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
203  eigen_assert(l.size() == 0);
204  }
205 
206  private:
207  T dummy;
208 };
209 
210 // Comparison operator
211 // Todo: implement !=, <, <=, >, and >=
212 template<class T, std::size_t N>
213 EIGEN_DEVICE_FUNC bool operator==(const array<T,N>& lhs, const array<T,N>& rhs) {
214  for (std::size_t i = 0; i < N; ++i) {
215  if (lhs[i] != rhs[i]) {
216  return false;
217  }
218  }
219  return true;
220 }
221 
222 
223 namespace internal {
224 template<std::size_t I_, class T, std::size_t N>
225 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) {
226  return a[I_];
227 }
228 template<std::size_t I_, class T, std::size_t N>
229 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
230  return a[I_];
231 }
232 
233 template<class T, std::size_t N> struct array_size<array<T,N> > {
234  enum { value = N };
235 };
236 template<class T, std::size_t N> struct array_size<array<T,N>& > {
237  enum { value = N };
238 };
239 template<class T, std::size_t N> struct array_size<const array<T,N> > {
240  enum { value = N };
241 };
242 template<class T, std::size_t N> struct array_size<const array<T,N>& > {
243  enum { value = N };
244 };
245 
246 } // end namespace internal
247 } // end namespace Eigen
248 
249 #else
250 
251 // The compiler supports c++11, and we're not targeting cuda: use std::array as Eigen::array
252 #include <array>
253 
254 namespace Eigen {
255 
256 template <typename T, std::size_t N> using array = std::array<T, N>;
257 
258 namespace internal {
259 /* std::get is only constexpr in C++14, not yet in C++11
260  * - libstdc++ from version 4.7 onwards has it nevertheless,
261  * so use that
262  * - libstdc++ older versions: use _M_instance directly
263  * - libc++ all versions so far: use __elems_ directly
264  * - all other libs: use std::get to be portable, but
265  * this may not be constexpr
266  */
267 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
268 #define STD_GET_ARR_HACK a._M_instance[I_]
269 #elif defined(_LIBCPP_VERSION)
270 #define STD_GET_ARR_HACK a.__elems_[I_]
271 #else
272 #define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
273 #endif
274 
275 template<std::size_t I_, class T, std::size_t N> constexpr inline T& array_get(std::array<T,N>& a) { return (T&) STD_GET_ARR_HACK; }
276 template<std::size_t I_, class T, std::size_t N> constexpr inline T&& array_get(std::array<T,N>&& a) { return (T&&) STD_GET_ARR_HACK; }
277 template<std::size_t I_, class T, std::size_t N> constexpr inline T const& array_get(std::array<T,N> const& a) { return (T const&) STD_GET_ARR_HACK; }
278 
279 #undef STD_GET_ARR_HACK
280 
281 } // end namespace internal
282 } // end namespace Eigen
283 
284 #endif
285 
286 #endif // EIGEN_EMULATE_ARRAY_H
Array< int, Dynamic, 1 > v
int n
#define STD_GET_ARR_HACK
Definition: EmulateArray.h:272
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:836
#define eigen_internal_assert(x)
Definition: Macros.h:908
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:957
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define eigen_assert(x)
Definition: Macros.h:902
#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())
static const lastp1_t end
bool operator==(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:316
constexpr T & array_get(std::array< T, N > &a)
Definition: EmulateArray.h:275
void smart_copy(const T *start, const T *end, T *target)
Definition: Memory.h:601
: InteropHeaders
Definition: Core:139
std::array< T, N > array
Definition: EmulateArray.h:256