Eigen  5.0.1-dev+60122df6
 
Loading...
Searching...
No Matches
MoreMeta.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11#ifndef EIGEN_MOREMETA_H
12#define EIGEN_MOREMETA_H
13
14// IWYU pragma: private
15#include "../InternalHeaderCheck.h"
16
17namespace Eigen {
18
19namespace internal {
20
21template <typename... tt>
22struct type_list {
23 constexpr static int count = sizeof...(tt);
24};
25
26template <typename t, typename... tt>
27struct type_list<t, tt...> {
28 constexpr static int count = sizeof...(tt) + 1;
29 typedef t first_type;
30};
31
32template <typename T, T... nn>
33struct numeric_list {
34 constexpr static std::size_t count = sizeof...(nn);
35};
36
37template <typename T, T n, T... nn>
38struct numeric_list<T, n, nn...> {
39 static constexpr std::size_t count = sizeof...(nn) + 1;
40 static constexpr T first_value = n;
41};
42
43// Ddoxygen doesn't like the recursive definition of gen_numeric_list.
44#ifndef EIGEN_PARSED_BY_DOXYGEN
45/* numeric list constructors
46 *
47 * equivalencies:
48 * constructor result
49 * typename gen_numeric_list<int, 5>::type numeric_list<int, 0,1,2,3,4>
50 * typename gen_numeric_list_reversed<int, 5>::type numeric_list<int, 4,3,2,1,0>
51 * typename gen_numeric_list_swapped_pair<int, 5,1,2>::type numeric_list<int, 0,2,1,3,4>
52 * typename gen_numeric_list_repeated<int, 0, 5>::type numeric_list<int, 0,0,0,0,0>
53 */
54
55template <typename T, std::size_t n, T start = 0, T... ii>
56struct gen_numeric_list : gen_numeric_list<T, n - 1, start, start + n - 1, ii...> {};
57
58template <typename T, T start, T... ii>
59struct gen_numeric_list<T, 0, start, ii...> {
60 typedef numeric_list<T, ii...> type;
61};
62
63template <typename T, std::size_t n, T start = 0, T... ii>
64struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n - 1, start, ii..., start + n - 1> {};
65template <typename T, T start, T... ii>
66struct gen_numeric_list_reversed<T, 0, start, ii...> {
67 typedef numeric_list<T, ii...> type;
68};
69
70template <typename T, std::size_t n, T a, T b, T start = 0, T... ii>
71struct gen_numeric_list_swapped_pair
72 : gen_numeric_list_swapped_pair<T, n - 1, a, b, start,
73 (start + n - 1) == a ? b : ((start + n - 1) == b ? a : (start + n - 1)), ii...> {};
74template <typename T, T a, T b, T start, T... ii>
75struct gen_numeric_list_swapped_pair<T, 0, a, b, start, ii...> {
76 typedef numeric_list<T, ii...> type;
77};
78
79template <typename T, std::size_t n, T V, T... nn>
80struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n - 1, V, V, nn...> {};
81template <typename T, T V, T... nn>
82struct gen_numeric_list_repeated<T, 0, V, nn...> {
83 typedef numeric_list<T, nn...> type;
84};
85#else
86template <typename T, std::size_t n, T start = 0, T... ii>
87struct gen_numeric_list;
88#endif // not EIGEN_PARSED_BY_DOXYGEN
89
90/* list manipulation: concatenate */
91
92template <class a, class b>
93struct concat;
94
95template <typename... as, typename... bs>
96struct concat<type_list<as...>, type_list<bs...>> {
97 typedef type_list<as..., bs...> type;
98};
99template <typename T, T... as, T... bs>
100struct concat<numeric_list<T, as...>, numeric_list<T, bs...>> {
101 typedef numeric_list<T, as..., bs...> type;
102};
103
104template <typename... p>
105struct mconcat;
106template <typename a>
107struct mconcat<a> {
108 typedef a type;
109};
110template <typename a, typename b>
111struct mconcat<a, b> : concat<a, b> {};
112template <typename a, typename b, typename... cs>
113struct mconcat<a, b, cs...> : concat<a, typename mconcat<b, cs...>::type> {};
114
115/* list manipulation: extract slices */
116
117template <int n, typename x>
118struct take;
119
120template <int n, typename a, typename... as>
121struct take<n, type_list<a, as...>> : concat<type_list<a>, typename take<n - 1, type_list<as...>>::type> {};
122
123template <int n>
124struct take<n, type_list<>> {
125 typedef type_list<> type;
126};
127
128template <typename a, typename... as>
129struct take<0, type_list<a, as...>> {
130 typedef type_list<> type;
131};
132
133template <>
134struct take<0, type_list<>> {
135 typedef type_list<> type;
136};
137
138template <typename T, int n, T a, T... as>
139struct take<n, numeric_list<T, a, as...>>
140 : concat<numeric_list<T, a>, typename take<n - 1, numeric_list<T, as...>>::type> {};
141
142template <typename T, T a, T... as>
143struct take<0, numeric_list<T, a, as...>> {
144 typedef numeric_list<T> type;
145};
146
147template <typename T>
148struct take<0, numeric_list<T>> {
149 typedef numeric_list<T> type;
150};
151
152template <typename T, int n, T... ii>
153struct h_skip_helper_numeric;
154template <typename T, int n, T i, T... ii>
155struct h_skip_helper_numeric<T, n, i, ii...> : h_skip_helper_numeric<T, n - 1, ii...> {};
156template <typename T, T i, T... ii>
157struct h_skip_helper_numeric<T, 0, i, ii...> {
158 typedef numeric_list<T, i, ii...> type;
159};
160template <typename T, int n>
161struct h_skip_helper_numeric<T, n> {
162 typedef numeric_list<T> type;
163};
164template <typename T>
165struct h_skip_helper_numeric<T, 0> {
166 typedef numeric_list<T> type;
167};
168
169template <int n, typename... tt>
170struct h_skip_helper_type;
171template <int n, typename t, typename... tt>
172struct h_skip_helper_type<n, t, tt...> : h_skip_helper_type<n - 1, tt...> {};
173template <typename t, typename... tt>
174struct h_skip_helper_type<0, t, tt...> {
175 typedef type_list<t, tt...> type;
176};
177template <int n>
178struct h_skip_helper_type<n> {
179 typedef type_list<> type;
180};
181template <>
182struct h_skip_helper_type<0> {
183 typedef type_list<> type;
184};
185
186template <int n>
187struct h_skip {
188 template <typename T, T... ii>
189 constexpr static EIGEN_STRONG_INLINE typename h_skip_helper_numeric<T, n, ii...>::type helper(
190 numeric_list<T, ii...>) {
191 return typename h_skip_helper_numeric<T, n, ii...>::type();
192 }
193 template <typename... tt>
194 constexpr static EIGEN_STRONG_INLINE typename h_skip_helper_type<n, tt...>::type helper(type_list<tt...>) {
195 return typename h_skip_helper_type<n, tt...>::type();
196 }
197};
198
199template <int n, typename a>
200struct skip {
201 typedef decltype(h_skip<n>::helper(a())) type;
202};
203
204template <int start, int count, typename a>
205struct slice : take<count, typename skip<start, a>::type> {};
206
207/* list manipulation: retrieve single element from list */
208
209template <int n, typename x>
210struct get;
211
212template <int n, typename a, typename... as>
213struct get<n, type_list<a, as...>> : get<n - 1, type_list<as...>> {};
214template <typename a, typename... as>
215struct get<0, type_list<a, as...>> {
216 typedef a type;
217};
218
219template <typename T, int n, T a, T... as>
220struct get<n, numeric_list<T, a, as...>> : get<n - 1, numeric_list<T, as...>> {};
221template <typename T, T a, T... as>
222struct get<0, numeric_list<T, a, as...>> {
223 constexpr static T value = a;
224};
225
226template <std::size_t n, typename T, T a, T... as>
227constexpr T array_get(const numeric_list<T, a, as...>&) {
228 return get<(int)n, numeric_list<T, a, as...>>::value;
229}
230
231/* always get type, regardless of dummy; good for parameter pack expansion */
232
233template <typename T, T dummy, typename t>
234struct id_numeric {
235 typedef t type;
236};
237template <typename dummy, typename t>
238struct id_type {
239 typedef t type;
240};
241
242/* equality checking, flagged version */
243
244template <typename a, typename b>
245struct is_same_gf : is_same<a, b> {
246 constexpr static int global_flags = 0;
247};
248
249/* apply_op to list */
250
251template <bool from_left, // false
252 template <typename, typename> class op, typename additional_param, typename... values>
253struct h_apply_op_helper {
254 typedef type_list<typename op<values, additional_param>::type...> type;
255};
256template <template <typename, typename> class op, typename additional_param, typename... values>
257struct h_apply_op_helper<true, op, additional_param, values...> {
258 typedef type_list<typename op<additional_param, values>::type...> type;
259};
260
261template <bool from_left, template <typename, typename> class op, typename additional_param>
262struct h_apply_op {
263 template <typename... values>
264 constexpr static typename h_apply_op_helper<from_left, op, additional_param, values...>::type helper(
265 type_list<values...>) {
266 return typename h_apply_op_helper<from_left, op, additional_param, values...>::type();
267 }
268};
269
270template <template <typename, typename> class op, typename additional_param, typename a>
271struct apply_op_from_left {
272 typedef decltype(h_apply_op<true, op, additional_param>::helper(a())) type;
273};
274
275template <template <typename, typename> class op, typename additional_param, typename a>
276struct apply_op_from_right {
277 typedef decltype(h_apply_op<false, op, additional_param>::helper(a())) type;
278};
279
280/* see if an element is in a list */
281
282template <template <typename, typename> class test, typename check_against, typename h_list,
283 bool last_check_positive = false>
284struct contained_in_list;
285
286template <template <typename, typename> class test, typename check_against, typename h_list>
287struct contained_in_list<test, check_against, h_list, true> {
288 constexpr static bool value = true;
289};
290
291template <template <typename, typename> class test, typename check_against, typename a, typename... as>
292struct contained_in_list<test, check_against, type_list<a, as...>, false>
293 : contained_in_list<test, check_against, type_list<as...>, test<check_against, a>::value> {};
294
295template <template <typename, typename> class test, typename check_against, typename... empty>
296struct contained_in_list<test, check_against, type_list<empty...>, false> {
297 constexpr static bool value = false;
298};
299
300/* see if an element is in a list and check for global flags */
301
302template <template <typename, typename> class test, typename check_against, typename h_list, int default_flags = 0,
303 bool last_check_positive = false, int last_check_flags = default_flags>
304struct contained_in_list_gf;
305
306template <template <typename, typename> class test, typename check_against, typename h_list, int default_flags,
307 int last_check_flags>
308struct contained_in_list_gf<test, check_against, h_list, default_flags, true, last_check_flags> {
309 constexpr static bool value = true;
310 constexpr static int global_flags = last_check_flags;
311};
312
313template <template <typename, typename> class test, typename check_against, typename a, typename... as,
314 int default_flags, int last_check_flags>
315struct contained_in_list_gf<test, check_against, type_list<a, as...>, default_flags, false, last_check_flags>
316 : contained_in_list_gf<test, check_against, type_list<as...>, default_flags, test<check_against, a>::value,
317 test<check_against, a>::global_flags> {};
318
319template <template <typename, typename> class test, typename check_against, typename... empty, int default_flags,
320 int last_check_flags>
321struct contained_in_list_gf<test, check_against, type_list<empty...>, default_flags, false, last_check_flags> {
322 constexpr static bool value = false;
323 constexpr static int global_flags = default_flags;
324};
325
326/* generic reductions */
327
328template <typename Reducer, typename... Ts>
329struct reduce;
330
331template <typename Reducer>
332struct reduce<Reducer> {
333 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE int run() { return Reducer::Identity; }
334};
335
336template <typename Reducer, typename A>
337struct reduce<Reducer, A> {
338 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE A run(A a) { return a; }
339};
340
341template <typename Reducer, typename A, typename... Ts>
342struct reduce<Reducer, A, Ts...> {
343 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, Ts... ts)
344 -> decltype(Reducer::run(a, reduce<Reducer, Ts...>::run(ts...))) {
345 return Reducer::run(a, reduce<Reducer, Ts...>::run(ts...));
346 }
347};
348
349/* generic binary operations */
350
351struct sum_op {
352 template <typename A, typename B>
353 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a + b) {
354 return a + b;
355 }
356 static constexpr int Identity = 0;
357};
358struct product_op {
359 template <typename A, typename B>
360 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a * b) {
361 return a * b;
362 }
363 static constexpr int Identity = 1;
364};
365
366struct logical_and_op {
367 template <typename A, typename B>
368 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a && b) {
369 return a && b;
370 }
371};
372struct logical_or_op {
373 template <typename A, typename B>
374 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a || b) {
375 return a || b;
376 }
377};
378
379struct equal_op {
380 template <typename A, typename B>
381 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a == b) {
382 return a == b;
383 }
384};
385struct not_equal_op {
386 template <typename A, typename B>
387 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a != b) {
388 return a != b;
389 }
390};
391struct lesser_op {
392 template <typename A, typename B>
393 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a < b) {
394 return a < b;
395 }
396};
397struct lesser_equal_op {
398 template <typename A, typename B>
399 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a <= b) {
400 return a <= b;
401 }
402};
403struct greater_op {
404 template <typename A, typename B>
405 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a > b) {
406 return a > b;
407 }
408};
409struct greater_equal_op {
410 template <typename A, typename B>
411 constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a >= b) {
412 return a >= b;
413 }
414};
415
416/* generic unary operations */
417
418struct not_op {
419 template <typename A>
420 constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(!a) {
421 return !a;
422 }
423};
424struct negation_op {
425 template <typename A>
426 constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(-a) {
427 return -a;
428 }
429};
430struct greater_equal_zero_op {
431 template <typename A>
432 constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(a >= 0) {
433 return a >= 0;
434 }
435};
436
437/* reductions for lists */
438
439// using auto -> return value spec makes ICC 13.0 and 13.1 crash here, so we have to hack it
440// together in front... (13.0 doesn't work with array_prod/array_reduce/... anyway, but 13.1
441// does...
442template <typename... Ts>
443EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE decltype(reduce<product_op, Ts...>::run((*((Ts*)0))...)) arg_prod(
444 Ts... ts) {
445 return reduce<product_op, Ts...>::run(ts...);
446}
447
448template <typename... Ts>
449constexpr EIGEN_STRONG_INLINE decltype(reduce<sum_op, Ts...>::run((*((Ts*)0))...)) arg_sum(Ts... ts) {
450 return reduce<sum_op, Ts...>::run(ts...);
451}
452
453/* reverse arrays */
454
455template <typename Array, int... n>
456constexpr EIGEN_STRONG_INLINE Array h_array_reverse(Array arr, numeric_list<int, n...>) {
457 return {{array_get<sizeof...(n) - n - 1>(arr)...}};
458}
459
460template <typename T, std::size_t N>
461constexpr EIGEN_STRONG_INLINE array<T, N> array_reverse(array<T, N> arr) {
462 return h_array_reverse(arr, typename gen_numeric_list<int, N>::type());
463}
464
465/* generic array reductions */
466
467// can't reuse standard reduce() interface above because Intel's Compiler
468// *really* doesn't like it, so we just reimplement the stuff
469// (start from N - 1 and work down to 0 because specialization for
470// n == N - 1 also doesn't work in Intel's compiler, so it goes into
471// an infinite loop)
472template <typename Reducer, typename T, std::size_t N, std::size_t n = N - 1>
473struct h_array_reduce {
474 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(array<T, N> arr, T identity)
475 -> decltype(Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr))) {
476 return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr));
477 }
478};
479
480template <typename Reducer, typename T, std::size_t N>
481struct h_array_reduce<Reducer, T, N, 0> {
482 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE T run(const array<T, N>& arr, T) { return array_get<0>(arr); }
483};
484
485template <typename Reducer, typename T>
486struct h_array_reduce<Reducer, T, 0> {
487 EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE T run(const array<T, 0>&, T identity) { return identity; }
488};
489
490template <typename Reducer, typename T, std::size_t N>
491EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_reduce(const array<T, N>& arr, T identity)
492 -> decltype(h_array_reduce<Reducer, T, N>::run(arr, identity)) {
493 return h_array_reduce<Reducer, T, N>::run(arr, identity);
494}
495
496/* standard array reductions */
497
498template <typename T, std::size_t N>
499EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_sum(const array<T, N>& arr)
500 -> decltype(array_reduce<sum_op, T, N>(arr, static_cast<T>(0))) {
501 return array_reduce<sum_op, T, N>(arr, static_cast<T>(0));
502}
503
504template <typename T, std::size_t N>
505EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_prod(const array<T, N>& arr)
506 -> decltype(array_reduce<product_op, T, N>(arr, static_cast<T>(1))) {
507 return array_reduce<product_op, T, N>(arr, static_cast<T>(1));
508}
509
510template <typename t>
511EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) {
512 eigen_assert(a.size() > 0);
513 t prod = 1;
514 for (size_t i = 0; i < a.size(); ++i) {
515 prod *= a[i];
516 }
517 return prod;
518}
519
520/* zip an array */
521
522template <typename Op, typename A, typename B, std::size_t N, int... n>
523constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A(), B())), N> h_array_zip(array<A, N> a, array<B, N> b,
524 numeric_list<int, n...>) {
525 return array<decltype(Op::run(A(), B())), N>{{Op::run(array_get<n>(a), array_get<n>(b))...}};
526}
527
528template <typename Op, typename A, typename B, std::size_t N>
529constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A(), B())), N> array_zip(array<A, N> a, array<B, N> b) {
530 return h_array_zip<Op>(a, b, typename gen_numeric_list<int, N>::type());
531}
532
533/* zip an array and reduce the result */
534
535template <typename Reducer, typename Op, typename A, typename B, std::size_t N, int... n>
536constexpr EIGEN_STRONG_INLINE auto h_array_zip_and_reduce(array<A, N> a, array<B, N> b, numeric_list<int, n...>)
537 -> decltype(reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A(), B()))>::type...>::run(
538 Op::run(array_get<n>(a), array_get<n>(b))...)) {
539 return reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A(), B()))>::type...>::run(
540 Op::run(array_get<n>(a), array_get<n>(b))...);
541}
542
543template <typename Reducer, typename Op, typename A, typename B, std::size_t N>
544constexpr EIGEN_STRONG_INLINE auto array_zip_and_reduce(array<A, N> a, array<B, N> b)
545 -> decltype(h_array_zip_and_reduce<Reducer, Op, A, B, N>(a, b, typename gen_numeric_list<int, N>::type())) {
546 return h_array_zip_and_reduce<Reducer, Op, A, B, N>(a, b, typename gen_numeric_list<int, N>::type());
547}
548
549/* apply stuff to an array */
550
551template <typename Op, typename A, std::size_t N, int... n>
552constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A())), N> h_array_apply(array<A, N> a, numeric_list<int, n...>) {
553 return array<decltype(Op::run(A())), N>{{Op::run(array_get<n>(a))...}};
554}
555
556template <typename Op, typename A, std::size_t N>
557constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A())), N> array_apply(array<A, N> a) {
558 return h_array_apply<Op>(a, typename gen_numeric_list<int, N>::type());
559}
560
561/* apply stuff to an array and reduce */
562
563template <typename Reducer, typename Op, typename A, std::size_t N, int... n>
564constexpr EIGEN_STRONG_INLINE auto h_array_apply_and_reduce(array<A, N> arr, numeric_list<int, n...>)
565 -> decltype(reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A()))>::type...>::run(
566 Op::run(array_get<n>(arr))...)) {
567 return reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A()))>::type...>::run(
568 Op::run(array_get<n>(arr))...);
569}
570
571template <typename Reducer, typename Op, typename A, std::size_t N>
572constexpr EIGEN_STRONG_INLINE auto array_apply_and_reduce(array<A, N> a)
573 -> decltype(h_array_apply_and_reduce<Reducer, Op, A, N>(a, typename gen_numeric_list<int, N>::type())) {
574 return h_array_apply_and_reduce<Reducer, Op, A, N>(a, typename gen_numeric_list<int, N>::type());
575}
576
577/* repeat a value n times (and make an array out of it
578 * usage:
579 * array<int, 16> = repeat<16>(42);
580 */
581
582template <int n>
583struct h_repeat {
584 template <typename t, int... ii>
585 constexpr static EIGEN_STRONG_INLINE array<t, n> run(t v, numeric_list<int, ii...>) {
586 return {{typename id_numeric<int, ii, t>::type(v)...}};
587 }
588};
589
590template <int n, typename t>
591constexpr array<t, n> repeat(t v) {
592 return h_repeat<n>::run(v, typename gen_numeric_list<int, n>::type());
593}
594
595/* instantiate a class by a C-style array */
596template <class InstType, typename ArrType, std::size_t N, bool Reverse, typename... Ps>
597struct h_instantiate_by_c_array;
598
599template <class InstType, typename ArrType, std::size_t N, typename... Ps>
600struct h_instantiate_by_c_array<InstType, ArrType, N, false, Ps...> {
601 static InstType run(ArrType* arr, Ps... args) {
602 return h_instantiate_by_c_array<InstType, ArrType, N - 1, false, Ps..., ArrType>::run(arr + 1, args..., arr[0]);
603 }
604};
605
606template <class InstType, typename ArrType, std::size_t N, typename... Ps>
607struct h_instantiate_by_c_array<InstType, ArrType, N, true, Ps...> {
608 static InstType run(ArrType* arr, Ps... args) {
609 return h_instantiate_by_c_array<InstType, ArrType, N - 1, false, ArrType, Ps...>::run(arr + 1, arr[0], args...);
610 }
611};
612
613template <class InstType, typename ArrType, typename... Ps>
614struct h_instantiate_by_c_array<InstType, ArrType, 0, false, Ps...> {
615 static InstType run(ArrType* arr, Ps... args) {
616 (void)arr;
617 return InstType(args...);
618 }
619};
620
621template <class InstType, typename ArrType, typename... Ps>
622struct h_instantiate_by_c_array<InstType, ArrType, 0, true, Ps...> {
623 static InstType run(ArrType* arr, Ps... args) {
624 (void)arr;
625 return InstType(args...);
626 }
627};
628
629template <class InstType, typename ArrType, std::size_t N, bool Reverse = false>
630InstType instantiate_by_c_array(ArrType* arr) {
631 return h_instantiate_by_c_array<InstType, ArrType, N, Reverse>::run(arr);
632}
633
634} // end namespace internal
635
636} // end namespace Eigen
637
638#endif // EIGEN_MOREMETA_H
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1