11 #ifndef EIGEN_MOREMETA_H
12 #define EIGEN_MOREMETA_H
14 #include "../InternalHeaderCheck.h"
20 template<
typename... tt>
21 struct type_list { constexpr
static int count =
sizeof...(tt); };
23 template<
typename t,
typename... tt>
24 struct type_list<t, tt...> { constexpr
static int count =
sizeof...(tt) + 1;
typedef t first_type; };
26 template<
typename T,
T... nn>
27 struct numeric_list { constexpr
static std::size_t count =
sizeof...(nn); };
29 template<
typename T,
T n,
T... nn>
30 struct numeric_list<
T,
n, nn...> {
static constexpr std::size_t count =
sizeof...(nn) + 1;
31 static constexpr
T first_value =
n; };
33 #ifndef EIGEN_PARSED_BY_DOXYGEN
44 template<
typename T, std::size_t
n,
T start = 0,
T... ii>
struct gen_numeric_list : gen_numeric_list<T, n-1, start, start + n-1, ii...> {};
45 template<
typename T,
T start,
T... ii>
struct gen_numeric_list<
T, 0, start, ii...> {
typedef numeric_list<
T, ii...> type; };
47 template<
typename T, std::size_t
n,
T start = 0,
T... ii>
struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n-1, start, ii..., start + n-1> {};
48 template<
typename T,
T start,
T... ii>
struct gen_numeric_list_reversed<
T, 0, start, ii...> {
typedef numeric_list<
T, ii...> type; };
50 template<
typename T, std::size_t
n,
T a,
T b,
T start = 0,
T... ii>
struct gen_numeric_list_swapped_pair : gen_numeric_list_swapped_pair<T, n-1, a, b, start, (start + n-1) == a ? b : ((start + n-1) == b ? a : (start + n-1)), ii...> {};
51 template<
typename T,
T a,
T b,
T start,
T... ii>
struct gen_numeric_list_swapped_pair<
T, 0,
a,
b, start, ii...> {
typedef numeric_list<
T, ii...> type; };
53 template<
typename T, std::size_t
n,
T V,
T... nn>
struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n-1, V, V, nn...> {};
54 template<
typename T,
T V,
T... nn>
struct gen_numeric_list_repeated<
T, 0,
V, nn...> {
typedef numeric_list<
T, nn...> type; };
58 template<
class a,
class b>
struct concat;
60 template<
typename... as,
typename... bs>
struct concat<type_list<as...>, type_list<bs...>> {
typedef type_list<as..., bs...> type; };
61 template<
typename T,
T... as,
T... bs>
struct concat<numeric_list<
T, as...>, numeric_list<
T, bs...> > {
typedef numeric_list<
T, as..., bs...> type; };
63 template<
typename...
p>
struct mconcat;
64 template<
typename a>
struct mconcat<
a> {
typedef a type; };
65 template<
typename a,
typename b>
struct mconcat<
a,
b> : concat<a, b> {};
66 template<
typename a,
typename b,
typename... cs>
struct mconcat<
a,
b, cs...> : concat<a, typename mconcat<b, cs...>::type> {};
70 template<
int n,
typename x>
struct take;
71 template<
int n,
typename a,
typename... as>
struct take<
n, type_list<
a, as...>> : concat<type_list<a>, typename take<n-1, type_list<as...>>::type> {};
72 template<
int n>
struct take<
n, type_list<>> {
typedef type_list<> type; };
73 template<
typename a,
typename... as>
struct take<0, type_list<
a, as...>> {
typedef type_list<> type; };
74 template<>
struct take<0, type_list<>> {
typedef type_list<> type; };
76 template<
typename T,
int n,
T a,
T... as>
struct take<
n, numeric_list<
T,
a, as...>> : concat<numeric_list<T, a>, typename take<n-1, numeric_list<T, as...>>::type> {};
79 template<
typename T,
T a,
T... as>
struct take<0, numeric_list<
T,
a, as...>> {
typedef numeric_list<T> type; };
80 template<
typename T>
struct take<0, numeric_list<
T>> {
typedef numeric_list<T> type; };
82 template<
typename T,
int n,
T... ii>
struct h_skip_helper_numeric;
83 template<
typename T,
int n,
T i,
T... ii>
struct h_skip_helper_numeric<
T,
n,
i, ii...> : h_skip_helper_numeric<T, n-1, ii...> {};
84 template<
typename T,
T i,
T... ii>
struct h_skip_helper_numeric<
T, 0,
i, ii...> {
typedef numeric_list<
T,
i, ii...> type; };
85 template<
typename T,
int n>
struct h_skip_helper_numeric<
T,
n> {
typedef numeric_list<T> type; };
86 template<
typename T>
struct h_skip_helper_numeric<
T, 0> {
typedef numeric_list<T> type; };
88 template<
int n,
typename... tt>
struct h_skip_helper_type;
89 template<
int n,
typename t,
typename... tt>
struct h_skip_helper_type<
n, t, tt...> : h_skip_helper_type<n-1, tt...> {};
90 template<
typename t,
typename... tt>
struct h_skip_helper_type<0, t, tt...> {
typedef type_list<t, tt...> type; };
91 template<
int n>
struct h_skip_helper_type<
n> {
typedef type_list<> type; };
92 template<>
struct h_skip_helper_type<0> {
typedef type_list<> type; };
97 template<
typename T,
T... ii>
98 constexpr
static EIGEN_STRONG_INLINE
typename h_skip_helper_numeric<
T,
n, ii...>::type helper(numeric_list<T, ii...>) {
return typename h_skip_helper_numeric<T, n, ii...>::type(); }
99 template<
typename... tt>
100 constexpr
static EIGEN_STRONG_INLINE
typename h_skip_helper_type<
n, tt...>::type helper(type_list<tt...>) {
return typename h_skip_helper_type<n, tt...>::type(); }
103 template<
int n,
typename a>
struct skip {
typedef decltype(h_skip<n>::helper(
a())) type; };
105 template<
int start,
int count, typename
a> struct slice :
take<count, typename skip<start,
a>::type> {};
109 template<
int n,
typename x>
struct get;
111 template<
int n,
typename a,
typename... as>
struct get<
n, type_list<
a, as...>> : get<n-1, type_list<as...>> {};
112 template<
typename a,
typename... as>
struct get<0, type_list<
a, as...>> {
typedef a type; };
114 template<
typename T,
int n,
T a,
T... as>
struct get<
n, numeric_list<
T,
a, as...>> : get<n-1, numeric_list<T, as...>> {};
115 template<
typename T,
T a,
T... as>
struct get<0, numeric_list<
T,
a, as...>> { constexpr
static T value =
a; };
117 template<std::size_t
n,
typename T,
T a,
T... as> constexpr
T array_get(
const numeric_list<T, a, as...>&) {
118 return get<(int)
n, numeric_list<T, a, as...>>::value;
123 template<
typename T, T dummy,
typename t>
struct id_numeric {
typedef t type; };
124 template<
typename dummy,
typename t>
struct id_type {
typedef t type; };
128 template<
typename a,
typename b>
struct is_same_gf : is_same<a, b> { constexpr
static int global_flags = 0; };
134 template<
typename,
typename>
class op,
135 typename additional_param,
138 struct h_apply_op_helper {
typedef type_list<typename op<values, additional_param>::type...> type; };
140 template<
typename,
typename>
class op,
141 typename additional_param,
144 struct h_apply_op_helper<true, op, additional_param, values...> {
typedef type_list<typename op<additional_param, values>::type...> type; };
148 template<
typename,
typename>
class op,
149 typename additional_param
153 template<
typename... values>
154 constexpr
static typename h_apply_op_helper<from_left, op, additional_param, values...>::type helper(type_list<values...>)
155 {
return typename h_apply_op_helper<from_left, op, additional_param, values...>::type(); }
159 template<
typename,
typename>
class op,
160 typename additional_param,
163 struct apply_op_from_left {
typedef decltype(h_apply_op<true, op, additional_param>::helper(
a())) type; };
166 template<typename, typename> class op,
167 typename additional_param,
170 struct apply_op_from_right {
typedef decltype(h_apply_op<false, op, additional_param>::helper(
a())) type; };
175 template<typename, typename> class test,
176 typename check_against,
178 bool last_check_positive = false
180 struct contained_in_list;
183 template<typename, typename> class test,
184 typename check_against,
187 struct contained_in_list<test, check_against, h_list, true>
189 constexpr
static bool value =
true;
193 template<
typename,
typename>
class test,
194 typename check_against,
198 struct contained_in_list<test, check_against, type_list<
a, as...>, false> : contained_in_list<test, check_against, type_list<as...>, test<check_against, a>::value> {};
201 template<
typename,
typename>
class test,
202 typename check_against,
205 struct contained_in_list<test, check_against, type_list<empty...>, false> { constexpr
static bool value =
false; };
210 template<
typename,
typename>
class test,
211 typename check_against,
213 int default_flags = 0,
214 bool last_check_positive =
false,
215 int last_check_flags = default_flags
217 struct contained_in_list_gf;
220 template<
typename,
typename>
class test,
221 typename check_against,
226 struct contained_in_list_gf<test, check_against, h_list, default_flags, true, last_check_flags>
228 constexpr
static bool value =
true;
229 constexpr
static int global_flags = last_check_flags;
233 template<
typename,
typename>
class test,
234 typename check_against,
240 struct contained_in_list_gf<test, check_against, type_list<
a, as...>, default_flags, false, last_check_flags> : contained_in_list_gf<test, check_against, type_list<as...>, default_flags, test<check_against, a>::value, test<check_against, a>::global_flags> {};
243 template<
typename,
typename>
class test,
244 typename check_against,
249 struct contained_in_list_gf<test, check_against, type_list<empty...>, default_flags, false, last_check_flags> { constexpr
static bool value =
false; constexpr
static int global_flags = default_flags; };
260 >
struct reduce<Reducer>
262 EIGEN_DEVICE_FUNC constexpr
static EIGEN_STRONG_INLINE
int run() {
return Reducer::Identity; }
268 >
struct reduce<Reducer,
A>
277 >
struct reduce<Reducer,
A, Ts...>
279 EIGEN_DEVICE_FUNC constexpr
static EIGEN_STRONG_INLINE
auto run(
A a, Ts... ts) -> decltype(Reducer::run(
a, reduce<Reducer, Ts...>::run(ts...))) {
280 return Reducer::run(
a, reduce<Reducer, Ts...>::run(ts...));
287 template<
typename A,
typename B>
EIGEN_DEVICE_FUNC constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a +
b) {
return a +
b; }
288 static constexpr
int Identity = 0;
291 template<
typename A,
typename B>
EIGEN_DEVICE_FUNC constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a *
b) {
return a *
b; }
292 static constexpr
int Identity = 1;
295 struct logical_and_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a &&
b) {
return a &&
b; } };
296 struct logical_or_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a ||
b) {
return a ||
b; } };
298 struct equal_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a ==
b) {
return a ==
b; } };
299 struct not_equal_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a !=
b) {
return a !=
b; } };
300 struct lesser_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a <
b) {
return a <
b; } };
301 struct lesser_equal_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a <=
b) {
return a <=
b; } };
302 struct greater_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a >
b) {
return a >
b; } };
303 struct greater_equal_op {
template<
typename A,
typename B> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a,
B b) -> decltype(
a >=
b) {
return a >=
b; } };
307 struct not_op {
template<
typename A> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a) -> decltype(!
a) {
return !
a; } };
308 struct negation_op {
template<
typename A> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a) -> decltype(-
a) {
return -
a; } };
309 struct greater_equal_zero_op {
template<
typename A> constexpr
static EIGEN_STRONG_INLINE
auto run(
A a) -> decltype(
a >= 0) {
return a >= 0; } };
317 template<
typename... Ts>
320 return reduce<product_op, Ts...>::run(ts...);
323 template<
typename... Ts>
324 constexpr EIGEN_STRONG_INLINE decltype(reduce<sum_op, Ts...>::run((*((Ts*)0))...))
arg_sum(Ts... ts)
326 return reduce<sum_op, Ts...>::run(ts...);
331 template<
typename Array,
int...
n>
334 return {{
array_get<
sizeof...(n) -
n - 1>(arr)...}};
337 template<
typename T, std::
size_t N>
340 return h_array_reverse(arr,
typename gen_numeric_list<int, N>::type());
351 template<
typename Reducer,
typename T, std::size_t N, std::size_t
n = N - 1>
352 struct h_array_reduce {
353 EIGEN_DEVICE_FUNC constexpr
static EIGEN_STRONG_INLINE
auto run(
array<T, N> arr,
T identity) -> decltype(Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr)))
355 return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr));
359 template<
typename Reducer,
typename T, std::
size_t N>
360 struct h_array_reduce<Reducer,
T, N, 0>
364 return array_get<0>(arr);
368 template<
typename Reducer,
typename T>
369 struct h_array_reduce<Reducer,
T, 0>
371 EIGEN_DEVICE_FUNC constexpr
static EIGEN_STRONG_INLINE
T run(
const array<T, 0>&,
T identity)
377 template<
typename Reducer,
typename T, std::
size_t N>
380 return h_array_reduce<Reducer, T, N>::run(arr, identity);
385 template<
typename T, std::
size_t N>
388 return array_reduce<sum_op, T, N>(arr,
static_cast<T>(0));
391 template<
typename T, std::
size_t N>
394 return array_reduce<product_op, T, N>(arr,
static_cast<T>(1));
401 for (
size_t i = 0;
i <
a.size(); ++
i) { prod *=
a[
i]; }
407 template<
typename Op,
typename A,
typename B, std::size_t N,
int...
n>
410 return array<decltype(Op::run(
A(),
B())),N>{{ Op::run(array_get<n>(
a), array_get<n>(
b))... }};
413 template<
typename Op,
typename A,
typename B, std::
size_t N>
416 return h_array_zip<Op>(
a,
b,
typename gen_numeric_list<int, N>::type());
421 template<
typename Reducer,
typename Op,
typename A,
typename B, std::size_t N,
int...
n>
422 constexpr EIGEN_STRONG_INLINE
auto h_array_zip_and_reduce(
array<A, N> a,
array<B, N> b, numeric_list<int, n...>) -> decltype(reduce<Reducer,
typename id_numeric<
int,
n,decltype(Op::run(
A(),
B()))>::type...>::run(Op::run(array_get<n>(
a), array_get<n>(
b))...))
424 return reduce<Reducer,
typename id_numeric<int,
n,decltype(Op::run(
A(),
B()))>::type...>::run(Op::run(array_get<n>(
a), array_get<n>(
b))...);
427 template<
typename Reducer,
typename Op,
typename A,
typename B, std::
size_t N>
428 constexpr EIGEN_STRONG_INLINE
auto array_zip_and_reduce(
array<A, N> a,
array<B, N> b) -> decltype(h_array_zip_and_reduce<Reducer, Op, A, B, N>(
a,
b,
typename gen_numeric_list<int, N>::type()))
430 return h_array_zip_and_reduce<Reducer, Op, A, B, N>(
a,
b,
typename gen_numeric_list<int, N>::type());
435 template<
typename Op,
typename A, std::size_t N,
int...
n>
438 return array<decltype(Op::run(
A())),N>{{ Op::run(array_get<n>(
a))... }};
441 template<
typename Op,
typename A, std::
size_t N>
444 return h_array_apply<Op>(
a,
typename gen_numeric_list<int, N>::type());
449 template<
typename Reducer,
typename Op,
typename A, std::size_t N,
int...
n>
450 constexpr EIGEN_STRONG_INLINE
auto h_array_apply_and_reduce(
array<A, N> arr, numeric_list<int, n...>) -> decltype(reduce<Reducer,
typename id_numeric<
int,
n,decltype(Op::run(
A()))>::type...>::run(Op::run(array_get<n>(arr))...))
452 return reduce<Reducer,
typename id_numeric<int,
n,decltype(Op::run(
A()))>::type...>::run(Op::run(array_get<n>(arr))...);
455 template<
typename Reducer,
typename Op,
typename A, std::
size_t N>
458 return h_array_apply_and_reduce<Reducer, Op, A, N>(
a,
typename gen_numeric_list<int, N>::type());
469 template<
typename t,
int... ii>
470 constexpr
static EIGEN_STRONG_INLINE
array<t, n> run(t
v, numeric_list<int, ii...>)
472 return {{
typename id_numeric<int, ii, t>::type(
v)... }};
476 template<
int n,
typename t>
477 constexpr
array<t, n> repeat(t
v) {
return h_repeat<n>::run(
v,
typename gen_numeric_list<int, n>::type()); }
480 template<
class InstType,
typename ArrType, std::size_t N,
bool Reverse,
typename... Ps>
481 struct h_instantiate_by_c_array;
483 template<
class InstType,
typename ArrType, std::size_t N,
typename... Ps>
484 struct h_instantiate_by_c_array<InstType, ArrType, N, false, Ps...>
486 static InstType run(ArrType* arr, Ps... args)
488 return h_instantiate_by_c_array<InstType, ArrType, N - 1, false, Ps..., ArrType>::run(arr + 1, args..., arr[0]);
492 template<
class InstType,
typename ArrType, std::size_t N,
typename... Ps>
493 struct h_instantiate_by_c_array<InstType, ArrType, N, true, Ps...>
495 static InstType run(ArrType* arr, Ps... args)
497 return h_instantiate_by_c_array<InstType, ArrType, N - 1, false, ArrType, Ps...>::run(arr + 1, arr[0], args...);
501 template<
class InstType,
typename ArrType,
typename... Ps>
502 struct h_instantiate_by_c_array<InstType, ArrType, 0, false, Ps...>
504 static InstType run(ArrType* arr, Ps... args)
507 return InstType(args...);
511 template<
class InstType,
typename ArrType,
typename... Ps>
512 struct h_instantiate_by_c_array<InstType, ArrType, 0, true, Ps...>
514 static InstType run(ArrType* arr, Ps... args)
517 return InstType(args...);
521 template<
class InstType,
typename ArrType, std::
size_t N,
bool Reverse = false>
524 return h_instantiate_by_c_array<InstType, ArrType, N, Reverse>::run(arr);
Array< int, Dynamic, 1 > v
#define EIGEN_DEVICE_FUNC
Eigen::Triplet< double > T
General-purpose arrays with easy API for coefficient-wise operations.
Expression of the reverse of a vector or matrix.
constexpr auto array_apply_and_reduce(array< A, N > a) -> decltype(h_array_apply_and_reduce< Reducer, Op, A, N >(a, typename gen_numeric_list< int, N >::type()))
constexpr array< T, N > array_reverse(array< T, N > arr)
constexpr Array h_array_reverse(Array arr, numeric_list< int, n... >)
constexpr auto h_array_zip_and_reduce(array< A, N > a, array< B, N > b, numeric_list< int, n... >) -> decltype(reduce< Reducer, typename id_numeric< int, n, decltype(Op::run(A(), B()))>::type... >::run(Op::run(array_get< n >(a), array_get< n >(b))...))
constexpr decltype(reduce< sum_op, Ts... >::run((*((Ts *) 0))...) arg_sum)(Ts... ts)
constexpr array< decltype(Op::run(A())), N > h_array_apply(array< A, N > a, numeric_list< int, n... >)
constexpr T & array_get(std::array< T, N > &a)
constexpr array< t, n > repeat(t v)
constexpr auto h_array_apply_and_reduce(array< A, N > arr, numeric_list< int, n... >) -> decltype(reduce< Reducer, typename id_numeric< int, n, decltype(Op::run(A()))>::type... >::run(Op::run(array_get< n >(arr))...))
constexpr auto array_reduce(const array< T, N > &arr, T identity) -> decltype(h_array_reduce< Reducer, T, N >::run(arr, identity))
constexpr auto array_sum(const array< T, N > &arr) -> decltype(array_reduce< sum_op, T, N >(arr, static_cast< T >(0)))
constexpr decltype(reduce< product_op, Ts... >::run((*((Ts *) 0))...) arg_prod)(Ts... ts)
constexpr auto array_prod(const array< T, N > &arr) -> decltype(array_reduce< product_op, T, N >(arr, static_cast< T >(1)))
constexpr array< decltype(Op::run(A(), B())), N > h_array_zip(array< A, N > a, array< B, N > b, numeric_list< int, n... >)
InstType instantiate_by_c_array(ArrType *arr)
constexpr auto array_zip_and_reduce(array< A, N > a, array< B, N > b) -> decltype(h_array_zip_and_reduce< Reducer, Op, A, B, N >(a, b, typename gen_numeric_list< int, N >::type()))
constexpr array< decltype(Op::run(A(), B())), N > array_zip(array< A, N > a, array< B, N > b)
constexpr array< decltype(Op::run(A())), N > array_apply(array< A, N > a)