EmulateCXX11Meta.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_CXX11_META_H
11 #define EIGEN_EMULATE_CXX11_META_H
12 
13 
14 
15 namespace Eigen {
16 
17 // The array class is only available starting with cxx11. Emulate our own here
18 // if needed
19 template <typename T, size_t n> class array {
20  public:
21  EIGEN_DEVICE_FUNC
22  EIGEN_STRONG_INLINE T& operator[] (size_t index) { return values[index]; }
23  EIGEN_DEVICE_FUNC
24  EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { return values[index]; }
25 
26  static const std::size_t size() { return n; }
27 
28  T values[n];
29 
30  EIGEN_DEVICE_FUNC
31  EIGEN_STRONG_INLINE array() { }
32  explicit EIGEN_DEVICE_FUNC
33  EIGEN_STRONG_INLINE array(const T& v) {
34  EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
35  values[0] = v;
36  }
37  EIGEN_DEVICE_FUNC
38  EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
39  EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
40  values[0] = v1;
41  values[1] = v2;
42  }
43  EIGEN_DEVICE_FUNC
44  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
45  EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE)
46  values[0] = v1;
47  values[1] = v2;
48  values[2] = v3;
49  }
50  EIGEN_DEVICE_FUNC
51  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3,
52  const T& v4) {
53  EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE)
54  values[0] = v1;
55  values[1] = v2;
56  values[2] = v3;
57  values[3] = v4;
58  }
59  EIGEN_DEVICE_FUNC
60  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
61  const T& v5) {
62  EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE)
63  values[0] = v1;
64  values[1] = v2;
65  values[2] = v3;
66  values[3] = v4;
67  values[4] = v5;
68  }
69  EIGEN_DEVICE_FUNC
70  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
71  const T& v5, const T& v6) {
72  EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE)
73  values[0] = v1;
74  values[1] = v2;
75  values[2] = v3;
76  values[3] = v4;
77  values[4] = v5;
78  values[5] = v6;
79  }
80  EIGEN_DEVICE_FUNC
81  EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
82  const T& v5, const T& v6, const T& v7) {
83  EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE)
84  values[0] = v1;
85  values[1] = v2;
86  values[2] = v3;
87  values[3] = v4;
88  values[4] = v5;
89  values[5] = v6;
90  values[6] = v7;
91  }
92  EIGEN_DEVICE_FUNC
93  EIGEN_STRONG_INLINE array(
94  const T& v1, const T& v2, const T& v3, const T& v4,
95  const T& v5, const T& v6, const T& v7, const T& v8) {
96  EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE)
97  values[0] = v1;
98  values[1] = v2;
99  values[2] = v3;
100  values[3] = v4;
101  values[4] = v5;
102  values[5] = v6;
103  values[6] = v7;
104  values[7] = v8;
105  }
106 
107 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
108  array(std::initializer_list<T> l) {
109  eigen_assert(l.size() == n);
110  internal::smart_copy(l.begin(), l.end(), values);
111  }
112 #endif
113 };
114 
115 
116 namespace internal {
117 
124 struct empty_list { static const std::size_t count = 0; };
125 
126 template<typename T, typename Tail=empty_list> struct type_list {
127  typedef T HeadType;
128  typedef Tail TailType;
129  static const T head;
130  static const Tail tail;
131  static const std::size_t count = 1 + Tail::count;
132 };
133 
134 struct null_type { };
135 
136 template<typename T1 = null_type, typename T2 = null_type, typename T3 = null_type,
137  typename T4 = null_type, typename T5 = null_type, typename T6 = null_type,
138  typename T7 = null_type, typename T8 = null_type>
139 struct make_type_list {
140  typedef typename make_type_list<T2, T3, T4, T5, T6, T7, T8>::type tailresult;
141 
142  typedef type_list<T1, tailresult> type;
143 };
144 
145 template<> struct make_type_list<> {
146  typedef empty_list type;
147 };
148 
149 
150 template <std::size_t index, class TList> struct get_type;
151 
152 template <class Head, class Tail>
153 struct get_type<0, type_list<Head, Tail> >
154 {
155  typedef Head type;
156 };
157 
158 template <std::size_t i, class Head, class Tail>
159 struct get_type<i, type_list<Head, Tail> >
160 {
161  typedef typename get_type<i-1, Tail>::type type;
162 };
163 
164 
165 /* numeric list */
166 template <typename T, T n>
167 struct type2val {
168  typedef T type;
169  static const T value = n;
170 };
171 
172 
173 template<typename T, size_t n, T V> struct gen_numeric_list_repeated;
174 
175 template<typename T, T V> struct gen_numeric_list_repeated<T, 1, V> {
176  typedef typename make_type_list<type2val<T, V> >::type type;
177 };
178 
179 template<typename T, T V> struct gen_numeric_list_repeated<T, 2, V> {
180  typedef typename make_type_list<type2val<T, V>, type2val<T, V> >::type type;
181 };
182 
183 template<typename T, T V> struct gen_numeric_list_repeated<T, 3, V> {
184  typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type;
185 };
186 
187 template<typename T, T V> struct gen_numeric_list_repeated<T, 4, V> {
188  typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type;
189 };
190 
191 template<typename T, T V> struct gen_numeric_list_repeated<T, 5, V> {
192  typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type;
193 };
194 
195 template<typename T, T V> struct gen_numeric_list_repeated<T, 6, V> {
196  typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>,
197  type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type;
198 };
199 
200 template<typename T, T V> struct gen_numeric_list_repeated<T, 7, V> {
201  typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>,
202  type2val<T, V>, type2val<T, V>, type2val<T, V>,
203  type2val<T, V> >::type type;
204 };
205 
206 template<typename T, T V> struct gen_numeric_list_repeated<T, 8, V> {
207  typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>,
208  type2val<T, V>, type2val<T, V>, type2val<T, V>,
209  type2val<T, V>, type2val<T, V> >::type type;
210 };
211 
212 
213 template <std::size_t index, class NList> struct get;
214 
215 template <std::size_t i>
216 struct get<i, empty_list>
217 {
218  get() { eigen_assert(false && "index overflow"); }
219  typedef void type;
220  static const char value = '\0';
221 };
222 
223 template <std::size_t i, class Head>
224 struct get<i, type_list<Head, empty_list> >
225 {
226  get() { eigen_assert(false && "index overflow"); }
227  typedef void type;
228  static const char value = '\0';
229 };
230 
231 template <class Head>
232 struct get<0, type_list<Head, empty_list> >
233 {
234  typedef typename Head::type type;
235  static const type value = Head::value;
236 };
237 
238 template <class Head, class Tail>
239 struct get<0, type_list<Head, Tail> >
240 {
241  typedef typename Head::type type;
242  static const type value = Head::value;
243 };
244 
245 template <std::size_t i, class Head, class Tail>
246 struct get<i, type_list<Head, Tail> >
247 {
248  typedef typename Tail::HeadType::type type;
249  static const type value = get<i-1, Tail>::value;
250 };
251 
252 
253 template <class NList> struct arg_prod {
254  static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod<typename NList::TailType>::value;
255 };
256 template <> struct arg_prod<empty_list> {
257  static const int value = 1;
258 };
259 
260 
261 template<int n, typename t>
262 array<t, n> repeat(t v) {
263  array<t, n> array;
264  array.fill(v);
265  return array;
266 }
267 
268 template<std::size_t I, class Head, class Tail>
269 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(type_list<Head, Tail>&) {
270  return get<I, type_list<Head, Tail> >::value;
271 }
272 template<std::size_t I, class Head, class Tail>
273 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(const type_list<Head, Tail>&) {
274  return get<I, type_list<Head, Tail> >::value;
275 }
276 
277 template <class NList>
278 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NList::HeadType::type array_prod(const NList&) {
279  return arg_prod<NList>::value;
280 }
281 
282 template<std::size_t n, typename t>
283 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array<t, n>& a) {
284  t prod = 1;
285  for (size_t i = 0; i < n; ++i) { prod *= a[i]; }
286  return prod;
287 }
288 template<typename t>
289 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array<t, 0>& /*a*/) {
290  return 0;
291 }
292 
293 template<typename t>
294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) {
295  eigen_assert(a.size() > 0);
296  t prod = 1;
297  for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; }
298  return prod;
299 }
300 
301 template<std::size_t I, class T, std::size_t N>
302 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) {
303  return a[I];
304 }
305 template<std::size_t I, class T, std::size_t N>
306 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
307  return a[I];
308 }
309 
310 template<std::size_t I, class T>
311 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(std::vector<T>& a) {
312  return a[I];
313 }
314 template<std::size_t I, class T>
315 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const std::vector<T>& a) {
316  return a[I];
317 }
318 
319 template <typename T> struct array_size;
320 template<class T, std::size_t N> struct array_size<array<T,N> > {
321  static const size_t value = N;
322 };
323 template <typename T> struct array_size;
324 template<class T, std::size_t N> struct array_size<array<T,N>& > {
325  static const size_t value = N;
326 };
327 template <typename T> struct array_size;
328 template<class T, std::size_t N> struct array_size<const array<T,N> > {
329  static const size_t value = N;
330 };
331 template <typename T> struct array_size;
332 template<class T, std::size_t N> struct array_size<const array<T,N>& > {
333  static const size_t value = N;
334 };
335 
336 struct sum_op {
337  template<typename A, typename B> static inline bool run(A a, B b) { return a + b; }
338 };
339 struct product_op {
340  template<typename A, typename B> static inline bool run(A a, B b) { return a * b; }
341 };
342 
343 struct logical_and_op {
344  template<typename A, typename B> static inline bool run(A a, B b) { return a && b; }
345 };
346 struct logical_or_op {
347  template<typename A, typename B> static inline bool run(A a, B b) { return a || b; }
348 };
349 
350 struct equal_op {
351  template<typename A, typename B> static inline bool run(A a, B b) { return a == b; }
352 };
353 struct not_equal_op {
354  template<typename A, typename B> static inline bool run(A a, B b) { return a != b; }
355 };
356 struct lesser_op {
357  template<typename A, typename B> static inline bool run(A a, B b) { return a < b; }
358 };
359 struct lesser_equal_op {
360  template<typename A, typename B> static inline bool run(A a, B b) { return a <= b; }
361 };
362 
363 struct greater_op {
364  template<typename A, typename B> static inline bool run(A a, B b) { return a > b; }
365 };
366 struct greater_equal_op {
367  template<typename A, typename B> static inline bool run(A a, B b) { return a >= b; }
368 };
369 
370 struct not_op {
371  template<typename A> static inline bool run(A a) { return !a; }
372 };
373 struct negation_op {
374  template<typename A> static inline bool run(A a) { return -a; }
375 };
376 struct greater_equal_zero_op {
377  template<typename A> static inline bool run(A a) { return a >= 0; }
378 };
379 
380 
381 template<typename Reducer, typename Op, typename A, std::size_t N>
382 struct ArrayApplyAndReduce {
383  static inline bool run(const array<A, N>& a) {
384  EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE);
385  bool result = Reducer::run(Op::run(a[0]), Op::run(a[1]));
386  for (size_t i = 2; i < N; ++i) {
387  result = Reducer::run(result, Op::run(a[i]));
388  }
389  return result;
390  }
391 };
392 
393 template<typename Reducer, typename Op, typename A>
394 struct ArrayApplyAndReduce<Reducer, Op, A, 1> {
395  static inline bool run(const array<A, 1>& a) {
396  return Op::run(a[0]);
397  }
398 };
399 
400 template<typename Reducer, typename Op, typename A, std::size_t N>
401 inline bool array_apply_and_reduce(const array<A, N>& a) {
402  return ArrayApplyAndReduce<Reducer, Op, A, N>::run(a);
403 }
404 
405 template<typename Reducer, typename Op, typename A, typename B, std::size_t N>
406 struct ArrayZipAndReduce {
407  static inline bool run(const array<A, N>& a, const array<B, N>& b) {
408  EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE);
409  bool result = Reducer::run(Op::run(a[0], b[0]), Op::run(a[1], b[1]));
410  for (size_t i = 2; i < N; ++i) {
411  result = Reducer::run(result, Op::run(a[i], b[i]));
412  }
413  return result;
414  }
415 };
416 
417 template<typename Reducer, typename Op, typename A, typename B>
418 struct ArrayZipAndReduce<Reducer, Op, A, B, 1> {
419  static inline bool run(const array<A, 1>& a, const array<B, 1>& b) {
420  return Op::run(a[0], b[0]);
421  }
422 };
423 
424 template<typename Reducer, typename Op, typename A, typename B, std::size_t N>
425 inline bool array_zip_and_reduce(const array<A, N>& a, const array<B, N>& b) {
426  return ArrayZipAndReduce<Reducer, Op, A, B, N>::run(a, b);
427 }
428 
429 } // end namespace internal
430 
431 } // end namespace Eigen
432 
433 
434 
435 #endif // EIGEN_EMULATE_CXX11_META_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13