Eigen  5.0.1
 
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// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_MOREMETA_H
13#define EIGEN_MOREMETA_H
14
15// IWYU pragma: private
16#include "../InternalHeaderCheck.h"
17
18namespace Eigen {
19
20namespace internal {
21
22template <typename... tt>
23struct type_list {
24 constexpr static int count = sizeof...(tt);
25};
26
27template <typename t, typename... tt>
28struct type_list<t, tt...> {
29 constexpr static int count = sizeof...(tt) + 1;
30 using first_type = t;
31};
32
33/* list manipulation: concatenate */
34
35template <class a, class b>
36struct concat;
37
38template <typename... as, typename... bs>
39struct concat<type_list<as...>, type_list<bs...>> {
40 using type = type_list<as..., bs...>;
41};
42
43template <typename... p>
44struct mconcat;
45template <typename a>
46struct mconcat<a> {
47 using type = a;
48};
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> {};
53
54/* list manipulation: extract slices */
55
56template <int n, typename x>
57struct take;
58
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> {};
61
62template <int n>
63struct take<n, type_list<>> {
64 using type = type_list<>;
65};
66
67template <typename a, typename... as>
68struct take<0, type_list<a, as...>> {
69 using type = type_list<>;
70};
71
72template <>
73struct take<0, type_list<>> {
74 using type = type_list<>;
75};
76
77template <int n, typename a>
78struct skip;
79
80template <int n, typename a, typename... as>
81struct skip<n, type_list<a, as...>> : skip<n - 1, type_list<as...>> {};
82
83template <typename a, typename... as>
84struct skip<0, type_list<a, as...>> {
85 using type = type_list<a, as...>;
86};
87
88template <int n>
89struct skip<n, type_list<>> {
90 using type = type_list<>;
91};
92
93template <>
94struct skip<0, type_list<>> {
95 using type = type_list<>;
96};
97
98template <int start, int count, typename a>
99struct slice : take<count, typename skip<start, a>::type> {};
100
101/* list manipulation: retrieve single element from list */
102
103template <int n, typename x>
104struct get;
105
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...>> {
110 using type = a;
111};
112
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;
118};
119
120/* equality checking, flagged version */
121
122template <typename a, typename b>
123struct is_same_gf : std::is_same<a, b> {
124 constexpr static int global_flags = 0;
125};
126
127/* apply_op to list */
128
129template <template <typename, typename> class op, typename additional_param, typename a>
130struct apply_op_from_left;
131
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...>;
135};
136
137template <template <typename, typename> class op, typename additional_param, typename a>
138struct apply_op_from_right;
139
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...>;
143};
144
145/* see if an element is in a list */
146
147template <template <typename, typename> class test, typename check_against, typename h_list,
148 bool last_check_positive = false>
149struct contained_in_list;
150
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;
154};
155
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> {};
159
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;
163};
164
165/* see if an element is in a list and check for global flags */
166
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;
170
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;
176};
177
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> {};
183
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;
189};
190
191/* generic reductions */
192
193template <typename Reducer, typename... Ts>
194struct reduce;
195
196template <typename Reducer>
197struct reduce<Reducer> {
198 EIGEN_DEVICE_FUNC constexpr static int run() { return Reducer::Identity; }
199};
200
201template <typename Reducer, typename A>
202struct reduce<Reducer, A> {
203 EIGEN_DEVICE_FUNC constexpr static A run(A a) { return a; }
204};
205
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...));
210 }
211};
212
213/* generic binary operations */
214
215struct sum_op {
216 template <typename A, typename B>
217 EIGEN_DEVICE_FUNC constexpr static auto run(A a, B b) {
218 return a + b;
219 }
220 static constexpr int Identity = 0;
221};
222struct product_op {
223 template <typename A, typename B>
224 EIGEN_DEVICE_FUNC constexpr static auto run(A a, B b) {
225 return a * b;
226 }
227 static constexpr int Identity = 1;
228};
229
230/* reductions for lists */
231
232template <typename... Ts>
233EIGEN_DEVICE_FUNC constexpr auto arg_prod(Ts... ts) {
234 return reduce<product_op, Ts...>::run(ts...);
235}
236
237template <typename... Ts>
238constexpr auto arg_sum(Ts... ts) {
239 return reduce<sum_op, Ts...>::run(ts...);
240}
241
242/* generic array reductions */
243
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]);
250 }
251 return result;
252 }
253};
254
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]; }
258};
259
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; }
263};
264
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);
268}
269
270/* standard array reductions */
271
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));
275}
276
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));
280}
281
282template <typename t>
283EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) {
284 eigen_assert(a.size() > 0);
285 t prod = 1;
286 for (size_t i = 0; i < a.size(); ++i) {
287 prod *= a[i];
288 }
289 return prod;
290}
291
292} // end namespace internal
293
294} // end namespace Eigen
295
296#endif // EIGEN_MOREMETA_H