Eigen  3.3.3
Meta.h
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
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends