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(__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 #if EIGEN_HAS_CXX11 113 using std::make_unsigned; 114 #else 115 // TODO: Possibly improve this implementation of make_unsigned. 116 // It is currently used only by 117 // template<typename Scalar> struct random_default_impl<Scalar, false, true>. 118 template<typename> struct make_unsigned; 119 template<> struct make_unsigned<char> { typedef unsigned char type; }; 120 template<> struct make_unsigned<signed char> { typedef unsigned char type; }; 121 template<> struct make_unsigned<unsigned char> { typedef unsigned char type; }; 122 template<> struct make_unsigned<signed short> { typedef unsigned short type; }; 123 template<> struct make_unsigned<unsigned short> { typedef unsigned short type; }; 124 template<> struct make_unsigned<signed int> { typedef unsigned int type; }; 125 template<> struct make_unsigned<unsigned int> { typedef unsigned int type; }; 126 template<> struct make_unsigned<signed long> { typedef unsigned long type; }; 127 template<> struct make_unsigned<unsigned long> { typedef unsigned long type; }; 128 #if EIGEN_COMP_MSVC 129 template<> struct make_unsigned<signed __int64> { typedef unsigned __int64 type; }; 130 template<> struct make_unsigned<unsigned __int64> { typedef unsigned __int64 type; }; 131 #endif 132 #endif 133 134 template <typename T> struct add_const { typedef const T type; }; 135 template <typename T> struct add_const<T&> { typedef T& type; }; 136 137 template <typename T> struct is_const { enum { value = 0 }; }; 138 template <typename T> struct is_const<T const> { enum { value = 1 }; }; 139 140 template<typename T> struct add_const_on_value_type { typedef const T type; }; 141 template<typename T> struct add_const_on_value_type<T&> { typedef T const& type; }; 142 template<typename T> struct add_const_on_value_type<T*> { typedef T const* type; }; 143 template<typename T> struct add_const_on_value_type<T* const> { typedef T const* const type; }; 144 template<typename T> struct add_const_on_value_type<T const* const> { typedef T const* const type; }; 145 146 147 template<typename From, typename To> 148 struct is_convertible_impl 149 { 150 private: 151 struct any_conversion 152 { 153 template <typename T> any_conversion(const volatile T&); 154 template <typename T> any_conversion(T&); 155 }; 156 struct yes {int a[1];}; 157 struct no {int a[2];}; 158 159 static yes test(const To&, int); 160 static no test(any_conversion, ...); 161 162 public: 163 static From ms_from; 164 #ifdef __INTEL_COMPILER 165 #pragma warning push 166 #pragma warning ( disable : 2259 ) 167 #endif 168 enum { value = sizeof(test(ms_from, 0))==sizeof(yes) }; 169 #ifdef __INTEL_COMPILER 170 #pragma warning pop 171 #endif 172 }; 173 174 template<typename From, typename To> 175 struct is_convertible 176 { 177 enum { value = is_convertible_impl<typename remove_all<From>::type, 178 typename remove_all<To >::type>::value }; 179 }; 180 181 /** \internal Allows to enable/disable an overload 182 * according to a compile time condition. 183 */ 184 template<bool Condition, typename T=void> struct enable_if; 185 186 template<typename T> struct enable_if<true,T> 187 { typedef T type; }; 188 189 #if defined(__CUDA_ARCH__) 190 #if !defined(__FLT_EPSILON__) 191 #define __FLT_EPSILON__ FLT_EPSILON 192 #define __DBL_EPSILON__ DBL_EPSILON 193 #endif 194 195 namespace device { 196 197 template<typename T> struct numeric_limits 198 { 199 EIGEN_DEVICE_FUNC 200 static T epsilon() { return 0; } 201 static T (max)() { assert(false && "Highest not supported for this type"); } 202 static T (min)() { assert(false && "Lowest not supported for this type"); } 203 static T infinity() { assert(false && "Infinity not supported for this type"); } 204 static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); } 205 }; 206 template<> struct numeric_limits<float> 207 { 208 EIGEN_DEVICE_FUNC 209 static float epsilon() { return __FLT_EPSILON__; } 210 EIGEN_DEVICE_FUNC 211 static float (max)() { return CUDART_MAX_NORMAL_F; } 212 EIGEN_DEVICE_FUNC 213 static float (min)() { return FLT_MIN; } 214 EIGEN_DEVICE_FUNC 215 static float infinity() { return CUDART_INF_F; } 216 EIGEN_DEVICE_FUNC 217 static float quiet_NaN() { return CUDART_NAN_F; } 218 }; 219 template<> struct numeric_limits<double> 220 { 221 EIGEN_DEVICE_FUNC 222 static double epsilon() { return __DBL_EPSILON__; } 223 EIGEN_DEVICE_FUNC 224 static double (max)() { return DBL_MAX; } 225 EIGEN_DEVICE_FUNC 226 static double (min)() { return DBL_MIN; } 227 EIGEN_DEVICE_FUNC 228 static double infinity() { return CUDART_INF; } 229 EIGEN_DEVICE_FUNC 230 static double quiet_NaN() { return CUDART_NAN; } 231 }; 232 template<> struct numeric_limits<int> 233 { 234 EIGEN_DEVICE_FUNC 235 static int epsilon() { return 0; } 236 EIGEN_DEVICE_FUNC 237 static int (max)() { return INT_MAX; } 238 EIGEN_DEVICE_FUNC 239 static int (min)() { return INT_MIN; } 240 }; 241 template<> struct numeric_limits<unsigned int> 242 { 243 EIGEN_DEVICE_FUNC 244 static unsigned int epsilon() { return 0; } 245 EIGEN_DEVICE_FUNC 246 static unsigned int (max)() { return UINT_MAX; } 247 EIGEN_DEVICE_FUNC 248 static unsigned int (min)() { return 0; } 249 }; 250 template<> struct numeric_limits<long> 251 { 252 EIGEN_DEVICE_FUNC 253 static long epsilon() { return 0; } 254 EIGEN_DEVICE_FUNC 255 static long (max)() { return LONG_MAX; } 256 EIGEN_DEVICE_FUNC 257 static long (min)() { return LONG_MIN; } 258 }; 259 template<> struct numeric_limits<unsigned long> 260 { 261 EIGEN_DEVICE_FUNC 262 static unsigned long epsilon() { return 0; } 263 EIGEN_DEVICE_FUNC 264 static unsigned long (max)() { return ULONG_MAX; } 265 EIGEN_DEVICE_FUNC 266 static unsigned long (min)() { return 0; } 267 }; 268 template<> struct numeric_limits<long long> 269 { 270 EIGEN_DEVICE_FUNC 271 static long long epsilon() { return 0; } 272 EIGEN_DEVICE_FUNC 273 static long long (max)() { return LLONG_MAX; } 274 EIGEN_DEVICE_FUNC 275 static long long (min)() { return LLONG_MIN; } 276 }; 277 template<> struct numeric_limits<unsigned long long> 278 { 279 EIGEN_DEVICE_FUNC 280 static unsigned long long epsilon() { return 0; } 281 EIGEN_DEVICE_FUNC 282 static unsigned long long (max)() { return ULLONG_MAX; } 283 EIGEN_DEVICE_FUNC 284 static unsigned long long (min)() { return 0; } 285 }; 286 287 } 288 289 #endif 290 291 /** \internal 292 * A base class do disable default copy ctor and copy assignement operator. 293 */ 294 class noncopyable 295 { 296 EIGEN_DEVICE_FUNC noncopyable(const noncopyable&); 297 EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&); 298 protected: 299 EIGEN_DEVICE_FUNC noncopyable() {} 300 EIGEN_DEVICE_FUNC ~noncopyable() {} 301 }; 302 303 /** \internal 304 * Convenient struct to get the result type of a unary or binary functor. 305 * 306 * It supports both the current STL mechanism (using the result_type member) as well as 307 * upcoming next STL generation (using a templated result member). 308 * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack. 309 */ 310 #if EIGEN_HAS_STD_RESULT_OF 311 template<typename T> struct result_of { 312 typedef typename std::result_of<T>::type type1; 313 typedef typename remove_all<type1>::type type; 314 }; 315 #else 316 template<typename T> struct result_of { }; 317 318 struct has_none {int a[1];}; 319 struct has_std_result_type {int a[2];}; 320 struct has_tr1_result {int a[3];}; 321 322 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)> 323 struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;}; 324 325 template<typename Func, typename ArgType> 326 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;}; 327 328 template<typename Func, typename ArgType> 329 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;}; 330 331 template<typename Func, typename ArgType> 332 struct result_of<Func(ArgType)> { 333 template<typename T> 334 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 335 template<typename T> 336 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0); 337 static has_none testFunctor(...); 338 339 // note that the following indirection is needed for gcc-3.3 340 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 341 typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type; 342 }; 343 344 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)> 345 struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;}; 346 347 template<typename Func, typename ArgType0, typename ArgType1> 348 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)> 349 {typedef typename Func::result_type type;}; 350 351 template<typename Func, typename ArgType0, typename ArgType1> 352 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)> 353 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;}; 354 355 template<typename Func, typename ArgType0, typename ArgType1> 356 struct result_of<Func(ArgType0,ArgType1)> { 357 template<typename T> 358 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 359 template<typename T> 360 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0); 361 static has_none testFunctor(...); 362 363 // note that the following indirection is needed for gcc-3.3 364 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 365 typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type; 366 }; 367 368 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)> 369 struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;}; 370 371 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2> 372 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)> 373 {typedef typename Func::result_type type;}; 374 375 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2> 376 struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)> 377 {typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;}; 378 379 template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2> 380 struct result_of<Func(ArgType0,ArgType1,ArgType2)> { 381 template<typename T> 382 static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); 383 template<typename T> 384 static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0); 385 static has_none testFunctor(...); 386 387 // note that the following indirection is needed for gcc-3.3 388 enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))}; 389 typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type; 390 }; 391 #endif 392 393 struct meta_yes { char a[1]; }; 394 struct meta_no { char a[2]; }; 395 396 // Check whether T::ReturnType does exist 397 template <typename T> 398 struct has_ReturnType 399 { 400 template <typename C> static meta_yes testFunctor(typename C::ReturnType const *); 401 template <typename C> static meta_no testFunctor(...); 402 403 enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) }; 404 }; 405 406 template<typename T> const T* return_ptr(); 407 408 template <typename T, typename IndexType=Index> 409 struct has_nullary_operator 410 { 411 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0); 412 static meta_no testFunctor(...); 413 414 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) }; 415 }; 416 417 template <typename T, typename IndexType=Index> 418 struct has_unary_operator 419 { 420 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0); 421 static meta_no testFunctor(...); 422 423 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) }; 424 }; 425 426 template <typename T, typename IndexType=Index> 427 struct has_binary_operator 428 { 429 template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0); 430 static meta_no testFunctor(...); 431 432 enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) }; 433 }; 434 435 /** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer. 436 * Usage example: \code meta_sqrt<1023>::ret \endcode 437 */ 438 template<int Y, 439 int InfX = 0, 440 int SupX = ((Y==1) ? 1 : Y/2), 441 bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) > 442 // use ?: instead of || just to shut up a stupid gcc 4.3 warning 443 class meta_sqrt 444 { 445 enum { 446 MidX = (InfX+SupX)/2, 447 TakeInf = MidX*MidX > Y ? 1 : 0, 448 NewInf = int(TakeInf) ? InfX : int(MidX), 449 NewSup = int(TakeInf) ? int(MidX) : SupX 450 }; 451 public: 452 enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret }; 453 }; 454 455 template<int Y, int InfX, int SupX> 456 class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; 457 458 459 /** \internal Computes the least common multiple of two positive integer A and B 460 * at compile-time. It implements a naive algorithm testing all multiples of A. 461 * It thus works better if A>=B. 462 */ 463 template<int A, int B, int K=1, bool Done = ((A*K)%B)==0> 464 struct meta_least_common_multiple 465 { 466 enum { ret = meta_least_common_multiple<A,B,K+1>::ret }; 467 }; 468 template<int A, int B, int K> 469 struct meta_least_common_multiple<A,B,K,true> 470 { 471 enum { ret = A*K }; 472 }; 473 474 /** \internal determines whether the product of two numeric types is allowed and what the return type is */ 475 template<typename T, typename U> struct scalar_product_traits 476 { 477 enum { Defined = 0 }; 478 }; 479 480 // FIXME quick workaround around current limitation of result_of 481 // template<typename Scalar, typename ArgType0, typename ArgType1> 482 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> { 483 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type; 484 // }; 485 486 } // end namespace internal 487 488 namespace numext { 489 490 #if defined(__CUDA_ARCH__) 491 template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; } 492 #else 493 template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); } 494 #endif 495 496 #if defined(__CUDA_ARCH__) 497 using internal::device::numeric_limits; 498 #else 499 using std::numeric_limits; 500 #endif 501 502 // Integer division with rounding up. 503 // T is assumed to be an integer type with a>=0, and b>0 504 template<typename T> 505 T div_ceil(const T &a, const T &b) 506 { 507 return (a+b-1) / b; 508 } 509 510 // The aim of the following functions is to bypass -Wfloat-equal warnings 511 // when we really want a strict equality comparison on floating points. 512 template<typename X, typename Y> EIGEN_STRONG_INLINE 513 bool equal_strict(const X& x,const Y& y) { return x == y; } 514 515 template<> EIGEN_STRONG_INLINE 516 bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); } 517 518 template<> EIGEN_STRONG_INLINE 519 bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); } 520 521 template<typename X, typename Y> EIGEN_STRONG_INLINE 522 bool not_equal_strict(const X& x,const Y& y) { return x != y; } 523 524 template<> EIGEN_STRONG_INLINE 525 bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); } 526 527 template<> EIGEN_STRONG_INLINE 528 bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); } 529 530 } // end namespace numext 531 532 } // end namespace Eigen 533 534 #endif // EIGEN_META_H 535