![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_META_H 00012 #define EIGEN_META_H 00013 00014 #if defined(__CUDA_ARCH__) 00015 #include <cfloat> 00016 #include <math_constants.h> 00017 #endif 00018 00019 #if EIGEN_COMP_ICC>=1600 && __cplusplus >= 201103L 00020 #include <cstdint> 00021 #endif 00022 00023 namespace Eigen { 00024 00025 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex; 00026 00033 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index; 00034 00035 namespace internal { 00036 00044 // Only recent versions of ICC complain about using ptrdiff_t to hold pointers, 00045 // and older versions do not provide *intptr_t types. 00046 #if EIGEN_COMP_ICC>=1600 && __cplusplus >= 201103L 00047 typedef std::intptr_t IntPtr; 00048 typedef std::uintptr_t UIntPtr; 00049 #else 00050 typedef std::ptrdiff_t IntPtr; 00051 typedef std::size_t UIntPtr; 00052 #endif 00053 00054 struct true_type { enum { value = 1 }; }; 00055 struct false_type { enum { value = 0 }; }; 00056 00057 template<bool Condition, typename Then, typename Else> 00058 struct conditional { typedef Then type; }; 00059 00060 template<typename Then, typename Else> 00061 struct conditional <false, Then, Else> { typedef Else type; }; 00062 00063 template<typename T, typename U> struct is_same { enum { value = 0 }; }; 00064 template<typename T> struct is_same<T,T> { enum { value = 1 }; }; 00065 00066 template<typename T> struct remove_reference { typedef T type; }; 00067 template<typename T> struct remove_reference<T&> { typedef T type; }; 00068 00069 template<typename T> struct remove_pointer { typedef T type; }; 00070 template<typename T> struct remove_pointer<T*> { typedef T type; }; 00071 template<typename T> struct remove_pointer<T*const> { typedef T type; }; 00072 00073 template <class T> struct remove_const { typedef T type; }; 00074 template <class T> struct remove_const<const T> { typedef T type; }; 00075 template <class T> struct remove_const<const T[]> { typedef T type[]; }; 00076 template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; }; 00077 00078 template<typename T> struct remove_all { typedef T type; }; 00079 template<typename T> struct remove_all<const T> { typedef typename remove_all<T>::type type; }; 00080 template<typename T> struct remove_all<T const&> { typedef typename remove_all<T>::type type; }; 00081 template<typename T> struct remove_all<T&> { typedef typename remove_all<T>::type type; }; 00082 template<typename T> struct remove_all<T const*> { typedef typename remove_all<T>::type type; }; 00083 template<typename T> struct remove_all<T*> { typedef typename remove_all<T>::type type; }; 00084 00085 template<typename T> struct is_arithmetic { enum { value = false }; }; 00086 template<> struct is_arithmetic<float> { enum { value = true }; }; 00087 template<> struct is_arithmetic<double> { enum { value = true }; }; 00088 template<> struct is_arithmetic<long double> { enum { value = true }; }; 00089 template<> struct is_arithmetic<bool> { enum { value = true }; }; 00090 template<> struct is_arithmetic<char> { enum { value = true }; }; 00091 template<> struct is_arithmetic<signed char> { enum { value = true }; }; 00092 template<> struct is_arithmetic<unsigned char> { enum { value = true }; }; 00093 template<> struct is_arithmetic<signed short> { enum { value = true }; }; 00094 template<> struct is_arithmetic<unsigned short>{ enum { value = true }; }; 00095 template<> struct is_arithmetic<signed int> { enum { value = true }; }; 00096 template<> struct is_arithmetic<unsigned int> { enum { value = true }; }; 00097 template<> struct is_arithmetic<signed long> { enum { value = true }; }; 00098 template<> struct is_arithmetic<unsigned long> { enum { value = true }; }; 00099 00100 template<typename T> struct is_integral { enum { value = false }; }; 00101 template<> struct is_integral<bool> { enum { value = true }; }; 00102 template<> struct is_integral<char> { enum { value = true }; }; 00103 template<> struct is_integral<signed char> { enum { value = true }; }; 00104 template<> struct is_integral<unsigned char> { enum { value = true }; }; 00105 template<> struct is_integral<signed short> { enum { value = true }; }; 00106 template<> struct is_integral<unsigned short> { enum { value = true }; }; 00107 template<> struct is_integral<signed int> { enum { value = true }; }; 00108 template<> struct is_integral<unsigned int> { enum { value = true }; }; 00109 template<> struct is_integral<signed long> { enum { value = true }; }; 00110 template<> struct is_integral<unsigned long> { enum { value = true }; }; 00111 00112 template <typename T> struct add_const { typedef const T type; }; 00113 template <typename T> struct add_const<T&> { typedef T& type; }; 00114 00115 template <typename T> struct is_const { enum { value = 0 }; }; 00116 template <typename T> struct is_const<T const> { enum { value = 1 }; }; 00117 00118 template<typename T> struct add_const_on_value_type { typedef const T type; }; 00119 template<typename T> struct add_const_on_value_type<T&> { typedef T const& type; }; 00120 template<typename T> struct add_const_on_value_type<T*> { typedef T const* type; }; 00121 template<typename T> struct add_const_on_value_type<T* const> { typedef T const* const type; }; 00122 template<typename T> struct add_const_on_value_type<T const* const> { typedef T const* const type; }; 00123 00124 00125 template<typename From, typename To> 00126 struct is_convertible_impl 00127 { 00128 private: 00129 struct any_conversion 00130 { 00131 template <typename T> any_conversion(const volatile T&); 00132 template <typename T> any_conversion(T&); 00133 }; 00134 struct yes {int a[1];}; 00135 struct no {int a[2];}; 00136 00137 static yes test(const To&, int); 00138 static no test(any_conversion, ...); 00139 00140 public: 00141 static From ms_from; 00142 #ifdef __INTEL_COMPILER 00143 #pragma warning push 00144 #pragma warning ( disable : 2259 ) 00145 #endif 00146 enum { value = sizeof(test(ms_from, 0))==sizeof(yes) }; 00147 #ifdef __INTEL_COMPILER 00148 #pragma warning pop 00149 #endif 00150 }; 00151 00152 template<typename From, typename To> 00153 struct is_convertible 00154 { 00155 enum { value = is_convertible_impl<typename remove_all<From>::type, 00156 typename remove_all<To >::type>::value }; 00157 }; 00158 00162 template<bool Condition, typename T=void> struct enable_if; 00163 00164 template<typename T> struct enable_if<true,T> 00165 { typedef T type; }; 00166 00167 #if defined(__CUDA_ARCH__) 00168 #if !defined(__FLT_EPSILON__) 00169 #define __FLT_EPSILON__ FLT_EPSILON 00170 #define __DBL_EPSILON__ DBL_EPSILON 00171 #endif 00172 00173 namespace device { 00174 00175 template<typename T> struct numeric_limits 00176 { 00177 EIGEN_DEVICE_FUNC 00178 static T epsilon() { return 0; } 00179 static T (max)() { assert(false && "Highest not supported for this type"); } 00180 static T (min)() { assert(false && "Lowest not supported for this type"); } 00181 static T infinity() { assert(false && "Infinity not supported for this type"); } 00182 static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); } 00183 }; 00184 template<> struct numeric_limits<float> 00185 { 00186 EIGEN_DEVICE_FUNC 00187 static float epsilon() { return __FLT_EPSILON__; } 00188 EIGEN_DEVICE_FUNC 00189 static float (max)() { return CUDART_MAX_NORMAL_F; } 00190 EIGEN_DEVICE_FUNC 00191 static float (min)() { return FLT_MIN; } 00192 EIGEN_DEVICE_FUNC 00193 static float infinity() { return CUDART_INF_F; } 00194 EIGEN_DEVICE_FUNC 00195 static float quiet_NaN() { return CUDART_NAN_F; } 00196 }; 00197 template<> struct numeric_limits<double> 00198 { 00199 EIGEN_DEVICE_FUNC 00200 static double epsilon() { return __DBL_EPSILON__; } 00201 EIGEN_DEVICE_FUNC 00202 static double (max)() { return DBL_MAX; } 00203 EIGEN_DEVICE_FUNC 00204 static double (min)() { return DBL_MIN; } 00205 EIGEN_DEVICE_FUNC 00206 static double infinity() { return CUDART_INF; } 00207 EIGEN_DEVICE_FUNC 00208 static double quiet_NaN() { return CUDART_NAN; } 00209 }; 00210 template<> struct numeric_limits<int> 00211 { 00212 EIGEN_DEVICE_FUNC 00213 static int epsilon() { return 0; } 00214 EIGEN_DEVICE_FUNC 00215 static int (max)() { return INT_MAX; } 00216 EIGEN_DEVICE_FUNC 00217 static int (min)() { return INT_MIN; } 00218 }; 00219 template<> struct numeric_limits<unsigned int> 00220 { 00221 EIGEN_DEVICE_FUNC 00222 static unsigned int epsilon() { return 0; } 00223 EIGEN_DEVICE_FUNC 00224 static unsigned int (max)() { return UINT_MAX; } 00225 EIGEN_DEVICE_FUNC 00226 static unsigned int (min)() { return 0; } 00227 }; 00228 template<> struct numeric_limits<long> 00229 { 00230 EIGEN_DEVICE_FUNC 00231 static long epsilon() { return 0; } 00232 EIGEN_DEVICE_FUNC 00233 static long (max)() { return LONG_MAX; } 00234 EIGEN_DEVICE_FUNC 00235 static long (min)() { return LONG_MIN; } 00236 }; 00237 template<> struct numeric_limits<unsigned long> 00238 { 00239 EIGEN_DEVICE_FUNC 00240 static unsigned long epsilon() { return 0; } 00241 EIGEN_DEVICE_FUNC 00242 static unsigned long (max)() { return ULONG_MAX; } 00243 EIGEN_DEVICE_FUNC 00244 static unsigned long (min)() { return 0; } 00245 }; 00246 template<> struct numeric_limits<long long> 00247 { 00248 EIGEN_DEVICE_FUNC 00249 static long long epsilon() { return 0; } 00250 EIGEN_DEVICE_FUNC 00251 static long long (max)() { return LLONG_MAX; } 00252 EIGEN_DEVICE_FUNC 00253 static long long (min)() { return LLONG_MIN; } 00254 }; 00255 template<> struct numeric_limits<unsigned long long> 00256 { 00257 EIGEN_DEVICE_FUNC 00258 static unsigned long long epsilon() { return 0; } 00259 EIGEN_DEVICE_FUNC 00260 static unsigned long long (max)() { return ULLONG_MAX; } 00261 EIGEN_DEVICE_FUNC 00262 static unsigned long long (min)() { return 0; } 00263 }; 00264 00265 } 00266 00267 #endif 00268 00272 class noncopyable 00273 { 00274 EIGEN_DEVICE_FUNC noncopyable(const noncopyable&); 00275 EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&); 00276 protected: 00277 EIGEN_DEVICE_FUNC noncopyable() {} 00278 EIGEN_DEVICE_FUNC ~noncopyable() {} 00279 }; 00280 00288 #if EIGEN_HAS_STD_RESULT_OF 00289 template<typename T> struct result_of { 00290 typedef typename std::result_of<T>::type type1; 00291 typedef typename remove_all<type1>::type type; 00292 }; 00293 #else 00294 template<typename T> struct result_of { }; 00295 00296 struct has_none {int a[1];}; 00297 struct has_std_result_type {int a[2];}; 00298 struct has_tr1_result {int a[3];}; 00299 00300 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)> 00301 struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;}; 00302 00303 template<typename Func, typename ArgType> 00304 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;}; 00305 00306 template<typename Func, typename ArgType> 00307 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;}; 00308 00309 template<typename Func, typename ArgType> 00310 struct result_of<Func(ArgType)> { 00311 template<typename T> 00312 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 00313 template<typename T> 00314 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0); 00315 static has_none testFunctor(...); 00316 00317 // note that the following indirection is needed for gcc-3.3 00318 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 00319 typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type; 00320 }; 00321 00322 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)> 00323 struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;}; 00324 00325 template<typename Func, typename ArgType0, typename ArgType1> 00326 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)> 00327 {typedef typename Func::result_type type;}; 00328 00329 template<typename Func, typename ArgType0, typename ArgType1> 00330 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)> 00331 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;}; 00332 00333 template<typename Func, typename ArgType0, typename ArgType1> 00334 struct result_of<Func(ArgType0,ArgType1)> { 00335 template<typename T> 00336 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 00337 template<typename T> 00338 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0); 00339 static has_none testFunctor(...); 00340 00341 // note that the following indirection is needed for gcc-3.3 00342 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 00343 typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type; 00344 }; 00345 00346 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)> 00347 struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;}; 00348 00349 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2> 00350 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)> 00351 {typedef typename Func::result_type type;}; 00352 00353 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2> 00354 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)> 00355 {typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;}; 00356 00357 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2> 00358 struct result_of<Func(ArgType0,ArgType1,ArgType2)> { 00359 template<typename T> 00360 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 00361 template<typename T> 00362 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0); 00363 static has_none testFunctor(...); 00364 00365 // note that the following indirection is needed for gcc-3.3 00366 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 00367 typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type; 00368 }; 00369 #endif 00370 00371 struct meta_yes { char a[1]; }; 00372 struct meta_no { char a[2]; }; 00373 00374 // Check whether T::ReturnType does exist 00375 template <typename T> 00376 struct has_ReturnType 00377 { 00378 template <typename C> static meta_yes testFunctor(typename C::ReturnType const *); 00379 template <typename C> static meta_no testFunctor(...); 00380 00381 enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) }; 00382 }; 00383 00384 template<typename T> const T* return_ptr(); 00385 00386 template <typename T, typename IndexType=Index> 00387 struct has_nullary_operator 00388 { 00389 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0); 00390 static meta_no testFunctor(...); 00391 00392 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) }; 00393 }; 00394 00395 template <typename T, typename IndexType=Index> 00396 struct has_unary_operator 00397 { 00398 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0); 00399 static meta_no testFunctor(...); 00400 00401 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) }; 00402 }; 00403 00404 template <typename T, typename IndexType=Index> 00405 struct has_binary_operator 00406 { 00407 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0); 00408 static meta_no testFunctor(...); 00409 00410 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) }; 00411 }; 00412 00416 template<int Y, 00417 int InfX = 0, 00418 int SupX = ((Y==1) ? 1 : Y/2), 00419 bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) > 00420 // use ?: instead of || just to shut up a stupid gcc 4.3 warning 00421 class meta_sqrt 00422 { 00423 enum { 00424 MidX = (InfX+SupX)/2, 00425 TakeInf = MidX*MidX > Y ? 1 : 0, 00426 NewInf = int(TakeInf) ? InfX : int(MidX), 00427 NewSup = int(TakeInf) ? int(MidX) : SupX 00428 }; 00429 public: 00430 enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret }; 00431 }; 00432 00433 template<int Y, int InfX, int SupX> 00434 class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; 00435 00436 00441 template<int A, int B, int K=1, bool Done = ((A*K)%B)==0> 00442 struct meta_least_common_multiple 00443 { 00444 enum { ret = meta_least_common_multiple<A,B,K+1>::ret }; 00445 }; 00446 template<int A, int B, int K> 00447 struct meta_least_common_multiple<A,B,K,true> 00448 { 00449 enum { ret = A*K }; 00450 }; 00451 00453 template<typename T, typename U> struct scalar_product_traits 00454 { 00455 enum { Defined = 0 }; 00456 }; 00457 00458 // FIXME quick workaround around current limitation of result_of 00459 // template<typename Scalar, typename ArgType0, typename ArgType1> 00460 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> { 00461 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type; 00462 // }; 00463 00464 } // end namespace internal 00465 00466 namespace numext { 00467 00468 #if defined(__CUDA_ARCH__) 00469 template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; } 00470 #else 00471 template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); } 00472 #endif 00473 00474 #if defined(__CUDA_ARCH__) 00475 using internal::device::numeric_limits; 00476 #else 00477 using std::numeric_limits; 00478 #endif 00479 00480 // Integer division with rounding up. 00481 // T is assumed to be an integer type with a>=0, and b>0 00482 template<typename T> 00483 T div_ceil(const T &a, const T &b) 00484 { 00485 return (a+b-1) / b; 00486 } 00487 00488 } // end namespace numext 00489 00490 } // end namespace Eigen 00491 00492 #endif // EIGEN_META_H