Eigen  5.0.1
 
Loading...
Searching...
No Matches
EmulateArray.h
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// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_EMULATE_ARRAY_H
12#define EIGEN_EMULATE_ARRAY_H
13
14// CUDA doesn't support the STL containers, so we use our own instead.
15#if defined(EIGEN_GPUCC) || defined(EIGEN_AVOID_STL_ARRAY)
16
17namespace Eigen {
18template <typename T, size_t n>
19class array {
20 public:
21 using value_type = T;
22 using iterator = T*;
23 using const_iterator = const T*;
24
25 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE iterator begin() { return values; }
26 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_iterator begin() const { return values; }
27
28 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE iterator end() { return values + n; }
29 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_iterator end() const { return values + n; }
30
31 using reverse_iterator = std::reverse_iterator<iterator>;
32 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
33
34 EIGEN_STRONG_INLINE reverse_iterator rbegin() { return reverse_iterator(end()); }
35 EIGEN_STRONG_INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
36
37 EIGEN_STRONG_INLINE reverse_iterator rend() { return reverse_iterator(begin()); }
38 EIGEN_STRONG_INLINE const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
39
40 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t index) {
41 eigen_internal_assert(index < size());
42 return values[index];
43 }
44 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t index) const {
45 eigen_internal_assert(index < size());
46 return values[index];
47 }
48
49 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& at(size_t index) {
50 eigen_assert(index < size());
51 return values[index];
52 }
53 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& at(size_t index) const {
54 eigen_assert(index < size());
55 return values[index];
56 }
57
58 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& front() { return values[0]; }
59 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
60
61 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() { return values[n - 1]; }
62 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const { return values[n - 1]; }
63
64 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static std::size_t size() { return n; }
65
66 T values[n];
67
68 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array() {}
69 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v) {
70 EIGEN_STATIC_ASSERT(n == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
71 values[0] = v;
72 }
73 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
74 EIGEN_STATIC_ASSERT(n == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
75 values[0] = v1;
76 values[1] = v2;
77 }
78 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
79 EIGEN_STATIC_ASSERT(n == 3, YOU_MADE_A_PROGRAMMING_MISTAKE)
80 values[0] = v1;
81 values[1] = v2;
82 values[2] = v3;
83 }
84 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4) {
85 EIGEN_STATIC_ASSERT(n == 4, YOU_MADE_A_PROGRAMMING_MISTAKE)
86 values[0] = v1;
87 values[1] = v2;
88 values[2] = v3;
89 values[3] = v4;
90 }
91 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) {
92 EIGEN_STATIC_ASSERT(n == 5, YOU_MADE_A_PROGRAMMING_MISTAKE)
93 values[0] = v1;
94 values[1] = v2;
95 values[2] = v3;
96 values[3] = v4;
97 values[4] = v5;
98 }
99 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
100 const T& v6) {
101 EIGEN_STATIC_ASSERT(n == 6, YOU_MADE_A_PROGRAMMING_MISTAKE)
102 values[0] = v1;
103 values[1] = v2;
104 values[2] = v3;
105 values[3] = v4;
106 values[4] = v5;
107 values[5] = v6;
108 }
109 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
110 const T& v6, const T& v7) {
111 EIGEN_STATIC_ASSERT(n == 7, YOU_MADE_A_PROGRAMMING_MISTAKE)
112 values[0] = v1;
113 values[1] = v2;
114 values[2] = v3;
115 values[3] = v4;
116 values[4] = v5;
117 values[5] = v6;
118 values[6] = v7;
119 }
120 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
121 const T& v6, const T& v7, const T& v8) {
122 EIGEN_STATIC_ASSERT(n == 8, YOU_MADE_A_PROGRAMMING_MISTAKE)
123 values[0] = v1;
124 values[1] = v2;
125 values[2] = v3;
126 values[3] = v4;
127 values[4] = v5;
128 values[5] = v6;
129 values[6] = v7;
130 values[7] = v8;
131 }
132
133 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
134 eigen_assert(l.size() == n);
135 internal::smart_copy(l.begin(), l.end(), values);
136 }
137};
138
139// Specialize array for zero size
140template <typename T>
141class array<T, 0> {
142 public:
143 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t) {
144 eigen_assert(false && "Can't index a zero size array");
145 return dummy;
146 }
147 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t) const {
148 eigen_assert(false && "Can't index a zero size array");
149 return dummy;
150 }
151
152 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& front() {
153 eigen_assert(false && "Can't index a zero size array");
154 return dummy;
155 }
156 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& front() const {
157 eigen_assert(false && "Can't index a zero size array");
158 return dummy;
159 }
160 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() {
161 eigen_assert(false && "Can't index a zero size array");
162 return dummy;
163 }
164 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const {
165 eigen_assert(false && "Can't index a zero size array");
166 return dummy;
167 }
168
169 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
170
171 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array() : dummy() {}
172
173 EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
174 EIGEN_UNUSED_VARIABLE(l);
175 eigen_assert(l.size() == 0);
176 }
177
178 private:
179 T dummy;
180};
181
182// Comparison operator
183// Todo: implement !=, <, <=, >, and >=
184template <class T, std::size_t N>
185EIGEN_DEVICE_FUNC bool operator==(const array<T, N>& lhs, const array<T, N>& rhs) {
186 for (std::size_t i = 0; i < N; ++i) {
187 if (lhs[i] != rhs[i]) {
188 return false;
189 }
190 }
191 return true;
192}
193
194namespace internal {
195template <std::size_t I_, class T, std::size_t N>
196EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T, N>& a) {
197 return a[I_];
198}
199template <std::size_t I_, class T, std::size_t N>
200EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T, N>& a) {
201 return a[I_];
202}
203
204template <class T, std::size_t N>
205struct array_size<array<T, N> > {
206 static constexpr Index value = N;
207};
208template <class T, std::size_t N>
209struct array_size<array<T, N>&> {
210 static constexpr Index value = N;
211};
212template <class T, std::size_t N>
213struct array_size<const array<T, N> > {
214 static constexpr Index value = N;
215};
216template <class T, std::size_t N>
217struct array_size<const array<T, N>&> {
218 static constexpr Index value = N;
219};
220
221} // end namespace internal
222} // end namespace Eigen
223
224#else
225
226// Not targeting cuda: use std::array as Eigen::array.
227#include <array>
228
229namespace Eigen {
230
231template <typename T, std::size_t N>
232using array = std::array<T, N>;
233
234namespace internal {
235
236template <std::size_t I_, class T, std::size_t N>
237constexpr T& array_get(std::array<T, N>& a) {
238 return std::get<I_>(a);
239}
240template <std::size_t I_, class T, std::size_t N>
241constexpr T&& array_get(std::array<T, N>&& a) {
242 return std::get<I_>(std::move(a));
243}
244template <std::size_t I_, class T, std::size_t N>
245constexpr T const& array_get(std::array<T, N> const& a) {
246 return std::get<I_>(a);
247}
248
249} // end namespace internal
250} // end namespace Eigen
251
252#endif
253
254#endif // EIGEN_EMULATE_ARRAY_H