12#ifndef EIGEN_MOREMETA_H
13#define EIGEN_MOREMETA_H
16#include "../InternalHeaderCheck.h"
22template <
typename... tt>
24 constexpr static int count =
sizeof...(tt);
27template <
typename t,
typename... tt>
28struct type_list<t, tt...> {
29 constexpr static int count =
sizeof...(tt) + 1;
35template <
class a,
class b>
38template <
typename... as,
typename... bs>
39struct concat<type_list<as...>, type_list<bs...>> {
40 using type = type_list<as..., bs...>;
43template <
typename... p>
49template <
typename a,
typename b>
50struct mconcat<a, b> : concat<a, b> {};
51template <
typename a,
typename b,
typename... cs>
52struct mconcat<a, b, cs...> : concat<a, typename mconcat<b, cs...>::type> {};
56template <
int n,
typename x>
59template <
int n,
typename a,
typename... as>
60struct take<n, type_list<a, as...>> : concat<type_list<a>, typename take<n - 1, type_list<as...>>::type> {};
63struct take<n, type_list<>> {
64 using type = type_list<>;
67template <
typename a,
typename... as>
68struct take<0, type_list<a, as...>> {
69 using type = type_list<>;
73struct take<0, type_list<>> {
74 using type = type_list<>;
77template <
int n,
typename a>
80template <
int n,
typename a,
typename... as>
81struct skip<n, type_list<a, as...>> : skip<n - 1, type_list<as...>> {};
83template <
typename a,
typename... as>
84struct skip<0, type_list<a, as...>> {
85 using type = type_list<a, as...>;
89struct skip<n, type_list<>> {
90 using type = type_list<>;
94struct skip<0, type_list<>> {
95 using type = type_list<>;
98template <
int start,
int count,
typename a>
99struct slice : take<count, typename skip<start, a>::type> {};
103template <
int n,
typename x>
106template <
int n,
typename a,
typename... as>
107struct get<n, type_list<a, as...>> : get<n - 1, type_list<as...>> {};
108template <
typename a,
typename... as>
109struct get<0, type_list<a, as...>> {
113template <
typename T,
int n, T a, T... as>
114struct get<n, std::integer_sequence<T, a, as...>> : get<n - 1, std::integer_sequence<T, as...>> {};
115template <
typename T, T a, T... as>
116struct get<0, std::integer_sequence<T, a, as...>> {
117 constexpr static T value = a;
122template <
typename a,
typename b>
123struct is_same_gf : std::is_same<a, b> {
124 constexpr static int global_flags = 0;
129template <
template <
typename,
typename>
class op,
typename additional_param,
typename a>
130struct apply_op_from_left;
132template <
template <
typename,
typename>
class op,
typename additional_param,
typename... values>
133struct apply_op_from_left<op, additional_param, type_list<values...>> {
134 using type = type_list<typename op<additional_param, values>::type...>;
137template <
template <
typename,
typename>
class op,
typename additional_param,
typename a>
138struct apply_op_from_right;
140template <
template <
typename,
typename>
class op,
typename additional_param,
typename... values>
141struct apply_op_from_right<op, additional_param, type_list<values...>> {
142 using type = type_list<typename op<values, additional_param>::type...>;
147template <
template <
typename,
typename>
class test,
typename check_against,
typename h_list,
148 bool last_check_positive =
false>
149struct contained_in_list;
151template <
template <
typename,
typename>
class test,
typename check_against,
typename h_list>
152struct contained_in_list<test, check_against, h_list, true> {
153 constexpr static bool value =
true;
156template <
template <
typename,
typename>
class test,
typename check_against,
typename a,
typename... as>
157struct contained_in_list<test, check_against, type_list<a, as...>, false>
158 : contained_in_list<test, check_against, type_list<as...>, test<check_against, a>::value> {};
160template <
template <
typename,
typename>
class test,
typename check_against,
typename... empty>
161struct contained_in_list<test, check_against, type_list<empty...>, false> {
162 constexpr static bool value =
false;
167template <
template <
typename,
typename>
class test,
typename check_against,
typename h_list,
int default_flags = 0,
168 bool last_check_positive =
false,
int last_check_flags = default_flags>
169struct contained_in_list_gf;
171template <
template <
typename,
typename>
class test,
typename check_against,
typename h_list,
int default_flags,
172 int last_check_flags>
173struct contained_in_list_gf<test, check_against, h_list, default_flags, true, last_check_flags> {
174 constexpr static bool value =
true;
175 constexpr static int global_flags = last_check_flags;
178template <
template <
typename,
typename>
class test,
typename check_against,
typename a,
typename... as,
179 int default_flags,
int last_check_flags>
180struct contained_in_list_gf<test, check_against, type_list<a, as...>, default_flags, false, last_check_flags>
181 : contained_in_list_gf<test, check_against, type_list<as...>, default_flags, test<check_against, a>::value,
182 test<check_against, a>::global_flags> {};
184template <
template <
typename,
typename>
class test,
typename check_against,
typename... empty,
int default_flags,
185 int last_check_flags>
186struct contained_in_list_gf<test, check_against, type_list<empty...>, default_flags, false, last_check_flags> {
187 constexpr static bool value =
false;
188 constexpr static int global_flags = default_flags;
193template <
typename Reducer,
typename... Ts>
196template <
typename Reducer>
197struct reduce<Reducer> {
198 EIGEN_DEVICE_FUNC
constexpr static int run() {
return Reducer::Identity; }
201template <
typename Reducer,
typename A>
202struct reduce<Reducer, A> {
203 EIGEN_DEVICE_FUNC
constexpr static A run(A a) {
return a; }
206template <
typename Reducer,
typename A,
typename... Ts>
207struct reduce<Reducer, A, Ts...> {
208 EIGEN_DEVICE_FUNC
constexpr static auto run(A a, Ts... ts) {
209 return Reducer::run(a, reduce<Reducer, Ts...>::run(ts...));
216 template <
typename A,
typename B>
217 EIGEN_DEVICE_FUNC
constexpr static auto run(A a, B b) {
220 static constexpr int Identity = 0;
223 template <
typename A,
typename B>
224 EIGEN_DEVICE_FUNC
constexpr static auto run(A a, B b) {
227 static constexpr int Identity = 1;
232template <
typename... Ts>
233EIGEN_DEVICE_FUNC
constexpr auto arg_prod(Ts... ts) {
234 return reduce<product_op, Ts...>::run(ts...);
237template <
typename... Ts>
238constexpr auto arg_sum(Ts... ts) {
239 return reduce<sum_op, Ts...>::run(ts...);
244template <
typename Reducer,
typename T, std::
size_t N>
245struct array_reducer {
246 EIGEN_DEVICE_FUNC
constexpr static auto run(
const array<T, N>& arr, T) {
247 auto result = Reducer::run(arr[0], arr[1]);
248 for (std::size_t i = 2; i < N; ++i) {
249 result = Reducer::run(result, arr[i]);
255template <
typename Reducer,
typename T>
256struct array_reducer<Reducer, T, 1> {
257 EIGEN_DEVICE_FUNC
constexpr static T run(
const array<T, 1>& arr, T) {
return arr[0]; }
260template <
typename Reducer,
typename T>
261struct array_reducer<Reducer, T, 0> {
262 EIGEN_DEVICE_FUNC
constexpr static T run(
const array<T, 0>&, T identity) {
return identity; }
265template <
typename Reducer,
typename T, std::
size_t N>
266EIGEN_DEVICE_FUNC
constexpr auto array_reduce(
const array<T, N>& arr, T identity) {
267 return array_reducer<Reducer, T, N>::run(arr, identity);
272template <
typename T, std::
size_t N>
273EIGEN_DEVICE_FUNC
constexpr auto array_sum(
const array<T, N>& arr) {
274 return array_reduce<sum_op, T, N>(arr,
static_cast<T
>(0));
277template <
typename T, std::
size_t N>
278EIGEN_DEVICE_FUNC
constexpr auto array_prod(
const array<T, N>& arr) {
279 return array_reduce<product_op, T, N>(arr,
static_cast<T
>(1));
283EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(
const std::vector<t>& a) {
284 eigen_assert(a.size() > 0);
286 for (
size_t i = 0; i < a.size(); ++i) {