Eigen  3.3.9
 
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#if defined(__CUDA_ARCH__)
15#include <cfloat>
16#include <math_constants.h>
17#endif
18
19// Recent versions of ICC require <cstdint> for pointer types below.
20#define EIGEN_ICC_NEEDS_CSTDINT (EIGEN_COMP_ICC>=1600 && EIGEN_COMP_CXXVER >= 11)
21
22// Define portable (u)int{32,64} types
23#if EIGEN_HAS_CXX11 || EIGEN_ICC_NEEDS_CSTDINT
24#include <cstdint>
25namespace Eigen {
26namespace numext {
27typedef std::uint8_t uint8_t;
28typedef std::int8_t int8_t;
29typedef std::uint16_t uint16_t;
30typedef std::int16_t int16_t;
31typedef std::uint32_t uint32_t;
32typedef std::int32_t int32_t;
33typedef std::uint64_t uint64_t;
34typedef std::int64_t int64_t;
35}
36}
37#else
38// Without c++11, all compilers able to compile Eigen also
39// provide the C99 stdint.h header file.
40#include <stdint.h>
41namespace Eigen {
42namespace numext {
43typedef ::uint8_t uint8_t;
44typedef ::int8_t int8_t;
45typedef ::uint16_t uint16_t;
46typedef ::int16_t int16_t;
47typedef ::uint32_t uint32_t;
48typedef ::int32_t int32_t;
49typedef ::uint64_t uint64_t;
50typedef ::int64_t int64_t;
51}
52}
53#endif
54
55namespace Eigen {
56
57typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
58
64
65typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
66
67namespace internal {
68
75
76// Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
77// and older versions do not provide *intptr_t types.
78#if EIGEN_ICC_NEEDS_CSTDINT
79typedef std::intptr_t IntPtr;
80typedef std::uintptr_t UIntPtr;
81#else
82typedef std::ptrdiff_t IntPtr;
83typedef std::size_t UIntPtr;
84#endif
85#undef EIGEN_ICC_NEEDS_CSTDINT
86
87struct true_type { enum { value = 1 }; };
88struct false_type { enum { value = 0 }; };
89
90template<bool Condition, typename Then, typename Else>
91struct conditional { typedef Then type; };
92
93template<typename Then, typename Else>
94struct conditional <false, Then, Else> { typedef Else type; };
95
96template<typename T, typename U> struct is_same { enum { value = 0 }; };
97template<typename T> struct is_same<T,T> { enum { value = 1 }; };
98
99template<typename T> struct remove_reference { typedef T type; };
100template<typename T> struct remove_reference<T&> { typedef T type; };
101
102template<typename T> struct remove_pointer { typedef T type; };
103template<typename T> struct remove_pointer<T*> { typedef T type; };
104template<typename T> struct remove_pointer<T*const> { typedef T type; };
105
106template <class T> struct remove_const { typedef T type; };
107template <class T> struct remove_const<const T> { typedef T type; };
108template <class T> struct remove_const<const T[]> { typedef T type[]; };
109template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
110
111template<typename T> struct remove_all { typedef T type; };
112template<typename T> struct remove_all<const T> { typedef typename remove_all<T>::type type; };
113template<typename T> struct remove_all<T const&> { typedef typename remove_all<T>::type type; };
114template<typename T> struct remove_all<T&> { typedef typename remove_all<T>::type type; };
115template<typename T> struct remove_all<T const*> { typedef typename remove_all<T>::type type; };
116template<typename T> struct remove_all<T*> { typedef typename remove_all<T>::type type; };
117
118template<typename T> struct is_arithmetic { enum { value = false }; };
119template<> struct is_arithmetic<float> { enum { value = true }; };
120template<> struct is_arithmetic<double> { enum { value = true }; };
121template<> struct is_arithmetic<long double> { enum { value = true }; };
122template<> struct is_arithmetic<bool> { enum { value = true }; };
123template<> struct is_arithmetic<char> { enum { value = true }; };
124template<> struct is_arithmetic<signed char> { enum { value = true }; };
125template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
126template<> struct is_arithmetic<signed short> { enum { value = true }; };
127template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
128template<> struct is_arithmetic<signed int> { enum { value = true }; };
129template<> struct is_arithmetic<unsigned int> { enum { value = true }; };
130template<> struct is_arithmetic<signed long> { enum { value = true }; };
131template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
132
133#if EIGEN_HAS_CXX11
134using std::is_integral;
135#else
136template<typename T> struct is_integral { enum { value = false }; };
137template<> struct is_integral<bool> { enum { value = true }; };
138template<> struct is_integral<char> { enum { value = true }; };
139template<> struct is_integral<signed char> { enum { value = true }; };
140template<> struct is_integral<unsigned char> { enum { value = true }; };
141template<> struct is_integral<signed short> { enum { value = true }; };
142template<> struct is_integral<unsigned short> { enum { value = true }; };
143template<> struct is_integral<signed int> { enum { value = true }; };
144template<> struct is_integral<unsigned int> { enum { value = true }; };
145template<> struct is_integral<signed long> { enum { value = true }; };
146template<> struct is_integral<unsigned long> { enum { value = true }; };
147#if EIGEN_COMP_MSVC
148template<> struct is_integral<signed __int64> { enum { value = true }; };
149template<> struct is_integral<unsigned __int64>{ enum { value = true }; };
150#endif
151#endif
152
153#if EIGEN_HAS_CXX11
154using std::make_unsigned;
155#else
156// TODO: Possibly improve this implementation of make_unsigned.
157// It is currently used only by
158// template<typename Scalar> struct random_default_impl<Scalar, false, true>.
159template<typename> struct make_unsigned;
160template<> struct make_unsigned<char> { typedef unsigned char type; };
161template<> struct make_unsigned<signed char> { typedef unsigned char type; };
162template<> struct make_unsigned<unsigned char> { typedef unsigned char type; };
163template<> struct make_unsigned<signed short> { typedef unsigned short type; };
164template<> struct make_unsigned<unsigned short> { typedef unsigned short type; };
165template<> struct make_unsigned<signed int> { typedef unsigned int type; };
166template<> struct make_unsigned<unsigned int> { typedef unsigned int type; };
167template<> struct make_unsigned<signed long> { typedef unsigned long type; };
168template<> struct make_unsigned<unsigned long> { typedef unsigned long type; };
169template<> struct make_unsigned<signed long long> { typedef unsigned long type; };
170template<> struct make_unsigned<unsigned long long> { typedef unsigned long type; };
171#endif
172
173template <typename T> struct add_const { typedef const T type; };
174template <typename T> struct add_const<T&> { typedef T& type; };
175
176template <typename T> struct is_const { enum { value = 0 }; };
177template <typename T> struct is_const<T const> { enum { value = 1 }; };
178
179template<typename T> struct add_const_on_value_type { typedef const T type; };
180template<typename T> struct add_const_on_value_type<T&> { typedef T const& type; };
181template<typename T> struct add_const_on_value_type<T*> { typedef T const* type; };
182template<typename T> struct add_const_on_value_type<T* const> { typedef T const* const type; };
183template<typename T> struct add_const_on_value_type<T const* const> { typedef T const* const type; };
184
185
186template<typename From, typename To>
187struct is_convertible_impl
188{
189private:
190 struct any_conversion
191 {
192 template <typename T> any_conversion(const volatile T&);
193 template <typename T> any_conversion(T&);
194 };
195 struct yes {int a[1];};
196 struct no {int a[2];};
197
198 static yes test(const To&, int);
199 static no test(any_conversion, ...);
200
201public:
202 static From ms_from;
203#ifdef __INTEL_COMPILER
204 #pragma warning push
205 #pragma warning ( disable : 2259 )
206#endif
207 enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
208#ifdef __INTEL_COMPILER
209 #pragma warning pop
210#endif
211};
212
213template<typename From, typename To>
214struct is_convertible
215{
216 enum { value = is_convertible_impl<typename remove_all<From>::type,
217 typename remove_all<To >::type>::value };
218};
219
223template<bool Condition, typename T=void> struct enable_if;
224
225template<typename T> struct enable_if<true,T>
226{ typedef T type; };
227
228#if defined(__CUDA_ARCH__)
229#if !defined(__FLT_EPSILON__)
230#define __FLT_EPSILON__ FLT_EPSILON
231#define __DBL_EPSILON__ DBL_EPSILON
232#endif
233
234namespace device {
235
236template<typename T> struct numeric_limits
237{
238 EIGEN_DEVICE_FUNC
239 static T epsilon() { return 0; }
240 static T (max)() { assert(false && "Highest not supported for this type"); }
241 static T (min)() { assert(false && "Lowest not supported for this type"); }
242 static T infinity() { assert(false && "Infinity not supported for this type"); }
243 static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
244};
245template<> struct numeric_limits<float>
246{
247 EIGEN_DEVICE_FUNC
248 static float epsilon() { return __FLT_EPSILON__; }
249 EIGEN_DEVICE_FUNC
250 static float (max)() { return CUDART_MAX_NORMAL_F; }
251 EIGEN_DEVICE_FUNC
252 static float (min)() { return FLT_MIN; }
253 EIGEN_DEVICE_FUNC
254 static float infinity() { return CUDART_INF_F; }
255 EIGEN_DEVICE_FUNC
256 static float quiet_NaN() { return CUDART_NAN_F; }
257};
258template<> struct numeric_limits<double>
259{
260 EIGEN_DEVICE_FUNC
261 static double epsilon() { return __DBL_EPSILON__; }
262 EIGEN_DEVICE_FUNC
263 static double (max)() { return DBL_MAX; }
264 EIGEN_DEVICE_FUNC
265 static double (min)() { return DBL_MIN; }
266 EIGEN_DEVICE_FUNC
267 static double infinity() { return CUDART_INF; }
268 EIGEN_DEVICE_FUNC
269 static double quiet_NaN() { return CUDART_NAN; }
270};
271template<> struct numeric_limits<int>
272{
273 EIGEN_DEVICE_FUNC
274 static int epsilon() { return 0; }
275 EIGEN_DEVICE_FUNC
276 static int (max)() { return INT_MAX; }
277 EIGEN_DEVICE_FUNC
278 static int (min)() { return INT_MIN; }
279};
280template<> struct numeric_limits<unsigned int>
281{
282 EIGEN_DEVICE_FUNC
283 static unsigned int epsilon() { return 0; }
284 EIGEN_DEVICE_FUNC
285 static unsigned int (max)() { return UINT_MAX; }
286 EIGEN_DEVICE_FUNC
287 static unsigned int (min)() { return 0; }
288};
289template<> struct numeric_limits<long>
290{
291 EIGEN_DEVICE_FUNC
292 static long epsilon() { return 0; }
293 EIGEN_DEVICE_FUNC
294 static long (max)() { return LONG_MAX; }
295 EIGEN_DEVICE_FUNC
296 static long (min)() { return LONG_MIN; }
297};
298template<> struct numeric_limits<unsigned long>
299{
300 EIGEN_DEVICE_FUNC
301 static unsigned long epsilon() { return 0; }
302 EIGEN_DEVICE_FUNC
303 static unsigned long (max)() { return ULONG_MAX; }
304 EIGEN_DEVICE_FUNC
305 static unsigned long (min)() { return 0; }
306};
307template<> struct numeric_limits<long long>
308{
309 EIGEN_DEVICE_FUNC
310 static long long epsilon() { return 0; }
311 EIGEN_DEVICE_FUNC
312 static long long (max)() { return LLONG_MAX; }
313 EIGEN_DEVICE_FUNC
314 static long long (min)() { return LLONG_MIN; }
315};
316template<> struct numeric_limits<unsigned long long>
317{
318 EIGEN_DEVICE_FUNC
319 static unsigned long long epsilon() { return 0; }
320 EIGEN_DEVICE_FUNC
321 static unsigned long long (max)() { return ULLONG_MAX; }
322 EIGEN_DEVICE_FUNC
323 static unsigned long long (min)() { return 0; }
324};
325
326}
327
328#endif
329
333class noncopyable
334{
335 EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
336 EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
337protected:
338 EIGEN_DEVICE_FUNC noncopyable() {}
339 EIGEN_DEVICE_FUNC ~noncopyable() {}
340};
341
349#if EIGEN_HAS_STD_RESULT_OF
350template<typename T> struct result_of {
351 typedef typename std::result_of<T>::type type1;
352 typedef typename remove_all<type1>::type type;
353};
354#else
355template<typename T> struct result_of { };
356
357struct has_none {int a[1];};
358struct has_std_result_type {int a[2];};
359struct has_tr1_result {int a[3];};
360
361template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
362struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
363
364template<typename Func, typename ArgType>
365struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
366
367template<typename Func, typename ArgType>
368struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
369
370template<typename Func, typename ArgType>
371struct result_of<Func(ArgType)> {
372 template<typename T>
373 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
374 template<typename T>
375 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
376 static has_none testFunctor(...);
377
378 // note that the following indirection is needed for gcc-3.3
379 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
380 typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
381};
382
383template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
384struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
385
386template<typename Func, typename ArgType0, typename ArgType1>
387struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
388{typedef typename Func::result_type type;};
389
390template<typename Func, typename ArgType0, typename ArgType1>
391struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
392{typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
393
394template<typename Func, typename ArgType0, typename ArgType1>
395struct result_of<Func(ArgType0,ArgType1)> {
396 template<typename T>
397 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
398 template<typename T>
399 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
400 static has_none testFunctor(...);
401
402 // note that the following indirection is needed for gcc-3.3
403 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
404 typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
405};
406
407template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)>
408struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
409
410template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
411struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)>
412{typedef typename Func::result_type type;};
413
414template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
415struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)>
416{typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;};
417
418template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
419struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
420 template<typename T>
421 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
422 template<typename T>
423 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0);
424 static has_none testFunctor(...);
425
426 // note that the following indirection is needed for gcc-3.3
427 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
428 typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
429};
430#endif
431
432struct meta_yes { char a[1]; };
433struct meta_no { char a[2]; };
434
435// Check whether T::ReturnType does exist
436template <typename T>
437struct has_ReturnType
438{
439 template <typename C> static meta_yes testFunctor(typename C::ReturnType const *);
440 template <typename C> static meta_no testFunctor(...);
441
442 enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) };
443};
444
445template<typename T> const T* return_ptr();
446
447template <typename T, typename IndexType=Index>
448struct has_nullary_operator
449{
450 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
451 static meta_no testFunctor(...);
452
453 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
454};
455
456template <typename T, typename IndexType=Index>
457struct has_unary_operator
458{
459 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0);
460 static meta_no testFunctor(...);
461
462 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
463};
464
465template <typename T, typename IndexType=Index>
466struct has_binary_operator
467{
468 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0);
469 static meta_no testFunctor(...);
470
471 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
472};
473
477template<int Y,
478 int InfX = 0,
479 int SupX = ((Y==1) ? 1 : Y/2),
480 bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
481 // use ?: instead of || just to shut up a stupid gcc 4.3 warning
482class meta_sqrt
483{
484 enum {
485 MidX = (InfX+SupX)/2,
486 TakeInf = MidX*MidX > Y ? 1 : 0,
487 NewInf = int(TakeInf) ? InfX : int(MidX),
488 NewSup = int(TakeInf) ? int(MidX) : SupX
489 };
490 public:
491 enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
492};
493
494template<int Y, int InfX, int SupX>
495class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
496
497
502template<int A, int B, int K=1, bool Done = ((A*K)%B)==0>
503struct meta_least_common_multiple
504{
505 enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
506};
507template<int A, int B, int K>
508struct meta_least_common_multiple<A,B,K,true>
509{
510 enum { ret = A*K };
511};
512
514template<typename T, typename U> struct scalar_product_traits
515{
516 enum { Defined = 0 };
517};
518
519// FIXME quick workaround around current limitation of result_of
520// template<typename Scalar, typename ArgType0, typename ArgType1>
521// struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
522// typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
523// };
524
525} // end namespace internal
526
527namespace numext {
528
529#if defined(__CUDA_ARCH__)
530template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
531#else
532template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
533#endif
534
535#if defined(__CUDA_ARCH__)
536using internal::device::numeric_limits;
537#else
538using std::numeric_limits;
539#endif
540
541// Integer division with rounding up.
542// T is assumed to be an integer type with a>=0, and b>0
543template<typename T>
544EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T div_ceil(const T &a, const T &b)
545{
546 return (a+b-1) / b;
547}
548
549// The aim of the following functions is to bypass -Wfloat-equal warnings
550// when we really want a strict equality comparison on floating points.
551template<typename X, typename Y> EIGEN_STRONG_INLINE
552bool equal_strict(const X& x,const Y& y) { return x == y; }
553
554template<> EIGEN_STRONG_INLINE
555bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
556
557template<> EIGEN_STRONG_INLINE
558bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
559
560template<typename X, typename Y> EIGEN_STRONG_INLINE
561bool not_equal_strict(const X& x,const Y& y) { return x != y; }
562
563template<> EIGEN_STRONG_INLINE
564bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
565
566template<> EIGEN_STRONG_INLINE
567bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
568
569} // end namespace numext
570
571} // end namespace Eigen
572
573#endif // EIGEN_META_H
Namespace containing all symbols from the Eigen library.
Definition A05_PortingFrom2To3.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:65