MOAB  4.9.3pre
Meta.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines