Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 09:06:02

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
0006 //
0007 // This Source Code Form is subject to the terms of the Mozilla
0008 // Public License v. 2.0. If a copy of the MPL was not distributed
0009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0010 
0011 #ifndef EIGEN_META_H
0012 #define EIGEN_META_H
0013 
0014 #if defined(EIGEN_GPU_COMPILE_PHASE)
0015 
0016  #include <cfloat>
0017 
0018  #if defined(EIGEN_CUDA_ARCH)
0019   #include <math_constants.h>
0020  #endif
0021 
0022  #if defined(EIGEN_HIP_DEVICE_COMPILE)
0023   #include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
0024   #endif
0025 
0026 #endif
0027 
0028 // Recent versions of ICC require <cstdint> for pointer types below.
0029 #define EIGEN_ICC_NEEDS_CSTDINT (EIGEN_COMP_ICC>=1600 && EIGEN_COMP_CXXVER >= 11)
0030 
0031 // Define portable (u)int{32,64} types
0032 #if EIGEN_HAS_CXX11 || EIGEN_ICC_NEEDS_CSTDINT
0033 #include <cstdint>
0034 namespace RivetEigen {
0035 namespace numext {
0036 typedef std::uint8_t  uint8_t;
0037 typedef std::int8_t   int8_t;
0038 typedef std::uint16_t uint16_t;
0039 typedef std::int16_t  int16_t;
0040 typedef std::uint32_t uint32_t;
0041 typedef std::int32_t  int32_t;
0042 typedef std::uint64_t uint64_t;
0043 typedef std::int64_t  int64_t;
0044 }
0045 }
0046 #else
0047 // Without c++11, all compilers able to compile Eigen also
0048 // provide the C99 stdint.h header file.
0049 #include <stdint.h>
0050 namespace RivetEigen {
0051 namespace numext {
0052 typedef ::uint8_t  uint8_t;
0053 typedef ::int8_t   int8_t;
0054 typedef ::uint16_t uint16_t;
0055 typedef ::int16_t  int16_t;
0056 typedef ::uint32_t uint32_t;
0057 typedef ::int32_t  int32_t;
0058 typedef ::uint64_t uint64_t;
0059 typedef ::int64_t  int64_t;
0060 }
0061 }
0062 #endif
0063 
0064 namespace RivetEigen {
0065 
0066 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
0067 
0068 /**
0069  * \brief The Index type as used for the API.
0070  * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
0071  * \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
0072  */
0073 
0074 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
0075 
0076 namespace internal {
0077 
0078 /** \internal
0079   * \file Meta.h
0080   * This file contains generic metaprogramming classes which are not specifically related to Eigen.
0081   * \note In case you wonder, yes we're aware that Boost already provides all these features,
0082   * we however don't want to add a dependency to Boost.
0083   */
0084 
0085 // Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
0086 // and older versions do not provide *intptr_t types.
0087 #if EIGEN_ICC_NEEDS_CSTDINT
0088 typedef std::intptr_t  IntPtr;
0089 typedef std::uintptr_t UIntPtr;
0090 #else
0091 typedef std::ptrdiff_t IntPtr;
0092 typedef std::size_t UIntPtr;
0093 #endif
0094 #undef EIGEN_ICC_NEEDS_CSTDINT
0095 
0096 struct true_type {  enum { value = 1 }; };
0097 struct false_type { enum { value = 0 }; };
0098 
0099 template<bool Condition>
0100 struct bool_constant;
0101 
0102 template<>
0103 struct bool_constant<true> : true_type {};
0104 
0105 template<>
0106 struct bool_constant<false> : false_type {};
0107 
0108 template<bool Condition, typename Then, typename Else>
0109 struct conditional { typedef Then type; };
0110 
0111 template<typename Then, typename Else>
0112 struct conditional <false, Then, Else> { typedef Else type; };
0113 
0114 template<typename T> struct remove_reference { typedef T type; };
0115 template<typename T> struct remove_reference<T&> { typedef T type; };
0116 
0117 template<typename T> struct remove_pointer { typedef T type; };
0118 template<typename T> struct remove_pointer<T*> { typedef T type; };
0119 template<typename T> struct remove_pointer<T*const> { typedef T type; };
0120 
0121 template <class T> struct remove_const { typedef T type; };
0122 template <class T> struct remove_const<const T> { typedef T type; };
0123 template <class T> struct remove_const<const T[]> { typedef T type[]; };
0124 template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
0125 
0126 template<typename T> struct remove_all { typedef T type; };
0127 template<typename T> struct remove_all<const T>   { typedef typename remove_all<T>::type type; };
0128 template<typename T> struct remove_all<T const&>  { typedef typename remove_all<T>::type type; };
0129 template<typename T> struct remove_all<T&>        { typedef typename remove_all<T>::type type; };
0130 template<typename T> struct remove_all<T const*>  { typedef typename remove_all<T>::type type; };
0131 template<typename T> struct remove_all<T*>        { typedef typename remove_all<T>::type type; };
0132 
0133 template<typename T> struct is_arithmetic      { enum { value = false }; };
0134 template<> struct is_arithmetic<float>         { enum { value = true }; };
0135 template<> struct is_arithmetic<double>        { enum { value = true }; };
0136 template<> struct is_arithmetic<long double>   { enum { value = true }; };
0137 template<> struct is_arithmetic<bool>          { enum { value = true }; };
0138 template<> struct is_arithmetic<char>          { enum { value = true }; };
0139 template<> struct is_arithmetic<signed char>   { enum { value = true }; };
0140 template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
0141 template<> struct is_arithmetic<signed short>  { enum { value = true }; };
0142 template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
0143 template<> struct is_arithmetic<signed int>    { enum { value = true }; };
0144 template<> struct is_arithmetic<unsigned int>  { enum { value = true }; };
0145 template<> struct is_arithmetic<signed long>   { enum { value = true }; };
0146 template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
0147 
0148 template<typename T, typename U> struct is_same { enum { value = 0 }; };
0149 template<typename T> struct is_same<T,T> { enum { value = 1 }; };
0150 
0151 template< class T >
0152 struct is_void : is_same<void, typename remove_const<T>::type> {};
0153 
0154 #if EIGEN_HAS_CXX11
0155 template<> struct is_arithmetic<signed long long>   { enum { value = true }; };
0156 template<> struct is_arithmetic<unsigned long long> { enum { value = true }; };
0157 using std::is_integral;
0158 #else
0159 template<typename T> struct is_integral               { enum { value = false }; };
0160 template<> struct is_integral<bool>                   { enum { value = true }; };
0161 template<> struct is_integral<char>                   { enum { value = true }; };
0162 template<> struct is_integral<signed char>            { enum { value = true }; };
0163 template<> struct is_integral<unsigned char>          { enum { value = true }; };
0164 template<> struct is_integral<signed short>           { enum { value = true }; };
0165 template<> struct is_integral<unsigned short>         { enum { value = true }; };
0166 template<> struct is_integral<signed int>             { enum { value = true }; };
0167 template<> struct is_integral<unsigned int>           { enum { value = true }; };
0168 template<> struct is_integral<signed long>            { enum { value = true }; };
0169 template<> struct is_integral<unsigned long>          { enum { value = true }; };
0170 #if EIGEN_COMP_MSVC
0171 template<> struct is_integral<signed __int64>         { enum { value = true }; };
0172 template<> struct is_integral<unsigned __int64>       { enum { value = true }; };
0173 #endif
0174 #endif
0175 
0176 #if EIGEN_HAS_CXX11
0177 using std::make_unsigned;
0178 #else
0179 // TODO: Possibly improve this implementation of make_unsigned.
0180 // It is currently used only by
0181 // template<typename Scalar> struct random_default_impl<Scalar, false, true>.
0182 template<typename> struct make_unsigned;
0183 template<> struct make_unsigned<char>             { typedef unsigned char type; };
0184 template<> struct make_unsigned<signed char>      { typedef unsigned char type; };
0185 template<> struct make_unsigned<unsigned char>    { typedef unsigned char type; };
0186 template<> struct make_unsigned<signed short>     { typedef unsigned short type; };
0187 template<> struct make_unsigned<unsigned short>   { typedef unsigned short type; };
0188 template<> struct make_unsigned<signed int>       { typedef unsigned int type; };
0189 template<> struct make_unsigned<unsigned int>     { typedef unsigned int type; };
0190 template<> struct make_unsigned<signed long>      { typedef unsigned long type; };
0191 template<> struct make_unsigned<unsigned long>    { typedef unsigned long type; };
0192 #if EIGEN_COMP_MSVC
0193 template<> struct make_unsigned<signed __int64>   { typedef unsigned __int64 type; };
0194 template<> struct make_unsigned<unsigned __int64> { typedef unsigned __int64 type; };
0195 #endif
0196 
0197 // Some platforms define int64_t as `long long` even for C++03, where
0198 // `long long` is not guaranteed by the standard. In this case we are missing
0199 // the definition for make_unsigned. If we just define it, we run into issues
0200 // where `long long` doesn't exist in some compilers for C++03. We therefore add
0201 // the specialization for these platforms only.
0202 #if EIGEN_OS_MAC || EIGEN_COMP_MINGW
0203 template<> struct make_unsigned<unsigned long long> { typedef unsigned long long type; };
0204 template<> struct make_unsigned<long long>          { typedef unsigned long long type; };
0205 #endif
0206 #endif
0207 
0208 template <typename T> struct add_const { typedef const T type; };
0209 template <typename T> struct add_const<T&> { typedef T& type; };
0210 
0211 template <typename T> struct is_const { enum { value = 0 }; };
0212 template <typename T> struct is_const<T const> { enum { value = 1 }; };
0213 
0214 template<typename T> struct add_const_on_value_type            { typedef const T type;  };
0215 template<typename T> struct add_const_on_value_type<T&>        { typedef T const& type; };
0216 template<typename T> struct add_const_on_value_type<T*>        { typedef T const* type; };
0217 template<typename T> struct add_const_on_value_type<T* const>  { typedef T const* const type; };
0218 template<typename T> struct add_const_on_value_type<T const* const>  { typedef T const* const type; };
0219 
0220 #if EIGEN_HAS_CXX11
0221 
0222 using std::is_convertible;
0223 
0224 #else
0225 
0226 template<typename From, typename To>
0227 struct is_convertible_impl
0228 {
0229 private:
0230   struct any_conversion
0231   {
0232     template <typename T> any_conversion(const volatile T&);
0233     template <typename T> any_conversion(T&);
0234   };
0235   struct yes {int a[1];};
0236   struct no  {int a[2];};
0237 
0238   template<typename T>
0239   static yes test(T, int);
0240 
0241   template<typename T>
0242   static no  test(any_conversion, ...);
0243 
0244 public:
0245   static typename internal::remove_reference<From>::type* ms_from;
0246 #ifdef __INTEL_COMPILER
0247   #pragma warning push
0248   #pragma warning ( disable : 2259 )
0249 #endif
0250   enum { value = sizeof(test<To>(*ms_from, 0))==sizeof(yes) };
0251 #ifdef __INTEL_COMPILER
0252   #pragma warning pop
0253 #endif
0254 };
0255 
0256 template<typename From, typename To>
0257 struct is_convertible
0258 {
0259   enum { value = is_convertible_impl<From,To>::value };
0260 };
0261 
0262 template<typename T>
0263 struct is_convertible<T,T&> { enum { value = false }; };
0264 
0265 template<typename T>
0266 struct is_convertible<const T,const T&> { enum { value = true }; };
0267 
0268 #endif
0269 
0270 /** \internal Allows to enable/disable an overload
0271   * according to a compile time condition.
0272   */
0273 template<bool Condition, typename T=void> struct enable_if;
0274 
0275 template<typename T> struct enable_if<true,T>
0276 { typedef T type; };
0277 
0278 #if defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
0279 #if !defined(__FLT_EPSILON__)
0280 #define __FLT_EPSILON__ FLT_EPSILON
0281 #define __DBL_EPSILON__ DBL_EPSILON
0282 #endif
0283 
0284 namespace device {
0285 
0286 template<typename T> struct numeric_limits
0287 {
0288   EIGEN_DEVICE_FUNC
0289   static EIGEN_CONSTEXPR T epsilon() { return 0; }
0290   static T (max)() { assert(false && "Highest not supported for this type"); }
0291   static T (min)() { assert(false && "Lowest not supported for this type"); }
0292   static T infinity() { assert(false && "Infinity not supported for this type"); }
0293   static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
0294 };
0295 template<> struct numeric_limits<float>
0296 {
0297   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0298   static float epsilon() { return __FLT_EPSILON__; }
0299   EIGEN_DEVICE_FUNC
0300   static float (max)() {
0301   #if defined(EIGEN_CUDA_ARCH)
0302     return CUDART_MAX_NORMAL_F;
0303   #else
0304     return HIPRT_MAX_NORMAL_F;
0305   #endif
0306   }
0307   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0308   static float (min)() { return FLT_MIN; }
0309   EIGEN_DEVICE_FUNC
0310   static float infinity() {
0311   #if defined(EIGEN_CUDA_ARCH)
0312     return CUDART_INF_F;
0313   #else
0314     return HIPRT_INF_F;
0315   #endif
0316   }
0317   EIGEN_DEVICE_FUNC
0318   static float quiet_NaN() {
0319   #if defined(EIGEN_CUDA_ARCH)
0320     return CUDART_NAN_F;
0321   #else
0322     return HIPRT_NAN_F;
0323   #endif
0324   }
0325 };
0326 template<> struct numeric_limits<double>
0327 {
0328   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0329   static double epsilon() { return __DBL_EPSILON__; }
0330   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0331   static double (max)() { return DBL_MAX; }
0332   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0333   static double (min)() { return DBL_MIN; }
0334   EIGEN_DEVICE_FUNC
0335   static double infinity() {
0336   #if defined(EIGEN_CUDA_ARCH)
0337     return CUDART_INF;
0338   #else
0339     return HIPRT_INF;
0340   #endif
0341   }
0342   EIGEN_DEVICE_FUNC
0343   static double quiet_NaN() {
0344   #if defined(EIGEN_CUDA_ARCH)
0345     return CUDART_NAN;
0346   #else
0347     return HIPRT_NAN;
0348   #endif
0349   }
0350 };
0351 template<> struct numeric_limits<int>
0352 {
0353   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0354   static int epsilon() { return 0; }
0355   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0356   static int (max)() { return INT_MAX; }
0357   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0358   static int (min)() { return INT_MIN; }
0359 };
0360 template<> struct numeric_limits<unsigned int>
0361 {
0362   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0363   static unsigned int epsilon() { return 0; }
0364   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0365   static unsigned int (max)() { return UINT_MAX; }
0366   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0367   static unsigned int (min)() { return 0; }
0368 };
0369 template<> struct numeric_limits<long>
0370 {
0371   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0372   static long epsilon() { return 0; }
0373   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0374   static long (max)() { return LONG_MAX; }
0375   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0376   static long (min)() { return LONG_MIN; }
0377 };
0378 template<> struct numeric_limits<unsigned long>
0379 {
0380   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0381   static unsigned long epsilon() { return 0; }
0382   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0383   static unsigned long (max)() { return ULONG_MAX; }
0384   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0385   static unsigned long (min)() { return 0; }
0386 };
0387 template<> struct numeric_limits<long long>
0388 {
0389   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0390   static long long epsilon() { return 0; }
0391   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0392   static long long (max)() { return LLONG_MAX; }
0393   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0394   static long long (min)() { return LLONG_MIN; }
0395 };
0396 template<> struct numeric_limits<unsigned long long>
0397 {
0398   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0399   static unsigned long long epsilon() { return 0; }
0400   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0401   static unsigned long long (max)() { return ULLONG_MAX; }
0402   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0403   static unsigned long long (min)() { return 0; }
0404 };
0405 template<> struct numeric_limits<bool>
0406 {
0407   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0408   static bool epsilon() { return false; }
0409   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0410   static bool (max)() { return true; }
0411   EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 
0412   static bool (min)() { return false; }
0413 };
0414 
0415 }
0416 
0417 #endif // defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
0418 
0419 /** \internal
0420   * A base class do disable default copy ctor and copy assignment operator.
0421   */
0422 class noncopyable
0423 {
0424   EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
0425   EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
0426 protected:
0427   EIGEN_DEVICE_FUNC noncopyable() {}
0428   EIGEN_DEVICE_FUNC ~noncopyable() {}
0429 };
0430 
0431 /** \internal
0432   * Provides access to the number of elements in the object of as a compile-time constant expression.
0433   * It "returns" RivetEigen::Dynamic if the size cannot be resolved at compile-time (default).
0434   *
0435   * Similar to std::tuple_size, but more general.
0436   *
0437   * It currently supports:
0438   *  - any types T defining T::SizeAtCompileTime
0439   *  - plain C arrays as T[N]
0440   *  - std::array (c++11)
0441   *  - some internal types such as SingleRange and AllRange
0442   *
0443   * The second template parameter eases SFINAE-based specializations.
0444   */
0445 template<typename T, typename EnableIf = void> struct array_size {
0446   enum { value = Dynamic };
0447 };
0448 
0449 template<typename T> struct array_size<T,typename internal::enable_if<((T::SizeAtCompileTime&0)==0)>::type> {
0450   enum { value = T::SizeAtCompileTime };
0451 };
0452 
0453 template<typename T, int N> struct array_size<const T (&)[N]> {
0454   enum { value = N };
0455 };
0456 template<typename T, int N> struct array_size<T (&)[N]> {
0457   enum { value = N };
0458 };
0459 
0460 #if EIGEN_HAS_CXX11
0461 template<typename T, std::size_t N> struct array_size<const std::array<T,N> > {
0462   enum { value = N };
0463 };
0464 template<typename T, std::size_t N> struct array_size<std::array<T,N> > {
0465   enum { value = N };
0466 };
0467 #endif
0468 
0469 /** \internal
0470   * Analogue of the std::size free function.
0471   * It returns the size of the container or view \a x of type \c T
0472   *
0473   * It currently supports:
0474   *  - any types T defining a member T::size() const
0475   *  - plain C arrays as T[N]
0476   *
0477   */
0478 template<typename T>
0479 EIGEN_CONSTEXPR Index size(const T& x) { return x.size(); }
0480 
0481 template<typename T,std::size_t N>
0482 EIGEN_CONSTEXPR Index size(const T (&) [N]) { return N; }
0483 
0484 /** \internal
0485   * Convenient struct to get the result type of a nullary, unary, binary, or
0486   * ternary functor.
0487   * 
0488   * Pre C++11:
0489   * Supports both a Func::result_type member and templated
0490   * Func::result<Func(ArgTypes...)>::type member.
0491   * 
0492   * If none of these members is provided, then the type of the first
0493   * argument is returned.
0494   * 
0495   * Post C++11:
0496   * This uses std::result_of. However, note the `type` member removes
0497   * const and converts references/pointers to their corresponding value type.
0498   */
0499 #if EIGEN_HAS_STD_INVOKE_RESULT
0500 template<typename T> struct result_of;
0501 
0502 template<typename F, typename... ArgTypes>
0503 struct result_of<F(ArgTypes...)> {
0504   typedef typename std::invoke_result<F, ArgTypes...>::type type1;
0505   typedef typename remove_all<type1>::type type;
0506 };
0507 #elif EIGEN_HAS_STD_RESULT_OF
0508 template<typename T> struct result_of {
0509   typedef typename std::result_of<T>::type type1;
0510   typedef typename remove_all<type1>::type type;
0511 };
0512 #else
0513 template<typename T> struct result_of { };
0514 
0515 struct has_none {int a[1];};
0516 struct has_std_result_type {int a[2];};
0517 struct has_tr1_result {int a[3];};
0518 
0519 template<typename Func, int SizeOf>
0520 struct nullary_result_of_select {};
0521 
0522 template<typename Func>
0523 struct nullary_result_of_select<Func, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
0524 
0525 template<typename Func>
0526 struct nullary_result_of_select<Func, sizeof(has_tr1_result)> {typedef typename Func::template result<Func()>::type type;};
0527 
0528 template<typename Func>
0529 struct result_of<Func()> {
0530     template<typename T>
0531     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
0532     template<typename T>
0533     static has_tr1_result         testFunctor(T const *, typename T::template result<T()>::type const * = 0);
0534     static has_none               testFunctor(...);
0535 
0536     // note that the following indirection is needed for gcc-3.3
0537     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
0538     typedef typename nullary_result_of_select<Func, FunctorType>::type type;
0539 };
0540 
0541 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
0542 struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
0543 
0544 template<typename Func, typename ArgType>
0545 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
0546 
0547 template<typename Func, typename ArgType>
0548 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
0549 
0550 template<typename Func, typename ArgType>
0551 struct result_of<Func(ArgType)> {
0552     template<typename T>
0553     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
0554     template<typename T>
0555     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
0556     static has_none               testFunctor(...);
0557 
0558     // note that the following indirection is needed for gcc-3.3
0559     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
0560     typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
0561 };
0562 
0563 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
0564 struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
0565 
0566 template<typename Func, typename ArgType0, typename ArgType1>
0567 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
0568 {typedef typename Func::result_type type;};
0569 
0570 template<typename Func, typename ArgType0, typename ArgType1>
0571 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
0572 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
0573 
0574 template<typename Func, typename ArgType0, typename ArgType1>
0575 struct result_of<Func(ArgType0,ArgType1)> {
0576     template<typename T>
0577     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
0578     template<typename T>
0579     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
0580     static has_none               testFunctor(...);
0581 
0582     // note that the following indirection is needed for gcc-3.3
0583     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
0584     typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
0585 };
0586 
0587 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)>
0588 struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
0589 
0590 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
0591 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)>
0592 {typedef typename Func::result_type type;};
0593 
0594 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
0595 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)>
0596 {typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;};
0597 
0598 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
0599 struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
0600     template<typename T>
0601     static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
0602     template<typename T>
0603     static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0);
0604     static has_none               testFunctor(...);
0605 
0606     // note that the following indirection is needed for gcc-3.3
0607     enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
0608     typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
0609 };
0610 
0611 #endif
0612 
0613 #if EIGEN_HAS_STD_INVOKE_RESULT
0614 template<typename F, typename... ArgTypes>
0615 struct invoke_result {
0616   typedef typename std::invoke_result<F, ArgTypes...>::type type1;
0617   typedef typename remove_all<type1>::type type;
0618 };
0619 #elif EIGEN_HAS_CXX11
0620 template<typename F, typename... ArgTypes>
0621 struct invoke_result {
0622   typedef typename result_of<F(ArgTypes...)>::type type1;
0623   typedef typename remove_all<type1>::type type;
0624 };
0625 #else
0626 template<typename F, typename ArgType0 = void, typename ArgType1 = void, typename ArgType2 = void>
0627 struct invoke_result {
0628   typedef typename result_of<F(ArgType0, ArgType1, ArgType2)>::type type1;
0629   typedef typename remove_all<type1>::type type;
0630 };
0631 
0632 template<typename F>
0633 struct invoke_result<F, void, void, void> {
0634   typedef typename result_of<F()>::type type1;
0635   typedef typename remove_all<type1>::type type;
0636 };
0637 
0638 template<typename F, typename ArgType0>
0639 struct invoke_result<F, ArgType0, void, void> {
0640   typedef typename result_of<F(ArgType0)>::type type1;
0641   typedef typename remove_all<type1>::type type;
0642 };
0643 
0644 template<typename F, typename ArgType0, typename ArgType1>
0645 struct invoke_result<F, ArgType0, ArgType1, void> {
0646   typedef typename result_of<F(ArgType0, ArgType1)>::type type1;
0647   typedef typename remove_all<type1>::type type;
0648 };
0649 #endif
0650 
0651 struct meta_yes { char a[1]; };
0652 struct meta_no  { char a[2]; };
0653 
0654 // Check whether T::ReturnType does exist
0655 template <typename T>
0656 struct has_ReturnType
0657 {
0658   template <typename C> static meta_yes testFunctor(C const *, typename C::ReturnType const * = 0);
0659   template <typename C> static meta_no  testFunctor(...);
0660 
0661   enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
0662 };
0663 
0664 template<typename T> const T* return_ptr();
0665 
0666 template <typename T, typename IndexType=Index>
0667 struct has_nullary_operator
0668 {
0669   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
0670   static meta_no testFunctor(...);
0671 
0672   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
0673 };
0674 
0675 template <typename T, typename IndexType=Index>
0676 struct has_unary_operator
0677 {
0678   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0);
0679   static meta_no testFunctor(...);
0680 
0681   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
0682 };
0683 
0684 template <typename T, typename IndexType=Index>
0685 struct has_binary_operator
0686 {
0687   template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0);
0688   static meta_no testFunctor(...);
0689 
0690   enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
0691 };
0692 
0693 /** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
0694   * Usage example: \code meta_sqrt<1023>::ret \endcode
0695   */
0696 template<int Y,
0697          int InfX = 0,
0698          int SupX = ((Y==1) ? 1 : Y/2),
0699          bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
0700                                 // use ?: instead of || just to shut up a stupid gcc 4.3 warning
0701 class meta_sqrt
0702 {
0703     enum {
0704       MidX = (InfX+SupX)/2,
0705       TakeInf = MidX*MidX > Y ? 1 : 0,
0706       NewInf = int(TakeInf) ? InfX : int(MidX),
0707       NewSup = int(TakeInf) ? int(MidX) : SupX
0708     };
0709   public:
0710     enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
0711 };
0712 
0713 template<int Y, int InfX, int SupX>
0714 class meta_sqrt<Y, InfX, SupX, true> { public:  enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
0715 
0716 
0717 /** \internal Computes the least common multiple of two positive integer A and B
0718   * at compile-time. 
0719   */
0720 template<int A, int B, int K=1, bool Done = ((A*K)%B)==0, bool Big=(A>=B)>
0721 struct meta_least_common_multiple
0722 {
0723   enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
0724 };
0725 template<int A, int B, int K, bool Done>
0726 struct meta_least_common_multiple<A,B,K,Done,false>
0727 {
0728   enum { ret = meta_least_common_multiple<B,A,K>::ret };
0729 };
0730 template<int A, int B, int K>
0731 struct meta_least_common_multiple<A,B,K,true,true>
0732 {
0733   enum { ret = A*K };
0734 };
0735 
0736 
0737 /** \internal determines whether the product of two numeric types is allowed and what the return type is */
0738 template<typename T, typename U> struct scalar_product_traits
0739 {
0740   enum { Defined = 0 };
0741 };
0742 
0743 // FIXME quick workaround around current limitation of result_of
0744 // template<typename Scalar, typename ArgType0, typename ArgType1>
0745 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
0746 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
0747 // };
0748 
0749 /** \internal Obtains a POD type suitable to use as storage for an object of a size
0750   * of at most Len bytes, aligned as specified by \c Align.
0751   */
0752 template<unsigned Len, unsigned Align>
0753 struct aligned_storage {
0754   struct type {
0755     EIGEN_ALIGN_TO_BOUNDARY(Align) unsigned char data[Len];
0756   };
0757 };
0758 
0759 } // end namespace internal
0760 
0761 namespace numext {
0762 
0763 #if defined(EIGEN_GPU_COMPILE_PHASE)
0764 template<typename T> EIGEN_DEVICE_FUNC   void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
0765 #else
0766 template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
0767 #endif
0768 
0769 #if defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
0770 using internal::device::numeric_limits;
0771 #else
0772 using std::numeric_limits;
0773 #endif
0774 
0775 // Integer division with rounding up.
0776 // T is assumed to be an integer type with a>=0, and b>0
0777 template<typename T>
0778 EIGEN_DEVICE_FUNC
0779 T div_ceil(const T &a, const T &b)
0780 {
0781   return (a+b-1) / b;
0782 }
0783 
0784 // The aim of the following functions is to bypass -Wfloat-equal warnings
0785 // when we really want a strict equality comparison on floating points.
0786 template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
0787 bool equal_strict(const X& x,const Y& y) { return x == y; }
0788 
0789 #if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
0790 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
0791 bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
0792 
0793 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
0794 bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
0795 #endif
0796 
0797 template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
0798 bool not_equal_strict(const X& x,const Y& y) { return x != y; }
0799 
0800 #if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
0801 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
0802 bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
0803 
0804 template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
0805 bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
0806 #endif
0807 
0808 } // end namespace numext
0809 
0810 } // end namespace RivetEigen
0811 
0812 #endif // EIGEN_META_H