MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2015 Gael Guennebaud <[email protected]> 00005 // Copyright (C) 2006-2008 Benoit Jacob <[email protected]> 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 namespace Eigen { 00020 00021 namespace internal { 00022 00030 struct true_type { enum { value = 1 }; }; 00031 struct false_type { enum { value = 0 }; }; 00032 00033 template<bool Condition, typename Then, typename Else> 00034 struct conditional { typedef Then type; }; 00035 00036 template<typename Then, typename Else> 00037 struct conditional <false, Then, Else> { typedef Else type; }; 00038 00039 template<typename T, typename U> struct is_same { enum { value = 0 }; }; 00040 template<typename T> struct is_same<T,T> { enum { value = 1 }; }; 00041 00042 template<typename T> struct remove_reference { typedef T type; }; 00043 template<typename T> struct remove_reference<T&> { typedef T type; }; 00044 00045 template<typename T> struct remove_pointer { typedef T type; }; 00046 template<typename T> struct remove_pointer<T*> { typedef T type; }; 00047 template<typename T> struct remove_pointer<T*const> { typedef T type; }; 00048 00049 template <class T> struct remove_const { typedef T type; }; 00050 template <class T> struct remove_const<const T> { typedef T type; }; 00051 template <class T> struct remove_const<const T[]> { typedef T type[]; }; 00052 template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; }; 00053 00054 template<typename T> struct remove_all { typedef T type; }; 00055 template<typename T> struct remove_all<const T> { typedef typename remove_all<T>::type type; }; 00056 template<typename T> struct remove_all<T const&> { typedef typename remove_all<T>::type type; }; 00057 template<typename T> struct remove_all<T&> { typedef typename remove_all<T>::type type; }; 00058 template<typename T> struct remove_all<T const*> { typedef typename remove_all<T>::type type; }; 00059 template<typename T> struct remove_all<T*> { typedef typename remove_all<T>::type type; }; 00060 00061 template<typename T> struct is_arithmetic { enum { value = false }; }; 00062 template<> struct is_arithmetic<float> { enum { value = true }; }; 00063 template<> struct is_arithmetic<double> { enum { value = true }; }; 00064 template<> struct is_arithmetic<long double> { enum { value = true }; }; 00065 template<> struct is_arithmetic<bool> { enum { value = true }; }; 00066 template<> struct is_arithmetic<char> { enum { value = true }; }; 00067 template<> struct is_arithmetic<signed char> { enum { value = true }; }; 00068 template<> struct is_arithmetic<unsigned char> { enum { value = true }; }; 00069 template<> struct is_arithmetic<signed short> { enum { value = true }; }; 00070 template<> struct is_arithmetic<unsigned short>{ enum { value = true }; }; 00071 template<> struct is_arithmetic<signed int> { enum { value = true }; }; 00072 template<> struct is_arithmetic<unsigned int> { enum { value = true }; }; 00073 template<> struct is_arithmetic<signed long> { enum { value = true }; }; 00074 template<> struct is_arithmetic<unsigned long> { enum { value = true }; }; 00075 00076 template<typename T> struct is_integral { enum { value = false }; }; 00077 template<> struct is_integral<bool> { enum { value = true }; }; 00078 template<> struct is_integral<char> { enum { value = true }; }; 00079 template<> struct is_integral<signed char> { enum { value = true }; }; 00080 template<> struct is_integral<unsigned char> { enum { value = true }; }; 00081 template<> struct is_integral<signed short> { enum { value = true }; }; 00082 template<> struct is_integral<unsigned short> { enum { value = true }; }; 00083 template<> struct is_integral<signed int> { enum { value = true }; }; 00084 template<> struct is_integral<unsigned int> { enum { value = true }; }; 00085 template<> struct is_integral<signed long> { enum { value = true }; }; 00086 template<> struct is_integral<unsigned long> { enum { value = true }; }; 00087 00088 template <typename T> struct add_const { typedef const T type; }; 00089 template <typename T> struct add_const<T&> { typedef T& type; }; 00090 00091 template <typename T> struct is_const { enum { value = 0 }; }; 00092 template <typename T> struct is_const<T const> { enum { value = 1 }; }; 00093 00094 template<typename T> struct add_const_on_value_type { typedef const T type; }; 00095 template<typename T> struct add_const_on_value_type<T&> { typedef T const& type; }; 00096 template<typename T> struct add_const_on_value_type<T*> { typedef T const* type; }; 00097 template<typename T> struct add_const_on_value_type<T* const> { typedef T const* const type; }; 00098 template<typename T> struct add_const_on_value_type<T const* const> { typedef T const* const type; }; 00099 00100 00101 template<typename From, typename To> 00102 struct is_convertible_impl 00103 { 00104 private: 00105 struct any_conversion 00106 { 00107 template <typename T> any_conversion(const volatile T&); 00108 template <typename T> any_conversion(T&); 00109 }; 00110 struct yes {int a[1];}; 00111 struct no {int a[2];}; 00112 00113 static yes test(const To&, int); 00114 static no test(any_conversion, ...); 00115 00116 public: 00117 static From ms_from; 00118 enum { value = sizeof(test(ms_from, 0))==sizeof(yes) }; 00119 }; 00120 00121 template<typename From, typename To> 00122 struct is_convertible 00123 { 00124 enum { value = is_convertible_impl<typename remove_all<From>::type, 00125 typename remove_all<To >::type>::value }; 00126 }; 00127 00131 template<bool Condition, typename T> struct enable_if; 00132 00133 template<typename T> struct enable_if<true,T> 00134 { typedef T type; }; 00135 00136 #if defined(__CUDA_ARCH__) 00137 #if !defined(__FLT_EPSILON__) 00138 #define __FLT_EPSILON__ FLT_EPSILON 00139 #define __DBL_EPSILON__ DBL_EPSILON 00140 #endif 00141 00142 namespace device { 00143 00144 template<typename T> struct numeric_limits 00145 { 00146 EIGEN_DEVICE_FUNC 00147 static T epsilon() { return 0; } 00148 static T (max)() { assert(false && "Highest not supported for this type"); } 00149 static T (min)() { assert(false && "Lowest not supported for this type"); } 00150 static T infinity() { assert(false && "Infinity not supported for this type"); } 00151 }; 00152 template<> struct numeric_limits<float> 00153 { 00154 EIGEN_DEVICE_FUNC 00155 static float epsilon() { return __FLT_EPSILON__; } 00156 EIGEN_DEVICE_FUNC 00157 static float (max)() { return CUDART_MAX_NORMAL_F; } 00158 EIGEN_DEVICE_FUNC 00159 static float (min)() { return FLT_MIN; } 00160 EIGEN_DEVICE_FUNC 00161 static float infinity() { return CUDART_INF_F; } 00162 }; 00163 template<> struct numeric_limits<double> 00164 { 00165 EIGEN_DEVICE_FUNC 00166 static double epsilon() { return __DBL_EPSILON__; } 00167 EIGEN_DEVICE_FUNC 00168 static double (max)() { return DBL_MAX; } 00169 EIGEN_DEVICE_FUNC 00170 static double (min)() { return DBL_MIN; } 00171 EIGEN_DEVICE_FUNC 00172 static double infinity() { return CUDART_INF; } 00173 }; 00174 template<> struct numeric_limits<int> 00175 { 00176 EIGEN_DEVICE_FUNC 00177 static int epsilon() { return 0; } 00178 EIGEN_DEVICE_FUNC 00179 static int (max)() { return INT_MAX; } 00180 EIGEN_DEVICE_FUNC 00181 static int (min)() { return INT_MIN; } 00182 }; 00183 template<> struct numeric_limits<unsigned int> 00184 { 00185 EIGEN_DEVICE_FUNC 00186 static unsigned int epsilon() { return 0; } 00187 EIGEN_DEVICE_FUNC 00188 static unsigned int (max)() { return UINT_MAX; } 00189 EIGEN_DEVICE_FUNC 00190 static unsigned int (min)() { return 0; } 00191 }; 00192 template<> struct numeric_limits<long> 00193 { 00194 EIGEN_DEVICE_FUNC 00195 static long epsilon() { return 0; } 00196 EIGEN_DEVICE_FUNC 00197 static long (max)() { return LONG_MAX; } 00198 EIGEN_DEVICE_FUNC 00199 static long (min)() { return LONG_MIN; } 00200 }; 00201 template<> struct numeric_limits<unsigned long> 00202 { 00203 EIGEN_DEVICE_FUNC 00204 static unsigned long epsilon() { return 0; } 00205 EIGEN_DEVICE_FUNC 00206 static unsigned long (max)() { return ULONG_MAX; } 00207 EIGEN_DEVICE_FUNC 00208 static unsigned long (min)() { return 0; } 00209 }; 00210 template<> struct numeric_limits<long long> 00211 { 00212 EIGEN_DEVICE_FUNC 00213 static long long epsilon() { return 0; } 00214 EIGEN_DEVICE_FUNC 00215 static long long (max)() { return LLONG_MAX; } 00216 EIGEN_DEVICE_FUNC 00217 static long long (min)() { return LLONG_MIN; } 00218 }; 00219 template<> struct numeric_limits<unsigned long long> 00220 { 00221 EIGEN_DEVICE_FUNC 00222 static unsigned long long epsilon() { return 0; } 00223 EIGEN_DEVICE_FUNC 00224 static unsigned long long (max)() { return ULLONG_MAX; } 00225 EIGEN_DEVICE_FUNC 00226 static unsigned long long (min)() { return 0; } 00227 }; 00228 00229 } 00230 00231 #endif 00232 00236 class noncopyable 00237 { 00238 EIGEN_DEVICE_FUNC noncopyable(const noncopyable&); 00239 EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&); 00240 protected: 00241 EIGEN_DEVICE_FUNC noncopyable() {} 00242 EIGEN_DEVICE_FUNC ~noncopyable() {} 00243 }; 00244 00252 #ifdef EIGEN_HAS_STD_RESULT_OF 00253 template<typename T> struct result_of { 00254 typedef typename std::result_of<T>::type type1; 00255 typedef typename remove_all<type1>::type type; 00256 }; 00257 #else 00258 template<typename T> struct result_of { }; 00259 00260 struct has_none {int a[1];}; 00261 struct has_std_result_type {int a[2];}; 00262 struct has_tr1_result {int a[3];}; 00263 00264 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)> 00265 struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;}; 00266 00267 template<typename Func, typename ArgType> 00268 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;}; 00269 00270 template<typename Func, typename ArgType> 00271 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;}; 00272 00273 template<typename Func, typename ArgType> 00274 struct result_of<Func(ArgType)> { 00275 template<typename T> 00276 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 00277 template<typename T> 00278 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0); 00279 static has_none testFunctor(...); 00280 00281 // note that the following indirection is needed for gcc-3.3 00282 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 00283 typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type; 00284 }; 00285 00286 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)> 00287 struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;}; 00288 00289 template<typename Func, typename ArgType0, typename ArgType1> 00290 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)> 00291 {typedef typename Func::result_type type;}; 00292 00293 template<typename Func, typename ArgType0, typename ArgType1> 00294 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)> 00295 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;}; 00296 00297 template<typename Func, typename ArgType0, typename ArgType1> 00298 struct result_of<Func(ArgType0,ArgType1)> { 00299 template<typename T> 00300 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 00301 template<typename T> 00302 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0); 00303 static has_none testFunctor(...); 00304 00305 // note that the following indirection is needed for gcc-3.3 00306 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 00307 typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type; 00308 }; 00309 #endif 00310 00314 template<int Y, 00315 int InfX = 0, 00316 int SupX = ((Y==1) ? 1 : Y/2), 00317 bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) > 00318 // use ?: instead of || just to shut up a stupid gcc 4.3 warning 00319 class meta_sqrt 00320 { 00321 enum { 00322 MidX = (InfX+SupX)/2, 00323 TakeInf = MidX*MidX > Y ? 1 : 0, 00324 NewInf = int(TakeInf) ? InfX : int(MidX), 00325 NewSup = int(TakeInf) ? int(MidX) : SupX 00326 }; 00327 public: 00328 enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret }; 00329 }; 00330 00331 template<int Y, int InfX, int SupX> 00332 class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; 00333 00334 00339 template<int A, int B, int K=1, bool Done = ((A*K)%B)==0> 00340 struct meta_least_common_multiple 00341 { 00342 enum { ret = meta_least_common_multiple<A,B,K+1>::ret }; 00343 }; 00344 template<int A, int B, int K> 00345 struct meta_least_common_multiple<A,B,K,true> 00346 { 00347 enum { ret = A*K }; 00348 }; 00349 00351 template<typename T, typename U> struct scalar_product_traits 00352 { 00353 enum { Defined = 0 }; 00354 }; 00355 00356 template<typename T> struct scalar_product_traits<T,T> 00357 { 00358 enum { 00359 // Cost = NumTraits<T>::MulCost, 00360 Defined = 1 00361 }; 00362 typedef T ReturnType; 00363 }; 00364 00365 template<typename T> struct scalar_product_traits<T,std::complex<T> > 00366 { 00367 enum { 00368 // Cost = 2*NumTraits<T>::MulCost, 00369 Defined = 1 00370 }; 00371 typedef std::complex<T> ReturnType; 00372 }; 00373 00374 template<typename T> struct scalar_product_traits<std::complex<T>, T> 00375 { 00376 enum { 00377 // Cost = 2*NumTraits<T>::MulCost, 00378 Defined = 1 00379 }; 00380 typedef std::complex<T> ReturnType; 00381 }; 00382 00383 // FIXME quick workaround around current limitation of result_of 00384 // template<typename Scalar, typename ArgType0, typename ArgType1> 00385 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> { 00386 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type; 00387 // }; 00388 00389 } // end namespace internal 00390 00391 namespace numext { 00392 00393 #if defined(__CUDA_ARCH__) 00394 template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; } 00395 #else 00396 template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); } 00397 #endif 00398 00399 #if defined(__CUDA_ARCH__) 00400 using internal::device::numeric_limits; 00401 #else 00402 using std::numeric_limits; 00403 #endif 00404 00405 // Integer division with rounding up. 00406 // T is assumed to be an integer type with a>=0, and b>0 00407 template<typename T> 00408 T div_ceil(const T &a, const T &b) 00409 { 00410 return (a+b-1) / b; 00411 } 00412 00413 } // end namespace numext 00414 00415 } // end namespace Eigen 00416 00417 #endif // EIGEN_META_H