cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

Meta.h (29336B)


      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@inria.fr>
      5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@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(EIGEN_GPU_COMPILE_PHASE)
     15 
     16  #include <cfloat>
     17 
     18  #if defined(EIGEN_CUDA_ARCH)
     19   #include <math_constants.h>
     20  #endif
     21 
     22  #if defined(EIGEN_HIP_DEVICE_COMPILE)
     23   #include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
     24   #endif
     25 
     26 #endif
     27 
     28 // Recent versions of ICC require <cstdint> for pointer types below.
     29 #define EIGEN_ICC_NEEDS_CSTDINT (EIGEN_COMP_ICC>=1600 && EIGEN_COMP_CXXVER >= 11)
     30 
     31 // Define portable (u)int{32,64} types
     32 #if EIGEN_HAS_CXX11 || EIGEN_ICC_NEEDS_CSTDINT
     33 #include <cstdint>
     34 namespace Eigen {
     35 namespace numext {
     36 typedef std::uint8_t  uint8_t;
     37 typedef std::int8_t   int8_t;
     38 typedef std::uint16_t uint16_t;
     39 typedef std::int16_t  int16_t;
     40 typedef std::uint32_t uint32_t;
     41 typedef std::int32_t  int32_t;
     42 typedef std::uint64_t uint64_t;
     43 typedef std::int64_t  int64_t;
     44 }
     45 }
     46 #else
     47 // Without c++11, all compilers able to compile Eigen also
     48 // provide the C99 stdint.h header file.
     49 #include <stdint.h>
     50 namespace Eigen {
     51 namespace numext {
     52 typedef ::uint8_t  uint8_t;
     53 typedef ::int8_t   int8_t;
     54 typedef ::uint16_t uint16_t;
     55 typedef ::int16_t  int16_t;
     56 typedef ::uint32_t uint32_t;
     57 typedef ::int32_t  int32_t;
     58 typedef ::uint64_t uint64_t;
     59 typedef ::int64_t  int64_t;
     60 }
     61 }
     62 #endif
     63 
     64 namespace Eigen {
     65 
     66 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
     67 
     68 /**
     69  * \brief The Index type as used for the API.
     70  * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
     71  * \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
     72  */
     73 
     74 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
     75 
     76 namespace internal {
     77 
     78 /** \internal
     79   * \file Meta.h
     80   * This file contains generic metaprogramming classes which are not specifically related to Eigen.
     81   * \note In case you wonder, yes we're aware that Boost already provides all these features,
     82   * we however don't want to add a dependency to Boost.
     83   */
     84 
     85 // Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
     86 // and older versions do not provide *intptr_t types.
     87 #if EIGEN_ICC_NEEDS_CSTDINT
     88 typedef std::intptr_t  IntPtr;
     89 typedef std::uintptr_t UIntPtr;
     90 #else
     91 typedef std::ptrdiff_t IntPtr;
     92 typedef std::size_t UIntPtr;
     93 #endif
     94 #undef EIGEN_ICC_NEEDS_CSTDINT
     95 
     96 struct true_type {  enum { value = 1 }; };
     97 struct false_type { enum { value = 0 }; };
     98 
     99 template<bool Condition>
    100 struct bool_constant;
    101 
    102 template<>
    103 struct bool_constant<true> : true_type {};
    104 
    105 template<>
    106 struct bool_constant<false> : false_type {};
    107 
    108 template<bool Condition, typename Then, typename Else>
    109 struct conditional { typedef Then type; };
    110 
    111 template<typename Then, typename Else>
    112 struct conditional <false, Then, Else> { typedef Else type; };
    113 
    114 template<typename T> struct remove_reference { typedef T type; };
    115 template<typename T> struct remove_reference<T&> { typedef T type; };
    116 
    117 template<typename T> struct remove_pointer { typedef T type; };
    118 template<typename T> struct remove_pointer<T*> { typedef T type; };
    119 template<typename T> struct remove_pointer<T*const> { typedef T type; };
    120 
    121 template <class T> struct remove_const { typedef T type; };
    122 template <class T> struct remove_const<const T> { typedef T type; };
    123 template <class T> struct remove_const<const T[]> { typedef T type[]; };
    124 template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
    125 
    126 template<typename T> struct remove_all { typedef T type; };
    127 template<typename T> struct remove_all<const T>   { typedef typename remove_all<T>::type type; };
    128 template<typename T> struct remove_all<T const&>  { typedef typename remove_all<T>::type type; };
    129 template<typename T> struct remove_all<T&>        { typedef typename remove_all<T>::type type; };
    130 template<typename T> struct remove_all<T const*>  { typedef typename remove_all<T>::type type; };
    131 template<typename T> struct remove_all<T*>        { typedef typename remove_all<T>::type type; };
    132 
    133 template<typename T> struct is_arithmetic      { enum { value = false }; };
    134 template<> struct is_arithmetic<float>         { enum { value = true }; };
    135 template<> struct is_arithmetic<double>        { enum { value = true }; };
    136 template<> struct is_arithmetic<long double>   { enum { value = true }; };
    137 template<> struct is_arithmetic<bool>          { enum { value = true }; };
    138 template<> struct is_arithmetic<char>          { enum { value = true }; };
    139 template<> struct is_arithmetic<signed char>   { enum { value = true }; };
    140 template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
    141 template<> struct is_arithmetic<signed short>  { enum { value = true }; };
    142 template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
    143 template<> struct is_arithmetic<signed int>    { enum { value = true }; };
    144 template<> struct is_arithmetic<unsigned int>  { enum { value = true }; };
    145 template<> struct is_arithmetic<signed long>   { enum { value = true }; };
    146 template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
    147 
    148 template<typename T, typename U> struct is_same { enum { value = 0 }; };
    149 template<typename T> struct is_same<T,T> { enum { value = 1 }; };
    150 
    151 template< class T >
    152 struct is_void : is_same<void, typename remove_const<T>::type> {};
    153 
    154 #if EIGEN_HAS_CXX11
    155 template<> struct is_arithmetic<signed long long>   { enum { value = true }; };
    156 template<> struct is_arithmetic<unsigned long long> { enum { value = true }; };
    157 using std::is_integral;
    158 #else
    159 template<typename T> struct is_integral               { enum { value = false }; };
    160 template<> struct is_integral<bool>                   { enum { value = true }; };
    161 template<> struct is_integral<char>                   { enum { value = true }; };
    162 template<> struct is_integral<signed char>            { enum { value = true }; };
    163 template<> struct is_integral<unsigned char>          { enum { value = true }; };
    164 template<> struct is_integral<signed short>           { enum { value = true }; };
    165 template<> struct is_integral<unsigned short>         { enum { value = true }; };
    166 template<> struct is_integral<signed int>             { enum { value = true }; };
    167 template<> struct is_integral<unsigned int>           { enum { value = true }; };
    168 template<> struct is_integral<signed long>            { enum { value = true }; };
    169 template<> struct is_integral<unsigned long>          { enum { value = true }; };
    170 #if EIGEN_COMP_MSVC
    171 template<> struct is_integral<signed __int64>         { enum { value = true }; };
    172 template<> struct is_integral<unsigned __int64>       { enum { value = true }; };
    173 #endif
    174 #endif
    175 
    176 #if EIGEN_HAS_CXX11
    177 using std::make_unsigned;
    178 #else
    179 // TODO: Possibly improve this implementation of make_unsigned.
    180 // It is currently used only by
    181 // template<typename Scalar> struct random_default_impl<Scalar, false, true>.
    182 template<typename> struct make_unsigned;
    183 template<> struct make_unsigned<char>             { typedef unsigned char type; };
    184 template<> struct make_unsigned<signed char>      { typedef unsigned char type; };
    185 template<> struct make_unsigned<unsigned char>    { typedef unsigned char type; };
    186 template<> struct make_unsigned<signed short>     { typedef unsigned short type; };
    187 template<> struct make_unsigned<unsigned short>   { typedef unsigned short type; };
    188 template<> struct make_unsigned<signed int>       { typedef unsigned int type; };
    189 template<> struct make_unsigned<unsigned int>     { typedef unsigned int type; };
    190 template<> struct make_unsigned<signed long>      { typedef unsigned long type; };
    191 template<> struct make_unsigned<unsigned long>    { typedef unsigned long type; };
    192 #if EIGEN_COMP_MSVC
    193 template<> struct make_unsigned<signed __int64>   { typedef unsigned __int64 type; };
    194 template<> struct make_unsigned<unsigned __int64> { typedef unsigned __int64 type; };
    195 #endif
    196 
    197 // Some platforms define int64_t as `long long` even for C++03, where
    198 // `long long` is not guaranteed by the standard. In this case we are missing
    199 // the definition for make_unsigned. If we just define it, we run into issues
    200 // where `long long` doesn't exist in some compilers for C++03. We therefore add
    201 // the specialization for these platforms only.
    202 #if EIGEN_OS_MAC || EIGEN_COMP_MINGW
    203 template<> struct make_unsigned<unsigned long long> { typedef unsigned long long type; };
    204 template<> struct make_unsigned<long long>          { typedef unsigned long long type; };
    205 #endif
    206 #endif
    207 
    208 template <typename T> struct add_const { typedef const T type; };
    209 template <typename T> struct add_const<T&> { typedef T& type; };
    210 
    211 template <typename T> struct is_const { enum { value = 0 }; };
    212 template <typename T> struct is_const<T const> { enum { value = 1 }; };
    213 
    214 template<typename T> struct add_const_on_value_type            { typedef const T type;  };
    215 template<typename T> struct add_const_on_value_type<T&>        { typedef T const& type; };
    216 template<typename T> struct add_const_on_value_type<T*>        { typedef T const* type; };
    217 template<typename T> struct add_const_on_value_type<T* const>  { typedef T const* const type; };
    218 template<typename T> struct add_const_on_value_type<T const* const>  { typedef T const* const type; };
    219 
    220 #if EIGEN_HAS_CXX11
    221 
    222 using std::is_convertible;
    223 
    224 #else
    225 
    226 template<typename From, typename To>
    227 struct is_convertible_impl
    228 {
    229 private:
    230   struct any_conversion
    231   {
    232     template <typename T> any_conversion(const volatile T&);
    233     template <typename T> any_conversion(T&);
    234   };
    235   struct yes {int a[1];};
    236   struct no  {int a[2];};
    237 
    238   template<typename T>
    239   static yes test(T, int);
    240 
    241   template<typename T>
    242   static no  test(any_conversion, ...);
    243 
    244 public:
    245   static typename internal::remove_reference<From>::type* ms_from;
    246 #ifdef __INTEL_COMPILER
    247   #pragma warning push
    248   #pragma warning ( disable : 2259 )
    249 #endif
    250   enum { value = sizeof(test<To>(*ms_from, 0))==sizeof(yes) };
    251 #ifdef __INTEL_COMPILER
    252   #pragma warning pop
    253 #endif
    254 };
    255 
    256 template<typename From, typename To>
    257 struct is_convertible
    258 {
    259   enum { value = is_convertible_impl<From,To>::value };
    260 };
    261 
    262 template<typename T>
    263 struct is_convertible<T,T&> { enum { value = false }; };
    264 
    265 template<typename T>
    266 struct is_convertible<const T,const T&> { enum { value = true }; };
    267 
    268 #endif
    269 
    270 /** \internal Allows to enable/disable an overload
    271   * according to a compile time condition.
    272   */
    273 template<bool Condition, typename T=void> struct enable_if;
    274 
    275 template<typename T> struct enable_if<true,T>
    276 { typedef T type; };
    277 
    278 #if defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
    279 #if !defined(__FLT_EPSILON__)
    280 #define __FLT_EPSILON__ FLT_EPSILON
    281 #define __DBL_EPSILON__ DBL_EPSILON
    282 #endif
    283 
    284 namespace device {
    285 
    286 template<typename T> struct numeric_limits
    287 {
    288   EIGEN_DEVICE_FUNC
    289   static EIGEN_CONSTEXPR T epsilon() { return 0; }
    290   static T (max)() { assert(false && "Highest not supported for this type"); }
    291   static T (min)() { assert(false && "Lowest not supported for this type"); }
    292   static T infinity() { assert(false && "Infinity not supported for this type"); }
    293   static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
    294 };
    295 template<> struct numeric_limits<float>
    296 {
    297   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    298   static float epsilon() { return __FLT_EPSILON__; }
    299   EIGEN_DEVICE_FUNC
    300   static float (max)() {
    301   #if defined(EIGEN_CUDA_ARCH)
    302     return CUDART_MAX_NORMAL_F;
    303   #else
    304     return HIPRT_MAX_NORMAL_F;
    305   #endif
    306   }
    307   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    308   static float (min)() { return FLT_MIN; }
    309   EIGEN_DEVICE_FUNC
    310   static float infinity() {
    311   #if defined(EIGEN_CUDA_ARCH)
    312     return CUDART_INF_F;
    313   #else
    314     return HIPRT_INF_F;
    315   #endif
    316   }
    317   EIGEN_DEVICE_FUNC
    318   static float quiet_NaN() {
    319   #if defined(EIGEN_CUDA_ARCH)
    320     return CUDART_NAN_F;
    321   #else
    322     return HIPRT_NAN_F;
    323   #endif
    324   }
    325 };
    326 template<> struct numeric_limits<double>
    327 {
    328   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    329   static double epsilon() { return __DBL_EPSILON__; }
    330   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    331   static double (max)() { return DBL_MAX; }
    332   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    333   static double (min)() { return DBL_MIN; }
    334   EIGEN_DEVICE_FUNC
    335   static double infinity() {
    336   #if defined(EIGEN_CUDA_ARCH)
    337     return CUDART_INF;
    338   #else
    339     return HIPRT_INF;
    340   #endif
    341   }
    342   EIGEN_DEVICE_FUNC
    343   static double quiet_NaN() {
    344   #if defined(EIGEN_CUDA_ARCH)
    345     return CUDART_NAN;
    346   #else
    347     return HIPRT_NAN;
    348   #endif
    349   }
    350 };
    351 template<> struct numeric_limits<int>
    352 {
    353   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    354   static int epsilon() { return 0; }
    355   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    356   static int (max)() { return INT_MAX; }
    357   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    358   static int (min)() { return INT_MIN; }
    359 };
    360 template<> struct numeric_limits<unsigned int>
    361 {
    362   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    363   static unsigned int epsilon() { return 0; }
    364   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    365   static unsigned int (max)() { return UINT_MAX; }
    366   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    367   static unsigned int (min)() { return 0; }
    368 };
    369 template<> struct numeric_limits<long>
    370 {
    371   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    372   static long epsilon() { return 0; }
    373   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    374   static long (max)() { return LONG_MAX; }
    375   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    376   static long (min)() { return LONG_MIN; }
    377 };
    378 template<> struct numeric_limits<unsigned long>
    379 {
    380   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    381   static unsigned long epsilon() { return 0; }
    382   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    383   static unsigned long (max)() { return ULONG_MAX; }
    384   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    385   static unsigned long (min)() { return 0; }
    386 };
    387 template<> struct numeric_limits<long long>
    388 {
    389   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    390   static long long epsilon() { return 0; }
    391   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    392   static long long (max)() { return LLONG_MAX; }
    393   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    394   static long long (min)() { return LLONG_MIN; }
    395 };
    396 template<> struct numeric_limits<unsigned long long>
    397 {
    398   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    399   static unsigned long long epsilon() { return 0; }
    400   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    401   static unsigned long long (max)() { return ULLONG_MAX; }
    402   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    403   static unsigned long long (min)() { return 0; }
    404 };
    405 template<> struct numeric_limits<bool>
    406 {
    407   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    408   static bool epsilon() { return false; }
    409   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    410   static bool (max)() { return true; }
    411   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 
    412   static bool (min)() { return false; }
    413 };
    414 
    415 }
    416 
    417 #endif // defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
    418 
    419 /** \internal
    420   * A base class do disable default copy ctor and copy assignment operator.
    421   */
    422 class noncopyable
    423 {
    424   EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
    425   EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
    426 protected:
    427   EIGEN_DEVICE_FUNC noncopyable() {}
    428   EIGEN_DEVICE_FUNC ~noncopyable() {}
    429 };
    430 
    431 /** \internal
    432   * Provides access to the number of elements in the object of as a compile-time constant expression.
    433   * It "returns" Eigen::Dynamic if the size cannot be resolved at compile-time (default).
    434   *
    435   * Similar to std::tuple_size, but more general.
    436   *
    437   * It currently supports:
    438   *  - any types T defining T::SizeAtCompileTime
    439   *  - plain C arrays as T[N]
    440   *  - std::array (c++11)
    441   *  - some internal types such as SingleRange and AllRange
    442   *
    443   * The second template parameter eases SFINAE-based specializations.
    444   */
    445 template<typename T, typename EnableIf = void> struct array_size {
    446   enum { value = Dynamic };
    447 };
    448 
    449 template<typename T> struct array_size<T,typename internal::enable_if<((T::SizeAtCompileTime&0)==0)>::type> {
    450   enum { value = T::SizeAtCompileTime };
    451 };
    452 
    453 template<typename T, int N> struct array_size<const T (&)[N]> {
    454   enum { value = N };
    455 };
    456 template<typename T, int N> struct array_size<T (&)[N]> {
    457   enum { value = N };
    458 };
    459 
    460 #if EIGEN_HAS_CXX11
    461 template<typename T, std::size_t N> struct array_size<const std::array<T,N> > {
    462   enum { value = N };
    463 };
    464 template<typename T, std::size_t N> struct array_size<std::array<T,N> > {
    465   enum { value = N };
    466 };
    467 #endif
    468 
    469 /** \internal
    470   * Analogue of the std::size free function.
    471   * It returns the size of the container or view \a x of type \c T
    472   *
    473   * It currently supports:
    474   *  - any types T defining a member T::size() const
    475   *  - plain C arrays as T[N]
    476   *
    477   */
    478 template<typename T>
    479 EIGEN_CONSTEXPR Index size(const T& x) { return x.size(); }
    480 
    481 template<typename T,std::size_t N>
    482 EIGEN_CONSTEXPR Index size(const T (&) [N]) { return N; }
    483 
    484 /** \internal
    485   * Convenient struct to get the result type of a nullary, unary, binary, or
    486   * ternary functor.
    487   * 
    488   * Pre C++11:
    489   * Supports both a Func::result_type member and templated
    490   * Func::result<Func(ArgTypes...)>::type member.
    491   * 
    492   * If none of these members is provided, then the type of the first
    493   * argument is returned.
    494   * 
    495   * Post C++11:
    496   * This uses std::result_of. However, note the `type` member removes
    497   * const and converts references/pointers to their corresponding value type.
    498   */
    499 #if EIGEN_HAS_STD_INVOKE_RESULT
    500 template<typename T> struct result_of;
    501 
    502 template<typename F, typename... ArgTypes>
    503 struct result_of<F(ArgTypes...)> {
    504   typedef typename std::invoke_result<F, ArgTypes...>::type type1;
    505   typedef typename remove_all<type1>::type type;
    506 };
    507 #elif EIGEN_HAS_STD_RESULT_OF
    508 template<typename T> struct result_of {
    509   typedef typename std::result_of<T>::type type1;
    510   typedef typename remove_all<type1>::type type;
    511 };
    512 #else
    513 template<typename T> struct result_of { };
    514 
    515 struct has_none {int a[1];};
    516 struct has_std_result_type {int a[2];};
    517 struct has_tr1_result {int a[3];};
    518 
    519 template<typename Func, int SizeOf>
    520 struct nullary_result_of_select {};
    521 
    522 template<typename Func>
    523 struct nullary_result_of_select<Func, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
    524 
    525 template<typename Func>
    526 struct nullary_result_of_select<Func, sizeof(has_tr1_result)> {typedef typename Func::template result<Func()>::type type;};
    527 
    528 template<typename Func>
    529 struct result_of<Func()> {
    530     template<typename T>
    531     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    532     template<typename T>
    533     static has_tr1_result         testFunctor(T const *, typename T::template result<T()>::type const * = 0);
    534     static has_none               testFunctor(...);
    535 
    536     // note that the following indirection is needed for gcc-3.3
    537     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    538     typedef typename nullary_result_of_select<Func, FunctorType>::type type;
    539 };
    540 
    541 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
    542 struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
    543 
    544 template<typename Func, typename ArgType>
    545 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
    546 
    547 template<typename Func, typename ArgType>
    548 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
    549 
    550 template<typename Func, typename ArgType>
    551 struct result_of<Func(ArgType)> {
    552     template<typename T>
    553     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    554     template<typename T>
    555     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
    556     static has_none               testFunctor(...);
    557 
    558     // note that the following indirection is needed for gcc-3.3
    559     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    560     typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
    561 };
    562 
    563 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
    564 struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
    565 
    566 template<typename Func, typename ArgType0, typename ArgType1>
    567 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
    568 {typedef typename Func::result_type type;};
    569 
    570 template<typename Func, typename ArgType0, typename ArgType1>
    571 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
    572 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
    573 
    574 template<typename Func, typename ArgType0, typename ArgType1>
    575 struct result_of<Func(ArgType0,ArgType1)> {
    576     template<typename T>
    577     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    578     template<typename T>
    579     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
    580     static has_none               testFunctor(...);
    581 
    582     // note that the following indirection is needed for gcc-3.3
    583     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    584     typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
    585 };
    586 
    587 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)>
    588 struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
    589 
    590 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
    591 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)>
    592 {typedef typename Func::result_type type;};
    593 
    594 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
    595 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)>
    596 {typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;};
    597 
    598 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
    599 struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
    600     template<typename T>
    601     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
    602     template<typename T>
    603     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0);
    604     static has_none               testFunctor(...);
    605 
    606     // note that the following indirection is needed for gcc-3.3
    607     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
    608     typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
    609 };
    610 
    611 #endif
    612 
    613 #if EIGEN_HAS_STD_INVOKE_RESULT
    614 template<typename F, typename... ArgTypes>
    615 struct invoke_result {
    616   typedef typename std::invoke_result<F, ArgTypes...>::type type1;
    617   typedef typename remove_all<type1>::type type;
    618 };
    619 #elif EIGEN_HAS_CXX11
    620 template<typename F, typename... ArgTypes>
    621 struct invoke_result {
    622   typedef typename result_of<F(ArgTypes...)>::type type1;
    623   typedef typename remove_all<type1>::type type;
    624 };
    625 #else
    626 template<typename F, typename ArgType0 = void, typename ArgType1 = void, typename ArgType2 = void>
    627 struct invoke_result {
    628   typedef typename result_of<F(ArgType0, ArgType1, ArgType2)>::type type1;
    629   typedef typename remove_all<type1>::type type;
    630 };
    631 
    632 template<typename F>
    633 struct invoke_result<F, void, void, void> {
    634   typedef typename result_of<F()>::type type1;
    635   typedef typename remove_all<type1>::type type;
    636 };
    637 
    638 template<typename F, typename ArgType0>
    639 struct invoke_result<F, ArgType0, void, void> {
    640   typedef typename result_of<F(ArgType0)>::type type1;
    641   typedef typename remove_all<type1>::type type;
    642 };
    643 
    644 template<typename F, typename ArgType0, typename ArgType1>
    645 struct invoke_result<F, ArgType0, ArgType1, void> {
    646   typedef typename result_of<F(ArgType0, ArgType1)>::type type1;
    647   typedef typename remove_all<type1>::type type;
    648 };
    649 #endif
    650 
    651 struct meta_yes { char a[1]; };
    652 struct meta_no  { char a[2]; };
    653 
    654 // Check whether T::ReturnType does exist
    655 template <typename T>
    656 struct has_ReturnType
    657 {
    658   template <typename C> static meta_yes testFunctor(C const *, typename C::ReturnType const * = 0);
    659   template <typename C> static meta_no  testFunctor(...);
    660 
    661   enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
    662 };
    663 
    664 template<typename T> const T* return_ptr();
    665 
    666 template <typename T, typename IndexType=Index>
    667 struct has_nullary_operator
    668 {
    669   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
    670   static meta_no testFunctor(...);
    671 
    672   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
    673 };
    674 
    675 template <typename T, typename IndexType=Index>
    676 struct has_unary_operator
    677 {
    678   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0);
    679   static meta_no testFunctor(...);
    680 
    681   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
    682 };
    683 
    684 template <typename T, typename IndexType=Index>
    685 struct has_binary_operator
    686 {
    687   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0);
    688   static meta_no testFunctor(...);
    689 
    690   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
    691 };
    692 
    693 /** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
    694   * Usage example: \code meta_sqrt<1023>::ret \endcode
    695   */
    696 template<int Y,
    697          int InfX = 0,
    698          int SupX = ((Y==1) ? 1 : Y/2),
    699          bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
    700                                 // use ?: instead of || just to shut up a stupid gcc 4.3 warning
    701 class meta_sqrt
    702 {
    703     enum {
    704       MidX = (InfX+SupX)/2,
    705       TakeInf = MidX*MidX > Y ? 1 : 0,
    706       NewInf = int(TakeInf) ? InfX : int(MidX),
    707       NewSup = int(TakeInf) ? int(MidX) : SupX
    708     };
    709   public:
    710     enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
    711 };
    712 
    713 template<int Y, int InfX, int SupX>
    714 class meta_sqrt<Y, InfX, SupX, true> { public:  enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
    715 
    716 
    717 /** \internal Computes the least common multiple of two positive integer A and B
    718   * at compile-time. 
    719   */
    720 template<int A, int B, int K=1, bool Done = ((A*K)%B)==0, bool Big=(A>=B)>
    721 struct meta_least_common_multiple
    722 {
    723   enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
    724 };
    725 template<int A, int B, int K, bool Done>
    726 struct meta_least_common_multiple<A,B,K,Done,false>
    727 {
    728   enum { ret = meta_least_common_multiple<B,A,K>::ret };
    729 };
    730 template<int A, int B, int K>
    731 struct meta_least_common_multiple<A,B,K,true,true>
    732 {
    733   enum { ret = A*K };
    734 };
    735 
    736 
    737 /** \internal determines whether the product of two numeric types is allowed and what the return type is */
    738 template<typename T, typename U> struct scalar_product_traits
    739 {
    740   enum { Defined = 0 };
    741 };
    742 
    743 // FIXME quick workaround around current limitation of result_of
    744 // template<typename Scalar, typename ArgType0, typename ArgType1>
    745 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
    746 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
    747 // };
    748 
    749 /** \internal Obtains a POD type suitable to use as storage for an object of a size
    750   * of at most Len bytes, aligned as specified by \c Align.
    751   */
    752 template<unsigned Len, unsigned Align>
    753 struct aligned_storage {
    754   struct type {
    755     EIGEN_ALIGN_TO_BOUNDARY(Align) unsigned char data[Len];
    756   };
    757 };
    758 
    759 } // end namespace internal
    760 
    761 namespace numext {
    762 
    763 #if defined(EIGEN_GPU_COMPILE_PHASE)
    764 template<typename T> EIGEN_DEVICE_FUNC   void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
    765 #else
    766 template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
    767 #endif
    768 
    769 #if defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
    770 using internal::device::numeric_limits;
    771 #else
    772 using std::numeric_limits;
    773 #endif
    774 
    775 // Integer division with rounding up.
    776 // T is assumed to be an integer type with a>=0, and b>0
    777 template<typename T>
    778 EIGEN_DEVICE_FUNC
    779 T div_ceil(const T &a, const T &b)
    780 {
    781   return (a+b-1) / b;
    782 }
    783 
    784 // The aim of the following functions is to bypass -Wfloat-equal warnings
    785 // when we really want a strict equality comparison on floating points.
    786 template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
    787 bool equal_strict(const X& x,const Y& y) { return x == y; }
    788 
    789 #if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
    790 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
    791 bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
    792 
    793 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
    794 bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
    795 #endif
    796 
    797 template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
    798 bool not_equal_strict(const X& x,const Y& y) { return x != y; }
    799 
    800 #if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
    801 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
    802 bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
    803 
    804 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
    805 bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
    806 #endif
    807 
    808 } // end namespace numext
    809 
    810 } // end namespace Eigen
    811 
    812 #endif // EIGEN_META_H