Eigen  5.0.1-dev+60122df6
 
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 <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_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
82typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
83
84namespace internal {
85
92
93using std::false_type;
94using std::true_type;
95
96template <bool Condition>
97struct bool_constant;
98
99template <>
100struct bool_constant<true> : true_type {};
101
102template <>
103struct bool_constant<false> : false_type {};
104
105// Third-party libraries rely on these.
106using std::conditional;
107using std::remove_const;
108using std::remove_pointer;
109using std::remove_reference;
110
111template <typename T>
112struct remove_all {
113 typedef T type;
114};
115template <typename T>
116struct remove_all<const T> {
117 typedef typename remove_all<T>::type type;
118};
119template <typename T>
120struct remove_all<T const&> {
121 typedef typename remove_all<T>::type type;
122};
123template <typename T>
124struct remove_all<T&> {
125 typedef typename remove_all<T>::type type;
126};
127template <typename T>
128struct remove_all<T const*> {
129 typedef typename remove_all<T>::type type;
130};
131template <typename T>
132struct remove_all<T*> {
133 typedef typename remove_all<T>::type type;
134};
135
136template <typename T>
137using remove_all_t = typename remove_all<T>::type;
138
139template <typename T>
140struct is_arithmetic {
141 enum { value = false };
142};
143template <>
144struct is_arithmetic<float> {
145 enum { value = true };
146};
147template <>
148struct is_arithmetic<double> {
149 enum { value = true };
150};
151// GPU devices treat `long double` as `double`.
152#ifndef EIGEN_GPU_COMPILE_PHASE
153template <>
154struct is_arithmetic<long double> {
155 enum { value = true };
156};
157#endif
158template <>
159struct is_arithmetic<bool> {
160 enum { value = true };
161};
162template <>
163struct is_arithmetic<char> {
164 enum { value = true };
165};
166template <>
167struct is_arithmetic<signed char> {
168 enum { value = true };
169};
170template <>
171struct is_arithmetic<unsigned char> {
172 enum { value = true };
173};
174template <>
175struct is_arithmetic<signed short> {
176 enum { value = true };
177};
178template <>
179struct is_arithmetic<unsigned short> {
180 enum { value = true };
181};
182template <>
183struct is_arithmetic<signed int> {
184 enum { value = true };
185};
186template <>
187struct is_arithmetic<unsigned int> {
188 enum { value = true };
189};
190template <>
191struct is_arithmetic<signed long> {
192 enum { value = true };
193};
194template <>
195struct is_arithmetic<unsigned long> {
196 enum { value = true };
197};
198
199template <typename T, typename U>
200struct is_same {
201 enum { value = 0 };
202};
203template <typename T>
204struct is_same<T, T> {
205 enum { value = 1 };
206};
207
208template <class T>
209struct is_void : is_same<void, std::remove_const_t<T>> {};
210
219#if EIGEN_COMP_CXXVER >= 17 && defined(__cpp_lib_void_t) && __cpp_lib_void_t >= 201411L
220using std::void_t;
221#else
222template <typename...>
223using void_t = void;
224#endif
225
226template <>
227struct is_arithmetic<signed long long> {
228 enum { value = true };
229};
230template <>
231struct is_arithmetic<unsigned long long> {
232 enum { value = true };
233};
234using std::is_integral;
235
236using std::make_unsigned;
237
238template <typename T>
239struct is_const {
240 enum { value = 0 };
241};
242template <typename T>
243struct is_const<T const> {
244 enum { value = 1 };
245};
246
247template <typename T>
248struct add_const_on_value_type {
249 typedef const T type;
250};
251template <typename T>
252struct add_const_on_value_type<T&> {
253 typedef T const& type;
254};
255template <typename T>
256struct add_const_on_value_type<T*> {
257 typedef T const* type;
258};
259template <typename T>
260struct add_const_on_value_type<T* const> {
261 typedef T const* const type;
262};
263template <typename T>
264struct add_const_on_value_type<T const* const> {
265 typedef T const* const type;
266};
267
268template <typename T>
269using add_const_on_value_type_t = typename add_const_on_value_type<T>::type;
270
271using std::is_convertible;
272
276class noncopyable {
277 EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
278 EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
279
280 protected:
281 EIGEN_DEVICE_FUNC noncopyable() {}
282 EIGEN_DEVICE_FUNC ~noncopyable() {}
283};
284
299template <typename T, typename EnableIf = void>
300struct array_size {
301 static constexpr Index value = Dynamic;
302};
303
304template <typename T>
305struct array_size<T, std::enable_if_t<((T::SizeAtCompileTime & 0) == 0)>> {
306 static constexpr Index value = T::SizeAtCompileTime;
307};
308
309template <typename T, int N>
310struct array_size<const T (&)[N]> {
311 static constexpr Index value = N;
312};
313template <typename T, int N>
314struct array_size<T (&)[N]> {
315 static constexpr Index value = N;
316};
317
318template <typename T, std::size_t N>
319struct array_size<const std::array<T, N>> {
320 static constexpr Index value = N;
321};
322template <typename T, std::size_t N>
323struct array_size<std::array<T, N>> {
324 static constexpr Index value = N;
325};
326
337#if EIGEN_COMP_CXXVER >= 20 && defined(__cpp_lib_ssize) && __cpp_lib_ssize >= 201902L
338
339template <typename T>
340constexpr auto index_list_size(T&& x) {
341 using std::ssize;
342 return ssize(std::forward<T>(x));
343}
344
345#else
346
347template <typename T>
348constexpr auto index_list_size(const T& x) {
349 using R = std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(x.size())>>;
350 return static_cast<R>(x.size());
351}
352
353template <typename T, std::ptrdiff_t N>
354constexpr std::ptrdiff_t index_list_size(const T (&)[N]) {
355 return N;
356}
357#endif
358
369#if EIGEN_HAS_STD_INVOKE_RESULT
370template <typename T>
371struct result_of;
372
373template <typename F, typename... ArgTypes>
374struct result_of<F(ArgTypes...)> {
375 typedef typename std::invoke_result<F, ArgTypes...>::type type1;
376 typedef remove_all_t<type1> type;
377};
378
379template <typename F, typename... ArgTypes>
380struct invoke_result {
381 typedef typename std::invoke_result<F, ArgTypes...>::type type1;
382 typedef remove_all_t<type1> type;
383};
384#else
385template <typename T>
386struct result_of {
387 typedef typename std::result_of<T>::type type1;
388 typedef remove_all_t<type1> type;
389};
390
391template <typename F, typename... ArgTypes>
392struct invoke_result {
393 typedef typename result_of<F(ArgTypes...)>::type type1;
394 typedef remove_all_t<type1> type;
395};
396#endif
397
398// Reduces a sequence of bools to true if all are true, false otherwise.
399template <bool... values>
400using reduce_all =
401 std::is_same<std::integer_sequence<bool, values..., true>, std::integer_sequence<bool, true, values...>>;
402
403// Reduces a sequence of bools to true if any are true, false if all false.
404template <bool... values>
405using reduce_any = std::integral_constant<bool, !std::is_same<std::integer_sequence<bool, values..., false>,
406 std::integer_sequence<bool, false, values...>>::value>;
407
408struct meta_yes {
409 char a[1];
410};
411struct meta_no {
412 char a[2];
413};
414
415// Check whether T::ReturnType does exist
416template <typename T>
417struct has_ReturnType {
418 template <typename C>
419 static meta_yes testFunctor(C const*, typename C::ReturnType const* = 0);
420 template <typename C>
421 static meta_no testFunctor(...);
422
423 enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
424};
425
426template <typename T>
427const T* return_ptr();
428
429template <typename T, typename IndexType = Index>
430struct has_nullary_operator {
431 template <typename C>
432 static meta_yes testFunctor(C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()()) > 0)>* = 0);
433 static meta_no testFunctor(...);
434
435 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
436};
437
438template <typename T, typename IndexType = Index>
439struct has_unary_operator {
440 template <typename C>
441 static meta_yes testFunctor(C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0))) > 0)>* = 0);
442 static meta_no testFunctor(...);
443
444 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
445};
446
447template <typename T, typename IndexType = Index>
448struct has_binary_operator {
449 template <typename C>
450 static meta_yes testFunctor(
451 C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0), IndexType(0))) > 0)>* = 0);
452 static meta_no testFunctor(...);
453
454 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
455};
456
460template <int Y, int InfX = 0, int SupX = ((Y == 1) ? 1 : Y / 2),
461 bool Done = ((SupX - InfX) <= 1 || ((SupX * SupX <= Y) && ((SupX + 1) * (SupX + 1) > Y)))>
462class meta_sqrt {
463 enum {
464 MidX = (InfX + SupX) / 2,
465 TakeInf = MidX * MidX > Y ? 1 : 0,
466 NewInf = int(TakeInf) ? InfX : int(MidX),
467 NewSup = int(TakeInf) ? int(MidX) : SupX
468 };
469
470 public:
471 enum { ret = meta_sqrt<Y, NewInf, NewSup>::ret };
472};
473
474template <int Y, int InfX, int SupX>
475class meta_sqrt<Y, InfX, SupX, true> {
476 public:
477 enum { ret = (SupX * SupX <= Y) ? SupX : InfX };
478};
479
483template <int A, int B, int K = 1, bool Done = ((A * K) % B) == 0, bool Big = (A >= B)>
484struct meta_least_common_multiple {
485 enum { ret = meta_least_common_multiple<A, B, K + 1>::ret };
486};
487template <int A, int B, int K, bool Done>
488struct meta_least_common_multiple<A, B, K, Done, false> {
489 enum { ret = meta_least_common_multiple<B, A, K>::ret };
490};
491template <int A, int B, int K>
492struct meta_least_common_multiple<A, B, K, true, true> {
493 enum { ret = A * K };
494};
495
497template <typename T, typename U>
498struct scalar_product_traits {
499 enum { Defined = 0 };
500};
501
502// FIXME quick workaround around current limitation of result_of
503// template<typename Scalar, typename ArgType0, typename ArgType1>
504// struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
505// typedef typename scalar_product_traits<remove_all_t<ArgType0>, remove_all_t<ArgType1>>::ReturnType type;
506// };
507
511template <unsigned Len, unsigned Align>
512struct aligned_storage {
513 struct type {
514 EIGEN_ALIGN_TO_BOUNDARY(Align) unsigned char data[Len];
515 };
516};
517
518} // end namespace internal
519
520template <typename T>
521struct NumTraits;
522
523namespace numext {
524
525#if defined(EIGEN_GPU_COMPILE_PHASE)
526template <typename T>
527EIGEN_DEVICE_FUNC void swap(T& a, T& b) {
528 T tmp = b;
529 b = a;
530 a = tmp;
531}
532#else
533template <typename T>
534EIGEN_STRONG_INLINE void swap(T& a, T& b) {
535 std::swap(a, b);
536}
537#endif
538
539using std::numeric_limits;
540
541// Handle integer comparisons of different signedness.
542template <typename X, typename Y, bool XIsInteger = NumTraits<X>::IsInteger, bool XIsSigned = NumTraits<X>::IsSigned,
543 bool YIsInteger = NumTraits<Y>::IsInteger, bool YIsSigned = NumTraits<Y>::IsSigned>
544struct equal_strict_impl {
545 static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) { return x == y; }
546};
547template <typename X, typename Y>
548struct equal_strict_impl<X, Y, true, false, true, true> {
549 // X is an unsigned integer
550 // Y is a signed integer
551 // if Y is non-negative, it may be represented exactly as its unsigned counterpart.
552 using UnsignedY = typename internal::make_unsigned<Y>::type;
553 static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
554 return y < Y(0) ? false : (x == static_cast<UnsignedY>(y));
555 }
556};
557template <typename X, typename Y>
558struct equal_strict_impl<X, Y, true, true, true, false> {
559 // X is a signed integer
560 // Y is an unsigned integer
561 static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
562 return equal_strict_impl<Y, X>::run(y, x);
563 }
564};
565
566// The aim of the following functions is to bypass -Wfloat-equal warnings
567// when we really want a strict equality comparison on floating points.
568template <typename X, typename Y>
569EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X& x, const Y& y) {
570 return equal_strict_impl<X, Y>::run(x, y);
571}
572
573#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
574template <>
575EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const float& x, const float& y) {
576 return std::equal_to<float>()(x, y);
577}
578
579template <>
580EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const double& x, const double& y) {
581 return std::equal_to<double>()(x, y);
582}
583#endif
584
589template <typename X>
590EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X& x) {
591 return equal_strict(x, typename NumTraits<X>::Literal{0});
592}
593
598template <typename X>
599EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_one(const X& x) {
600 return equal_strict(x, typename NumTraits<X>::Literal{1});
601}
602
603template <typename X, typename Y>
604EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const X& x, const Y& y) {
605 return !equal_strict_impl<X, Y>::run(x, y);
606}
607
608#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
609template <>
610EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const float& x, const float& y) {
611 return std::not_equal_to<float>()(x, y);
612}
613
614template <>
615EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const double& x, const double& y) {
616 return std::not_equal_to<double>()(x, y);
617}
618#endif
619
620} // end namespace numext
621
622namespace internal {
623
624template <typename Scalar>
625struct is_identically_zero_impl {
626 static inline bool run(const Scalar& s) { return numext::is_exactly_zero(s); }
627};
628
629template <typename Scalar>
630EIGEN_STRONG_INLINE bool is_identically_zero(const Scalar& s) {
631 return is_identically_zero_impl<Scalar>::run(s);
632}
633
636template <typename A>
637constexpr bool is_int_or_enum_v = std::is_enum<A>::value || std::is_integral<A>::value;
638
639template <typename A, typename B>
640constexpr void plain_enum_asserts(A, B) {
641 static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
642 static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
643}
644
646template <typename A, typename B>
647constexpr int plain_enum_min(A a, B b) {
648 plain_enum_asserts(a, b);
649 return ((int)a <= (int)b) ? (int)a : (int)b;
650}
651
653template <typename A, typename B>
654constexpr int plain_enum_max(A a, B b) {
655 plain_enum_asserts(a, b);
656 return ((int)a >= (int)b) ? (int)a : (int)b;
657}
658
665template <typename A, typename B>
666constexpr int min_size_prefer_dynamic(A a, B b) {
667 plain_enum_asserts(a, b);
668 if ((int)a == 0 || (int)b == 0) return 0;
669 if ((int)a == 1 || (int)b == 1) return 1;
670 if ((int)a == Dynamic || (int)b == Dynamic) return Dynamic;
671 return plain_enum_min(a, b);
672}
673
680template <typename A, typename B>
681constexpr int min_size_prefer_fixed(A a, B b) {
682 plain_enum_asserts(a, b);
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>
693constexpr int max_size_prefer_dynamic(A a, B b) {
694 plain_enum_asserts(a, b);
695 if ((int)a == Dynamic || (int)b == Dynamic) return Dynamic;
696 return plain_enum_max(a, b);
697}
698
699template <typename A, typename B>
700inline constexpr int size_prefer_fixed(A a, B b) {
701 plain_enum_asserts(a, b);
702 return int(a) == Dynamic ? int(b) : int(a);
703}
704
705template <typename A, typename B>
706inline constexpr bool enum_eq_not_dynamic(A a, B b) {
707 plain_enum_asserts(a, b);
708 if ((int)a == Dynamic || (int)b == Dynamic) return false;
709 return (int)a == (int)b;
710}
711
712template <typename A, typename B>
713constexpr bool enum_lt_not_dynamic(A a, B b) {
714 plain_enum_asserts(a, b);
715 if ((int)a == Dynamic || (int)b == Dynamic) return false;
716 return (int)a < (int)b;
717}
718
719template <typename A, typename B>
720constexpr bool enum_le_not_dynamic(A a, B b) {
721 plain_enum_asserts(a, b);
722 if ((int)a == Dynamic || (int)b == Dynamic) return false;
723 return (int)a <= (int)b;
724}
725
726template <typename A, typename B>
727constexpr bool enum_gt_not_dynamic(A a, B b) {
728 plain_enum_asserts(a, b);
729 if ((int)a == Dynamic || (int)b == Dynamic) return false;
730 return (int)a > (int)b;
731}
732
733template <typename A, typename B>
734constexpr bool enum_ge_not_dynamic(A a, B b) {
735 plain_enum_asserts(a, b);
736 if ((int)a == Dynamic || (int)b == Dynamic) return false;
737 return (int)a >= (int)b;
738}
739
741constexpr bool logical_xor(bool a, bool b) { return a != b; }
742
744constexpr bool check_implication(bool a, bool b) { return !a || b; }
745
747#if EIGEN_COMP_CXXVER >= 20 && defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
748using std::is_constant_evaluated;
749#else
750constexpr bool is_constant_evaluated() { return false; }
751#endif
752
753template <typename Scalar>
754using make_complex_t = std::conditional_t<NumTraits<Scalar>::IsComplex, Scalar, std::complex<Scalar>>;
755
756} // end namespace internal
757
758} // end namespace Eigen
759
760#endif // EIGEN_META_H
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
const int Dynamic
Definition Constants.h:25