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 
10 #ifndef EIGEN_EMULATE_ARRAY_H
11 #define EIGEN_EMULATE_ARRAY_H
12 
13 
14 
15 // The array class is only available starting with cxx11. Emulate our own here
16 // if needed.
17 // Moreover, CUDA doesn't support the STL containers, so we use our own instead.
18 #if __cplusplus <= 199711L || defined(__CUDACC__) || defined(EIGEN_AVOID_STL_ARRAY)
19 
20 namespace Eigen {
21 template <typename T, size_t n> class array {
22  public:
23  EIGEN_DEVICE_FUNC
24  EIGEN_STRONG_INLINE T& operator[] (size_t index) { return values[index]; }
25  EIGEN_DEVICE_FUNC
26  EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { return values[index]; }
27 
28  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
29  static std::size_t size() { return n; }
30 
31  T values[n];
32 
33  EIGEN_DEVICE_FUNC
34  EIGEN_STRONG_INLINE array() { }
35  explicit EIGEN_DEVICE_FUNC
36  EIGEN_STRONG_INLINE array(const T& v) {
37  EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
38  values[0] = v;
39  }
40  EIGEN_DEVICE_FUNC
41  EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
42  EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
43  values[0] = v1;
44  values[1] = v2;
45  }
46  EIGEN_DEVICE_FUNC
47  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
48  EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE)
49  values[0] = v1;
50  values[1] = v2;
51  values[2] = v3;
52  }
53  EIGEN_DEVICE_FUNC
54  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3,
55  const T& v4) {
56  EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE)
57  values[0] = v1;
58  values[1] = v2;
59  values[2] = v3;
60  values[3] = v4;
61  }
62  EIGEN_DEVICE_FUNC
63  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
64  const T& v5) {
65  EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE)
66  values[0] = v1;
67  values[1] = v2;
68  values[2] = v3;
69  values[3] = v4;
70  values[4] = v5;
71  }
72  EIGEN_DEVICE_FUNC
73  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
74  const T& v5, const T& v6) {
75  EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE)
76  values[0] = v1;
77  values[1] = v2;
78  values[2] = v3;
79  values[3] = v4;
80  values[4] = v5;
81  values[5] = v6;
82  }
83  EIGEN_DEVICE_FUNC
84  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
85  const T& v5, const T& v6, const T& v7) {
86  EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE)
87  values[0] = v1;
88  values[1] = v2;
89  values[2] = v3;
90  values[3] = v4;
91  values[4] = v5;
92  values[5] = v6;
93  values[6] = v7;
94  }
95  EIGEN_DEVICE_FUNC
96  EIGEN_STRONG_INLINE array(
97  const T& v1, const T& v2, const T& v3, const T& v4,
98  const T& v5, const T& v6, const T& v7, const T& v8) {
99  EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE)
100  values[0] = v1;
101  values[1] = v2;
102  values[2] = v3;
103  values[3] = v4;
104  values[4] = v5;
105  values[5] = v6;
106  values[6] = v7;
107  values[7] = v8;
108  }
109 
110 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
111  EIGEN_DEVICE_FUNC
112  EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
113  eigen_assert(l.size() == n);
114  internal::smart_copy(l.begin(), l.end(), values);
115  }
116 #endif
117 };
118 
119 
120 // Specialize array for zero size
121 template <typename T> class array<T, 0> {
122  public:
123  EIGEN_DEVICE_FUNC
124  EIGEN_STRONG_INLINE T& operator[] (size_t) {
125  eigen_assert(false && "Can't index a zero size array");
126  return *static_cast<T*>(NULL);
127  }
128 
129  EIGEN_DEVICE_FUNC
130  EIGEN_STRONG_INLINE const T& operator[] (size_t) const {
131  eigen_assert(false && "Can't index a zero size array");
132  return *static_cast<const T*>(NULL);
133  }
134 
135  static EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
136 
137  EIGEN_DEVICE_FUNC
138  EIGEN_STRONG_INLINE array() { }
139 
140 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
141  array(std::initializer_list<T> l) {
142  eigen_assert(l.size() == 0);
143  }
144 #endif
145 };
146 
147 namespace internal {
148 template<std::size_t I, class T, std::size_t N>
149 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) {
150  return a[I];
151 }
152 template<std::size_t I, class T, std::size_t N>
153 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
154  return a[I];
155 }
156 
157 template <typename T> struct array_size;
158 template<class T, std::size_t N> struct array_size<array<T,N> > {
159  static const size_t value = N;
160 };
161 template <typename T> struct array_size;
162 template<class T, std::size_t N> struct array_size<array<T,N>& > {
163  static const size_t value = N;
164 };
165 template <typename T> struct array_size;
166 template<class T, std::size_t N> struct array_size<const array<T,N> > {
167  static const size_t value = N;
168 };
169 template <typename T> struct array_size;
170 template<class T, std::size_t N> struct array_size<const array<T,N>& > {
171  static const size_t value = N;
172 };
173 
174 } // end namespace internal
175 } // end namespace Eigen
176 
177 #else
178 
179 // The compiler supports c++11, and we're not targetting cuda: use std::array as Eigen array
180 #include <array>
181 namespace Eigen {
182 
183 template <typename T, std::size_t N> using array = std::array<T, N>;
184 
185 namespace internal {
186 /* std::get is only constexpr in C++14, not yet in C++11
187  * - libstdc++ from version 4.7 onwards has it nevertheless,
188  * so use that
189  * - libstdc++ older versions: use _M_instance directly
190  * - libc++ all versions so far: use __elems_ directly
191  * - all other libs: use std::get to be portable, but
192  * this may not be constexpr
193  */
194 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
195 #define STD_GET_ARR_HACK a._M_instance[I]
196 #elif defined(_LIBCPP_VERSION)
197 #define STD_GET_ARR_HACK a.__elems_[I]
198 #else
199 #define STD_GET_ARR_HACK std::template get<I, T, N>(a)
200 #endif
201 
202 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; }
203 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; }
204 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; }
205 
206 #undef STD_GET_ARR_HACK
207 
208 template <typename T> struct array_size;
209 template<class T, std::size_t N> struct array_size<const std::array<T,N> > {
210  static const size_t value = N;
211 };
212 template <typename T> struct array_size;
213 template<class T, std::size_t N> struct array_size<std::array<T,N> > {
214  static const size_t value = N;
215 };
216 } // end namespace internal
217 } // end namespace Eigen
218 
219 #endif
220 
221 
222 
223 
224 
225 #endif // EIGEN_EMULATE_ARRAY_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13