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 | |