Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
Loading...
Searching...
No Matches
Meta.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 <[email protected]>
5// Copyright (C) 2006-2008 Benoit Jacob <[email protected]>
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_META_H
12#define EIGEN_META_H
13
14// IWYU pragma: private
15#include "../InternalHeaderCheck.h"
16
17#if defined(EIGEN_GPU_COMPILE_PHASE)
18
19#include <cfloat>
20
21#if defined(EIGEN_CUDA_ARCH)
22#include <math_constants.h>
23#endif
24
25#if defined(EIGEN_HIP_DEVICE_COMPILE)
26#include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
27#endif
28
29#endif
30
31// Define portable (u)int{32,64} types
32#include <cstdint>
33
34namespace Eigen {
35namespace numext {
36typedef std::uint8_t uint8_t;
37typedef std::int8_t int8_t;
38typedef std::uint16_t uint16_t;
39typedef std::int16_t int16_t;
40typedef std::uint32_t uint32_t;
41typedef std::int32_t int32_t;
42typedef std::uint64_t uint64_t;
43typedef std::int64_t int64_t;
44
45template <size_t Size>
46struct get_integer_by_size {
47 typedef void signed_type;
48 typedef void unsigned_type;
49};
50template <>
51struct get_integer_by_size<1> {
52 typedef int8_t signed_type;
53 typedef uint8_t unsigned_type;
54};
55template <>
56struct get_integer_by_size<2> {
57 typedef int16_t signed_type;
58 typedef uint16_t unsigned_type;
59};
60template <>
61struct get_integer_by_size<4> {
62 typedef int32_t signed_type;
63 typedef uint32_t unsigned_type;
64};
65template <>
66struct get_integer_by_size<8> {
67 typedef int64_t signed_type;
68 typedef uint64_t unsigned_type;
69};
70} // namespace numext
71} // namespace Eigen
72
73namespace Eigen {
74
75typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
76
83typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
84
85namespace internal {
86
94struct true_type {
95 enum { value = 1 };
96};
97struct false_type {
98 enum { value = 0 };
99};
100
101template <bool Condition>
102struct bool_constant;
103
104template <>
105struct bool_constant<true> : true_type {};
106
107template <>
108struct bool_constant<false> : false_type {};
109
110// Third-party libraries rely on these.
111using std::conditional;
112using std::remove_const;
113using std::remove_pointer;
114using std::remove_reference;
115
116template <typename T>
117struct remove_all {
118 typedef T type;
119};
120template <typename T>
121struct remove_all<const T> {
122 typedef typename remove_all<T>::type type;
123};
124template <typename T>
125struct remove_all<T const&> {
126 typedef typename remove_all<T>::type type;
127};
128template <typename T>
129struct remove_all<T&> {
130 typedef typename remove_all<T>::type type;
131};
132template <typename T>
133struct remove_all<T const*> {
134 typedef typename remove_all<T>::type type;
135};
136template <typename T>
137struct remove_all<T*> {
138 typedef typename remove_all<T>::type type;
139};
140
141template <typename T>
142using remove_all_t = typename remove_all<T>::type;
143
144template <typename T>
145struct is_arithmetic {
146 enum { value = false };
147};
148template <>
149struct is_arithmetic<float> {
150 enum { value = true };
151};
152template <>
153struct is_arithmetic<double> {
154 enum { value = true };
155};
156// GPU devices treat `long double` as `double`.
157#ifndef EIGEN_GPU_COMPILE_PHASE
158template <>
159struct is_arithmetic<long double> {
160 enum { value = true };
161};
162#endif
163template <>
164struct is_arithmetic<bool> {
165 enum { value = true };
166};
167template <>
168struct is_arithmetic<char> {
169 enum { value = true };
170};
171template <>
172struct is_arithmetic<signed char> {
173 enum { value = true };
174};
175template <>
176struct is_arithmetic<unsigned char> {
177 enum { value = true };
178};
179template <>
180struct is_arithmetic<signed short> {
181 enum { value = true };
182};
183template <>
184struct is_arithmetic<unsigned short> {
185 enum { value = true };
186};
187template <>
188struct is_arithmetic<signed int> {
189 enum { value = true };
190};
191template <>
192struct is_arithmetic<unsigned int> {
193 enum { value = true };
194};
195template <>
196struct is_arithmetic<signed long> {
197 enum { value = true };
198};
199template <>
200struct is_arithmetic<unsigned long> {
201 enum { value = true };
202};
203
204template <typename T, typename U>
205struct is_same {
206 enum { value = 0 };
207};
208template <typename T>
209struct is_same<T, T> {
210 enum { value = 1 };
211};
212
213template <class T>
214struct is_void : is_same<void, std::remove_const_t<T>> {};
215
224#if EIGEN_COMP_CXXVER >= 17
225using std::void_t;
226#else
227template <typename...>
228using void_t = void;
229#endif
230
231template <>
232struct is_arithmetic<signed long long> {
233 enum { value = true };
234};
235template <>
236struct is_arithmetic<unsigned long long> {
237 enum { value = true };
238};
239using std::is_integral;
240
241using std::make_unsigned;
242
243template <typename T>
244struct is_const {
245 enum { value = 0 };
246};
247template <typename T>
248struct is_const<T const> {
249 enum { value = 1 };
250};
251
252template <typename T>
253struct add_const_on_value_type {
254 typedef const T type;
255};
256template <typename T>
257struct add_const_on_value_type<T&> {
258 typedef T const& type;
259};
260template <typename T>
261struct add_const_on_value_type<T*> {
262 typedef T const* type;
263};
264template <typename T>
265struct add_const_on_value_type<T* const> {
266 typedef T const* const type;
267};
268template <typename T>
269struct add_const_on_value_type<T const* const> {
270 typedef T const* const type;
271};
272
273template <typename T>
274using add_const_on_value_type_t = typename add_const_on_value_type<T>::type;
275
276using std::is_convertible;
277
281class noncopyable {
282 EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
283 EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
284
285 protected:
286 EIGEN_DEVICE_FUNC noncopyable() {}
287 EIGEN_DEVICE_FUNC ~noncopyable() {}
288};
289
304template <typename T, typename EnableIf = void>
305struct array_size {
306 static constexpr Index value = Dynamic;
307};
308
309template <typename T>
310struct array_size<T, std::enable_if_t<((T::SizeAtCompileTime & 0) == 0)>> {
311 static constexpr Index value = T::SizeAtCompileTime;
312};
313
314template <typename T, int N>
315struct array_size<const T (&)[N]> {
316 static constexpr Index value = N;
317};
318template <typename T, int N>
319struct array_size<T (&)[N]> {
320 static constexpr Index value = N;
321};
322
323template <typename T, std::size_t N>
324struct array_size<const std::array<T, N>> {
325 static constexpr Index value = N;
326};
327template <typename T, std::size_t N>
328struct array_size<std::array<T, N>> {
329 static constexpr Index value = N;
330};
331
342#if EIGEN_COMP_CXXVER < 20 || EIGEN_GNUC_STRICT_LESS_THAN(10, 0, 0)
343template <typename T>
344EIGEN_CONSTEXPR auto index_list_size(const T& x) {
345 using R = std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(x.size())>>;
346 return static_cast<R>(x.size());
347}
348
349template <typename T, std::ptrdiff_t N>
350EIGEN_CONSTEXPR std::ptrdiff_t index_list_size(const T (&)[N]) {
351 return N;
352}
353#else
354template <typename T>
355EIGEN_CONSTEXPR auto index_list_size(T&& x) {
356 using std::ssize;
357 return ssize(std::forward<T>(x));
358}
359#endif // EIGEN_COMP_CXXVER
360
371#if EIGEN_HAS_STD_INVOKE_RESULT
372template <typename T>
373struct result_of;
374
375template <typename F, typename... ArgTypes>
376struct result_of<F(ArgTypes...)> {
377 typedef typename std::invoke_result<F, ArgTypes...>::type type1;
378 typedef remove_all_t<type1> type;
379};
380
381template <typename F, typename... ArgTypes>
382struct invoke_result {
383 typedef typename std::invoke_result<F, ArgTypes...>::type type1;
384 typedef remove_all_t<type1> type;
385};
386#else
387template <typename T>
388struct result_of {
389 typedef typename std::result_of<T>::type type1;
390 typedef remove_all_t<type1> type;
391};
392
393template <typename F, typename... ArgTypes>
394struct invoke_result {
395 typedef typename result_of<F(ArgTypes...)>::type type1;
396 typedef remove_all_t<type1> type;
397};
398#endif
399
400// Reduces a sequence of bools to true if all are true, false otherwise.
401template <bool... values>
402using reduce_all =
403 std::is_same<std::integer_sequence<bool, values..., true>, std::integer_sequence<bool, true, values...>>;
404
405// Reduces a sequence of bools to true if any are true, false if all false.
406template <bool... values>
407using reduce_any = std::integral_constant<bool, !std::is_same<std::integer_sequence<bool, values..., false>,
408 std::integer_sequence<bool, false, values...>>::value>;
409
410struct meta_yes {
411 char a[1];
412};
413struct meta_no {
414 char a[2];
415};
416
417// Check whether T::ReturnType does exist
418template <typename T>
419struct has_ReturnType {
420 template <typename C>
421 static meta_yes testFunctor(C const*, typename C::ReturnType const* = 0);
422 template <typename C>
423 static meta_no testFunctor(...);
424
425 enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
426};
427
428template <typename T>
429const T* return_ptr();
430
431template <typename T, typename IndexType = Index>
432struct has_nullary_operator {
433 template <typename C>
434 static meta_yes testFunctor(C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()()) > 0)>* = 0);
435 static meta_no testFunctor(...);
436
437 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
438};
439
440template <typename T, typename IndexType = Index>
441struct has_unary_operator {
442 template <typename C>
443 static meta_yes testFunctor(C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0))) > 0)>* = 0);
444 static meta_no testFunctor(...);
445
446 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
447};
448
449template <typename T, typename IndexType = Index>
450struct has_binary_operator {
451 template <typename C>
452 static meta_yes testFunctor(
453 C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0), IndexType(0))) > 0)>* = 0);
454 static meta_no testFunctor(...);
455
456 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
457};
458
462template <int Y, int InfX = 0, int SupX = ((Y == 1) ? 1 : Y / 2),
463 bool Done = ((SupX - InfX) <= 1 || ((SupX * SupX <= Y) && ((SupX + 1) * (SupX + 1) > Y)))>
464class meta_sqrt {
465 enum {
466 MidX = (InfX + SupX) / 2,
467 TakeInf = MidX * MidX > Y ? 1 : 0,
468 NewInf = int(TakeInf) ? InfX : int(MidX),
469 NewSup = int(TakeInf) ? int(MidX) : SupX
470 };
471
472 public:
473 enum { ret = meta_sqrt<Y, NewInf, NewSup>::ret };
474};
475
476template <int Y, int InfX, int SupX>
477class meta_sqrt<Y, InfX, SupX, true> {
478 public:
479 enum { ret = (SupX * SupX <= Y) ? SupX : InfX };
480};
481
485template <int A, int B, int K = 1, bool Done = ((A * K) % B) == 0, bool Big = (A >= B)>
486struct meta_least_common_multiple {
487 enum { ret = meta_least_common_multiple<A, B, K + 1>::ret };
488};
489template <int A, int B, int K, bool Done>
490struct meta_least_common_multiple<A, B, K, Done, false> {
491 enum { ret = meta_least_common_multiple<B, A, K>::ret };
492};
493template <int A, int B, int K>
494struct meta_least_common_multiple<A, B, K, true, true> {
495 enum { ret = A * K };
496};
497
499template <typename T, typename U>
500struct scalar_product_traits {
501 enum { Defined = 0 };
502};
503
504// FIXME quick workaround around current limitation of result_of
505// template<typename Scalar, typename ArgType0, typename ArgType1>
506// struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
507// typedef typename scalar_product_traits<remove_all_t<ArgType0>, remove_all_t<ArgType1>>::ReturnType type;
508// };
509
513template <unsigned Len, unsigned Align>
514struct aligned_storage {
515 struct type {
516 EIGEN_ALIGN_TO_BOUNDARY(Align) unsigned char data[Len];
517 };
518};
519
520} // end namespace internal
521
522template <typename T>
524
525namespace numext {
526
527#if defined(EIGEN_GPU_COMPILE_PHASE)
528template <typename T>
529EIGEN_DEVICE_FUNC void swap(T& a, T& b) {
530 T tmp = b;
531 b = a;
532 a = tmp;
533}
534#else
535template <typename T>
536EIGEN_STRONG_INLINE void swap(T& a, T& b) {
537 std::swap(a, b);
538}
539#endif
540
541using std::numeric_limits;
542
543// Handle integer comparisons of different signedness.
544template <typename X, typename Y, bool XIsInteger = NumTraits<X>::IsInteger, bool XIsSigned = NumTraits<X>::IsSigned,
545 bool YIsInteger = NumTraits<Y>::IsInteger, bool YIsSigned = NumTraits<Y>::IsSigned>
546struct equal_strict_impl {
547 static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) { return x == y; }
548};
549template <typename X, typename Y>
550struct equal_strict_impl<X, Y, true, false, true, true> {
551 // X is an unsigned integer
552 // Y is a signed integer
553 // if Y is non-negative, it may be represented exactly as its unsigned counterpart.
554 using UnsignedY = typename internal::make_unsigned<Y>::type;
555 static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
556 return y < Y(0) ? false : (x == static_cast<UnsignedY>(y));
557 }
558};
559template <typename X, typename Y>
560struct equal_strict_impl<X, Y, true, true, true, false> {
561 // X is a signed integer
562 // Y is an unsigned integer
563 static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
564 return equal_strict_impl<Y, X>::run(y, x);
565 }
566};
567
568// The aim of the following functions is to bypass -Wfloat-equal warnings
569// when we really want a strict equality comparison on floating points.
570template <typename X, typename Y>
571EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X& x, const Y& y) {
572 return equal_strict_impl<X, Y>::run(x, y);
573}
574
575#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
576template <>
577EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const float& x, const float& y) {
578 return std::equal_to<float>()(x, y);
579}
580
581template <>
582EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const double& x, const double& y) {
583 return std::equal_to<double>()(x, y);
584}
585#endif
586
591template <typename X>
592EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X& x) {
593 return equal_strict(x, typename NumTraits<X>::Literal{0});
594}
595
600template <typename X>
601EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_one(const X& x) {
602 return equal_strict(x, typename NumTraits<X>::Literal{1});
603}
604
605template <typename X, typename Y>
606EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const X& x, const Y& y) {
607 return !equal_strict_impl<X, Y>::run(x, y);
608}
609
610#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
611template <>
612EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const float& x, const float& y) {
613 return std::not_equal_to<float>()(x, y);
614}
615
616template <>
617EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const double& x, const double& y) {
618 return std::not_equal_to<double>()(x, y);
619}
620#endif
621
622} // end namespace numext
623
624namespace internal {
625
626template <typename Scalar>
627struct is_identically_zero_impl {
628 static inline bool run(const Scalar& s) { return numext::is_exactly_zero(s); }
629};
630
631template <typename Scalar>
632EIGEN_STRONG_INLINE bool is_identically_zero(const Scalar& s) {
633 return is_identically_zero_impl<Scalar>::run(s);
634}
635
638template <typename A>
639constexpr bool is_int_or_enum_v = std::is_enum<A>::value || std::is_integral<A>::value;
640
642template <typename A, typename B>
643inline constexpr int plain_enum_min(A a, B b) {
644 static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
645 static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
646 return ((int)a <= (int)b) ? (int)a : (int)b;
647}
648
650template <typename A, typename B>
651inline constexpr int plain_enum_max(A a, B b) {
652 static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
653 static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
654 return ((int)a >= (int)b) ? (int)a : (int)b;
655}
656
663template <typename A, typename B>
664inline constexpr int min_size_prefer_dynamic(A a, B b) {
665 static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
666 static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
667 if ((int)a == 0 || (int)b == 0) return 0;
668 if ((int)a == 1 || (int)b == 1) return 1;
669 if ((int)a == Dynamic || (int)b == Dynamic) return Dynamic;
670 return plain_enum_min(a, b);
671}
672
679template <typename A, typename B>
680inline constexpr int min_size_prefer_fixed(A a, B b) {
681 static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
682 static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
683 if ((int)a == 0 || (int)b == 0) return 0;
684 if ((int)a == 1 || (int)b == 1) return 1;
685 if ((int)a == Dynamic && (int)b == Dynamic) return Dynamic;
686 if ((int)a == Dynamic) return (int)b;
687 if ((int)b == Dynamic) return (int)a;
688 return plain_enum_min(a, b);
689}
690
692template <typename A, typename B>
693inline constexpr int max_size_prefer_dynamic(A a, B b) {
694 static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
695 static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
696 if ((int)a == Dynamic || (int)b == Dynamic) return Dynamic;
697 return plain_enum_max(a, b);
698}
699
701inline constexpr bool logical_xor(bool a, bool b) { return a != b; }
702
704inline constexpr bool check_implication(bool a, bool b) { return !a || b; }
705
707#if EIGEN_COMP_CXXVER >= 20
708using std::is_constant_evaluated;
709#else
710constexpr bool is_constant_evaluated() { return false; }
711#endif
712
713} // end namespace internal
714
715} // end namespace Eigen
716
717#endif // EIGEN_META_H
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const int Dynamic
Definition Constants.h:25
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition Meta.h:523