Home | History | Annotate | Download | only in util
      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 (at) inria.fr>
      5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1 (at) 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 #if EIGEN_COMP_ICC>=1600 &&  __cplusplus >= 201103L
     20 #include <cstdint>
     21 #endif
     22 
     23 namespace Eigen {
     24 
     25 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
     26 
     27 /**
     28  * \brief The Index type as used for the API.
     29  * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
     30  * \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
     31  */
     32 
     33 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
     34 
     35 namespace internal {
     36 
     37 /** \internal
     38   * \file Meta.h
     39   * This file contains generic metaprogramming classes which are not specifically related to Eigen.
     40   * \note In case you wonder, yes we're aware that Boost already provides all these features,
     41   * we however don't want to add a dependency to Boost.
     42   */
     43 
     44 // Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
     45 // and older versions do not provide *intptr_t types.
     46 #if EIGEN_COMP_ICC>=1600 &&  __cplusplus >= 201103L
     47 typedef std::intptr_t  IntPtr;
     48 typedef std::uintptr_t UIntPtr;
     49 #else
     50 typedef std::ptrdiff_t IntPtr;
     51 typedef std::size_t UIntPtr;
     52 #endif
     53 
     54 struct true_type {  enum { value = 1 }; };
     55 struct false_type { enum { value = 0 }; };
     56 
     57 template<bool Condition, typename Then, typename Else>
     58 struct conditional { typedef Then type; };
     59 
     60 template<typename Then, typename Else>
     61 struct conditional <false, Then, Else> { typedef Else type; };
     62 
     63 template<typename T, typename U> struct is_same { enum { value = 0 }; };
     64 template<typename T> struct is_same<T,T> { enum { value = 1 }; };
     65 
     66 template<typename T> struct remove_reference { typedef T type; };
     67 template<typename T> struct remove_reference<T&> { typedef T type; };
     68 
     69 template<typename T> struct remove_pointer { typedef T type; };
     70 template<typename T> struct remove_pointer<T*> { typedef T type; };
     71 template<typename T> struct remove_pointer<T*const> { typedef T type; };
     72 
     73 template <class T> struct remove_const { typedef T type; };
     74 template <class T> struct remove_const<const T> { typedef T type; };
     75 template <class T> struct remove_const<const T[]> { typedef T type[]; };
     76 template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
     77 
     78 template<typename T> struct remove_all { typedef T type; };
     79 template<typename T> struct remove_all<const T>   { typedef typename remove_all<T>::type type; };
     80 template<typename T> struct remove_all<T const&>  { typedef typename remove_all<T>::type type; };
     81 template<typename T> struct remove_all<T&>        { typedef typename remove_all<T>::type type; };
     82 template<typename T> struct remove_all<T const*>  { typedef typename remove_all<T>::type type; };
     83 template<typename T> struct remove_all<T*>        { typedef typename remove_all<T>::type type; };
     84 
     85 template<typename T> struct is_arithmetic      { enum { value = false }; };
     86 template<> struct is_arithmetic<float>         { enum { value = true }; };
     87 template<> struct is_arithmetic<double>        { enum { value = true }; };
     88 template<> struct is_arithmetic<long double>   { enum { value = true }; };
     89 template<> struct is_arithmetic<bool>          { enum { value = true }; };
     90 template<> struct is_arithmetic<char>          { enum { value = true }; };
     91 template<> struct is_arithmetic<signed char>   { enum { value = true }; };
     92 template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
     93 template<> struct is_arithmetic<signed short>  { enum { value = true }; };
     94 template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
     95 template<> struct is_arithmetic<signed int>    { enum { value = true }; };
     96 template<> struct is_arithmetic<unsigned int>  { enum { value = true }; };
     97 template<> struct is_arithmetic<signed long>   { enum { value = true }; };
     98 template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
     99 
    100 template<typename T> struct is_integral        { enum { value = false }; };
    101 template<> struct is_integral<bool>            { enum { value = true }; };
    102 template<> struct is_integral<char>            { enum { value = true }; };
    103 template<> struct is_integral<signed char>     { enum { value = true }; };
    104 template<> struct is_integral<unsigned char>   { enum { value = true }; };
    105 template<> struct is_integral<signed short>    { enum { value = true }; };
    106 template<> struct is_integral<unsigned short>  { enum { value = true }; };
    107 template<> struct is_integral<signed int>      { enum { value = true }; };
    108 template<> struct is_integral<unsigned int>    { enum { value = true }; };
    109 template<> struct is_integral<signed long>     { enum { value = true }; };
    110 template<> struct is_integral<unsigned long>   { enum { value = true }; };
    111 
    112 template <typename T> struct add_const { typedef const T type; };
    113 template <typename T> struct add_const<T&> { typedef T& type; };
    114 
    115 template <typename T> struct is_const { enum { value = 0 }; };
    116 template <typename T> struct is_const<T const> { enum { value = 1 }; };
    117 
    118 template<typename T> struct add_const_on_value_type            { typedef const T type;  };
    119 template<typename T> struct add_const_on_value_type<T&>        { typedef T const& type; };
    120 template<typename T> struct add_const_on_value_type<T*>        { typedef T const* type; };
    121 template<typename T> struct add_const_on_value_type<T* const>  { typedef T const* const type; };
    122 template<typename T> struct add_const_on_value_type<T const* const>  { typedef T const* const type; };
    123 
    124 
    125 template<typename From, typename To>
    126 struct is_convertible_impl
    127 {
    128 private:
    129   struct any_conversion
    130   {
    131     template <typename T> any_conversion(const volatile T&);
    132     template <typename T> any_conversion(T&);
    133   };
    134   struct yes {int a[1];};
    135   struct no  {int a[2];};
    136 
    137   static yes test(const To&, int);
    138   static no  test(any_conversion, ...);
    139 
    140 public:
    141   static From ms_from;
    142 #ifdef __INTEL_COMPILER
    143   #pragma warning push
    144   #pragma warning ( disable : 2259 )
    145 #endif
    146   enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
    147 #ifdef __INTEL_COMPILER
    148   #pragma warning pop
    149 #endif
    150 };
    151 
    152 template<typename From, typename To>
    153 struct is_convertible
    154 {
    155   enum { value = is_convertible_impl<typename remove_all<From>::type,
    156                                      typename remove_all<To  >::type>::value };
    157 };
    158 
    159 /** \internal Allows to enable/disable an overload
    160   * according to a compile time condition.
    161   */
    162 template<bool Condition, typename T=void> struct enable_if;
    163 
    164 template<typename T> struct enable_if<true,T>
    165 { typedef T type; };
    166 
    167 #if defined(__CUDA_ARCH__)
    168 #if !defined(__FLT_EPSILON__)
    169 #define __FLT_EPSILON__ FLT_EPSILON
    170 #define __DBL_EPSILON__ DBL_EPSILON
    171 #endif
    172 
    173 namespace device {
    174 
    175 template<typename T> struct numeric_limits
    176 {
    177   EIGEN_DEVICE_FUNC
    178   static T epsilon() { return 0; }
    179   static T (max)() { assert(false && "Highest not supported for this type"); }
    180   static T (min)() { assert(false && "Lowest not supported for this type"); }
    181   static T infinity() { assert(false && "Infinity not supported for this type"); }
    182   static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
    183 };
    184 template<> struct numeric_limits<float>
    185 {
    186   EIGEN_DEVICE_FUNC
    187   static float epsilon() { return __FLT_EPSILON__; }
    188   EIGEN_DEVICE_FUNC
    189   static float (max)() { return CUDART_MAX_NORMAL_F; }
    190   EIGEN_DEVICE_FUNC
    191   static float (min)() { return FLT_MIN; }
    192   EIGEN_DEVICE_FUNC
    193   static float infinity() { return CUDART_INF_F; }
    194   EIGEN_DEVICE_FUNC
    195   static float quiet_NaN() { return CUDART_NAN_F; }
    196 };
    197 template<> struct numeric_limits<double>
    198 {
    199   EIGEN_DEVICE_FUNC
    200   static double epsilon() { return __DBL_EPSILON__; }
    201   EIGEN_DEVICE_FUNC
    202   static double (max)() { return DBL_MAX; }
    203   EIGEN_DEVICE_FUNC
    204   static double (min)() { return DBL_MIN; }
    205   EIGEN_DEVICE_FUNC
    206   static double infinity() { return CUDART_INF; }
    207   EIGEN_DEVICE_FUNC
    208   static double quiet_NaN() { return CUDART_NAN; }
    209 };
    210 template<> struct numeric_limits<int>
    211 {
    212   EIGEN_DEVICE_FUNC
    213   static int epsilon() { return 0; }
    214   EIGEN_DEVICE_FUNC
    215   static int (max)() { return INT_MAX; }
    216   EIGEN_DEVICE_FUNC
    217   static int (min)() { return INT_MIN; }
    218 };
    219 template<> struct numeric_limits<unsigned int>
    220 {
    221   EIGEN_DEVICE_FUNC
    222   static unsigned int epsilon() { return 0; }
    223   EIGEN_DEVICE_FUNC
    224   static unsigned int (max)() { return UINT_MAX; }
    225   EIGEN_DEVICE_FUNC
    226   static unsigned int (min)() { return 0; }
    227 };
    228 template<> struct numeric_limits<long>
    229 {
    230   EIGEN_DEVICE_FUNC
    231   static long epsilon() { return 0; }
    232   EIGEN_DEVICE_FUNC
    233   static long (max)() { return LONG_MAX; }
    234   EIGEN_DEVICE_FUNC
    235   static long (min)() { return LONG_MIN; }
    236 };
    237 template<> struct numeric_limits<unsigned long>
    238 {
    239   EIGEN_DEVICE_FUNC
    240   static unsigned long epsilon() { return 0; }
    241   EIGEN_DEVICE_FUNC
    242   static unsigned long (max)() { return ULONG_MAX; }
    243   EIGEN_DEVICE_FUNC
    244   static unsigned long (min)() { return 0; }
    245 };
    246 template<> struct numeric_limits<long long>
    247 {
    248   EIGEN_DEVICE_FUNC
    249   static long long epsilon() { return 0; }
    250   EIGEN_DEVICE_FUNC
    251   static long long (max)() { return LLONG_MAX; }
    252   EIGEN_DEVICE_FUNC
    253   static long long (min)() { return LLONG_MIN; }
    254 };
    255 template<> struct numeric_limits<unsigned long long>
    256 {
    257   EIGEN_DEVICE_FUNC
    258   static unsigned long long epsilon() { return 0; }
    259   EIGEN_DEVICE_FUNC
    260   static unsigned long long (max)() { return ULLONG_MAX; }
    261   EIGEN_DEVICE_FUNC
    262   static unsigned long long (min)() { return 0; }
    263 };
    264 
    265 }
    266 
    267 #endif
    268 
    269 /** \internal
    270   * A base class do disable default copy ctor and copy assignement operator.
    271   */
    272 class noncopyable
    273 {
    274   EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
    275   EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
    276 protected:
    277   EIGEN_DEVICE_FUNC noncopyable() {}
    278   EIGEN_DEVICE_FUNC ~noncopyable() {}
    279 };
    280 
    281 /** \internal
    282   * Convenient struct to get the result type of a unary or binary functor.
    283   *
    284   * It supports both the current STL mechanism (using the result_type member) as well as
    285   * upcoming next STL generation (using a templated result member).
    286   * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
    287   */
    288 #if EIGEN_HAS_STD_RESULT_OF
    289 template<typename T> struct result_of {
    290   typedef typename std::result_of<T>::type type1;
    291   typedef typename remove_all<type1>::type type;
    292 };
    293 #else
    294 template<typename T> struct result_of { };
    295 
    296 struct has_none {int a[1];};
    297 struct has_std_result_type {int a[2];};
    298 struct has_tr1_result {int a[3];};
    299 
    300 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
    301 struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
    302 
    303 template<typename Func, typename ArgType>
    304 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
    305 
    306 template<typename Func, typename ArgType>
    307 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
    308 
    309 template<typename Func, typename ArgType>
    310 struct result_of<Func(ArgType)> {
    311     template<typename T>
    312     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    313     template<typename T>
    314     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
    315     static has_none               testFunctor(...);
    316 
    317     // note that the following indirection is needed for gcc-3.3
    318     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    319     typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
    320 };
    321 
    322 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
    323 struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
    324 
    325 template<typename Func, typename ArgType0, typename ArgType1>
    326 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
    327 {typedef typename Func::result_type type;};
    328 
    329 template<typename Func, typename ArgType0, typename ArgType1>
    330 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
    331 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
    332 
    333 template<typename Func, typename ArgType0, typename ArgType1>
    334 struct result_of<Func(ArgType0,ArgType1)> {
    335     template<typename T>
    336     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    337     template<typename T>
    338     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
    339     static has_none               testFunctor(...);
    340 
    341     // note that the following indirection is needed for gcc-3.3
    342     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    343     typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
    344 };
    345 
    346 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)>
    347 struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
    348 
    349 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
    350 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)>
    351 {typedef typename Func::result_type type;};
    352 
    353 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
    354 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)>
    355 {typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;};
    356 
    357 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
    358 struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
    359     template<typename T>
    360     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    361     template<typename T>
    362     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0);
    363     static has_none               testFunctor(...);
    364 
    365     // note that the following indirection is needed for gcc-3.3
    366     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    367     typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
    368 };
    369 #endif
    370 
    371 struct meta_yes { char a[1]; };
    372 struct meta_no  { char a[2]; };
    373 
    374 // Check whether T::ReturnType does exist
    375 template <typename T>
    376 struct has_ReturnType
    377 {
    378   template <typename C> static meta_yes testFunctor(typename C::ReturnType const *);
    379   template <typename C> static meta_no testFunctor(...);
    380 
    381   enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) };
    382 };
    383 
    384 template<typename T> const T* return_ptr();
    385 
    386 template <typename T, typename IndexType=Index>
    387 struct has_nullary_operator
    388 {
    389   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
    390   static meta_no testFunctor(...);
    391 
    392   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
    393 };
    394 
    395 template <typename T, typename IndexType=Index>
    396 struct has_unary_operator
    397 {
    398   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0);
    399   static meta_no testFunctor(...);
    400 
    401   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
    402 };
    403 
    404 template <typename T, typename IndexType=Index>
    405 struct has_binary_operator
    406 {
    407   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0);
    408   static meta_no testFunctor(...);
    409 
    410   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
    411 };
    412 
    413 /** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
    414   * Usage example: \code meta_sqrt<1023>::ret \endcode
    415   */
    416 template<int Y,
    417          int InfX = 0,
    418          int SupX = ((Y==1) ? 1 : Y/2),
    419          bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
    420                                 // use ?: instead of || just to shut up a stupid gcc 4.3 warning
    421 class meta_sqrt
    422 {
    423     enum {
    424       MidX = (InfX+SupX)/2,
    425       TakeInf = MidX*MidX > Y ? 1 : 0,
    426       NewInf = int(TakeInf) ? InfX : int(MidX),
    427       NewSup = int(TakeInf) ? int(MidX) : SupX
    428     };
    429   public:
    430     enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
    431 };
    432 
    433 template<int Y, int InfX, int SupX>
    434 class meta_sqrt<Y, InfX, SupX, true> { public:  enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
    435 
    436 
    437 /** \internal Computes the least common multiple of two positive integer A and B
    438   * at compile-time. It implements a naive algorithm testing all multiples of A.
    439   * It thus works better if A>=B.
    440   */
    441 template<int A, int B, int K=1, bool Done = ((A*K)%B)==0>
    442 struct meta_least_common_multiple
    443 {
    444   enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
    445 };
    446 template<int A, int B, int K>
    447 struct meta_least_common_multiple<A,B,K,true>
    448 {
    449   enum { ret = A*K };
    450 };
    451 
    452 /** \internal determines whether the product of two numeric types is allowed and what the return type is */
    453 template<typename T, typename U> struct scalar_product_traits
    454 {
    455   enum { Defined = 0 };
    456 };
    457 
    458 // FIXME quick workaround around current limitation of result_of
    459 // template<typename Scalar, typename ArgType0, typename ArgType1>
    460 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
    461 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
    462 // };
    463 
    464 } // end namespace internal
    465 
    466 namespace numext {
    467 
    468 #if defined(__CUDA_ARCH__)
    469 template<typename T> EIGEN_DEVICE_FUNC   void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
    470 #else
    471 template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
    472 #endif
    473 
    474 #if defined(__CUDA_ARCH__)
    475 using internal::device::numeric_limits;
    476 #else
    477 using std::numeric_limits;
    478 #endif
    479 
    480 // Integer division with rounding up.
    481 // T is assumed to be an integer type with a>=0, and b>0
    482 template<typename T>
    483 T div_ceil(const T &a, const T &b)
    484 {
    485   return (a+b-1) / b;
    486 }
    487 
    488 } // end namespace numext
    489 
    490 } // end namespace Eigen
    491 
    492 #endif // EIGEN_META_H
    493