DGtal  1.0.0
NumberTraits.h
1 
17 #pragma once
18 
31 #if defined(NumberTraits_RECURSES)
32 #error Recursive header files inclusion detected in NumberTraits.h
33 #else // defined(NumberTraits_RECURSES)
34 
35 #define NumberTraits_RECURSES
36 
37 #if !defined NumberTraits_h
38 
39 #define NumberTraits_h
40 
42 // Inclusions
43 #include <type_traits>
44 #include <limits>
45 
46 #include <boost/call_traits.hpp>
47 
48 #include "DGtal/base/Common.h"
50 
51 namespace DGtal
52 {
54  enum BoundEnum {BOUNDED = 0, UNBOUNDED = 1, BOUND_UNKNOWN = 2};
55 
57  enum SignEnum {SIGNED = 0, UNSIGNED = 1, SIGN_UNKNOWN = 2};
58 
59 
61 // template class NumberTraits and NumberTraitsImpl
62 
80  template <typename T, typename Enable = void>
82  {
83  // ----------------------- Associated types ------------------------------
86  typedef TagUnknown IsSigned;
89  typedef T SignedVersion;
90  typedef T UnsignedVersion;
91  typedef T ReturnType;
92 
96  typedef typename boost::call_traits<T>::param_type ParamType;
97 
98 
100  static const T ZERO = T(0);
101 
103  static const T ONE = T(1);
104 
106  static ReturnType zero();
107 
109  static ReturnType one();
110 
115  static ReturnType min();
116 
121  static ReturnType max();
122 
127  static unsigned int digits();
128 
133  static BoundEnum isBounded();
134 
139  static SignEnum isSigned();
140 
145  static DGtal::int64_t castToInt64_t(const T & aT)
146  {
147  return static_cast<DGtal::int64_t>(aT);
148  }
149 
154  static double castToDouble(const T & aT)
155  {
156  return static_cast<double>(aT);
157  }
163  static bool even( ParamType aT )
164  {
165  return ( aT & ONE ) == ZERO;
166  }
167 
173  static bool odd( ParamType aT )
174  {
175  return ( aT & ONE ) != ZERO;
176  }
177 
178  }; // end of class NumberTraitsImpl
179 
180  // Definition of the static attributes in order to allow ODR-usage.
181  template <typename T, typename Enable> const T NumberTraitsImpl<T, Enable>::ZERO;
182  template <typename T, typename Enable> const T NumberTraitsImpl<T, Enable>::ONE;
183 
184  // Some custom structs to factorize the code.
185  namespace details
186  {
187 
189  template <bool Value>
190  struct BoolToTag
191  {
193  };
194 
195  template <>
196  struct BoolToTag<false>
197  {
199  };
200 
202  template <typename T>
204  {
205  private:
206  using NL = std::numeric_limits<T>;
207 
208  public:
209  // ----------------------- Associated types ------------------------------
215 
216  using ReturnType = T;
217 
221  using ParamType = typename boost::call_traits<T>::param_type;
222 
224  static constexpr T ZERO = T(0);
225 
227  static constexpr T ONE = T(1);
228 
230  static inline constexpr
231  ReturnType zero() noexcept
232  {
233  return ZERO;
234  }
235 
237  static inline constexpr
238  ReturnType one() noexcept
239  {
240  return ONE;
241  }
242 
244  static inline constexpr
245  ReturnType min() noexcept
246  {
247  return NL::min();
248  }
249 
251  static inline constexpr
252  ReturnType max() noexcept
253  {
254  return NL::max();
255  }
256 
258  static inline constexpr
259  unsigned int digits() noexcept
260  {
261  return static_cast<unsigned int>(NL::digits);
262  }
263 
268  static inline constexpr
269  BoundEnum isBounded() noexcept
270  {
271  return NL::is_bounded ? BOUNDED : UNBOUNDED;
272  }
273 
278  static inline constexpr
279  SignEnum isSigned() noexcept
280  {
281  return NL::is_signed ? SIGNED : UNSIGNED;
282  }
283 
288  static inline constexpr
289  DGtal::int64_t castToInt64_t(const T & aT) noexcept
290  {
291  return static_cast<DGtal::int64_t>(aT);
292  }
293 
298  static inline constexpr
299  double castToDouble(const T & aT) noexcept
300  {
301  return static_cast<double>(aT);
302  }
303 
309  static inline constexpr
310  bool even( ParamType aT ) noexcept
311  {
312  return ( aT & ONE ) == ZERO;
313  }
314 
320  static inline constexpr
321  bool odd( ParamType aT ) noexcept
322  {
323  return ( aT & ONE ) != ZERO;
324  }
325 
326  };
327 
328  // Definition of the static attributes in order to allow ODR-usage.
329  template <typename T> constexpr T NumberTraitsImplFundamental<T>::ZERO;
330  template <typename T> constexpr T NumberTraitsImplFundamental<T>::ONE;
331 
332  } // namespace details
333 
335  template <typename T>
336  struct NumberTraitsImpl<T, typename std::enable_if<std::is_integral<T>::value>::type>
338  {
339  private:
341 
342  public:
343  using SignedVersion = typename std::make_signed<T>::type;
344  using UnsignedVersion = typename std::make_unsigned<T>::type;
345 
351  static inline constexpr
352  bool even( typename NTIF::ParamType aT ) noexcept
353  {
354  return ( aT & NTIF::ONE ) == NTIF::ZERO;
355  }
356 
362  static inline constexpr
363  bool odd( typename NTIF::ParamType aT ) noexcept
364  {
365  return ( aT & NTIF::ONE ) != NTIF::ZERO;
366  }
367 
368  }; // end of class NumberTraitsImpl
369 
371  template <typename T>
372  struct NumberTraitsImpl<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
374  {
375  using SignedVersion = T;
376  using UnsignedVersion = T;
377  }; // end of class NumberTraitsImpl
378 
379 #ifdef WITH_BIGINTEGER
380 
386  template <typename Enable>
388  {
389  typedef TagTrue IsIntegral;
390  typedef TagFalse IsBounded;
391  typedef TagTrue IsUnsigned;
392  typedef TagTrue IsSigned;
394 
398 
402  typedef typename boost::call_traits<BigInteger>::param_type ParamType;
403 
405  static const DGtal::BigInteger ZERO;
406 
408  static const DGtal::BigInteger ONE;
409 
411  static inline
412  ReturnType zero() noexcept
413  {
414  return ZERO;
415  }
416 
418  static inline
419  ReturnType one() noexcept
420  {
421  return ONE;
422  }
423 
425  static inline
426  ReturnType min() noexcept
427  {
428  FATAL_ERROR_MSG(false, "UnBounded interger type does not support min() function");
429  return ZERO;
430  }
431 
433  static inline
434  ReturnType max() noexcept
435  {
436  FATAL_ERROR_MSG(false, "UnBounded interger type does not support max() function");
437  return ZERO;
438  }
439 
441  static inline
442  unsigned int digits() noexcept
443  {
444  FATAL_ERROR_MSG(false, "UnBounded interger type does not support digits() function");
445  return 0;
446  }
447 
452  static inline
453  BoundEnum isBounded() noexcept
454  {
455  return UNBOUNDED;
456  }
457 
462  static inline
463  SignEnum isSigned() noexcept
464  {
465  return SIGNED;
466  }
467 
472  static inline
474  {
475  return aT.get_si();
476  }
477 
482  static inline
483  double castToDouble(const DGtal::BigInteger & aT) noexcept
484  {
485  return aT.get_d();
486  }
487 
493  static inline
494  bool even( ParamType aT ) noexcept
495  {
496  return mpz_even_p( aT.get_mpz_t() );
497  }
498 
504  static inline
505  bool odd( ParamType aT ) noexcept
506  {
507  return mpz_odd_p( aT.get_mpz_t() );
508  }
509  }; // end of class NumberTraits<DGtal::BigInteger>.
510 
511  // Definition of the static attributes in order to allow ODR-usage.
512  template <typename Enable> const DGtal::BigInteger NumberTraitsImpl<DGtal::BigInteger, Enable>::ZERO = 0;
513  template <typename Enable> const DGtal::BigInteger NumberTraitsImpl<DGtal::BigInteger, Enable>::ONE = 1;
514 #endif
515 
530  template <typename T>
532  : NumberTraitsImpl<typename std::decay<T>::type>
533  {
534  };
535 
537 
538  template<class A, class B>
540  {
542  };
543 
544  template<>
546  {
548  };
549 
550 } // namespace DGtal
551 
552 #endif // !defined NumberTraits_h
553 
554 #undef NumberTraits_RECURSES
555 #endif // else defined(NumberTraits_RECURSES)
static ReturnType one()
Return the one of this integer.
static DGtal::int64_t castToInt64_t(const DGtal::BigInteger &aT) noexcept
Cast method to DGtal::int64_t (for I/O or board export uses only).
Definition: NumberTraits.h:473
static ReturnType one() noexcept
Return the one of this integer.
Definition: NumberTraits.h:419
static ReturnType max()
Return the maximum possible value for this type of integer or ZERO if not bounded or unknown.
static double castToDouble(const DGtal::BigInteger &aT) noexcept
Cast method to double (for I/O or board export uses only).
Definition: NumberTraits.h:483
static constexpr ReturnType max() noexcept
Return the maximum possible value for this type of number.
Definition: NumberTraits.h:252
NumberTraits common part for fundamental integer and floating-point types.
Definition: NumberTraits.h:203
TagUnknown IsIntegral
Is the number of integral type.
Definition: NumberTraits.h:87
T SignedVersion
Alias to the signed version of a floating-point type (aka itself).
Definition: NumberTraits.h:375
DGtal::BigInteger ReturnType
Alias to the type that should be used as return type.
Definition: NumberTraits.h:397
static DGtal::int64_t castToInt64_t(const T &aT)
Cast method to DGtal::int64_t (for I/O or board export uses only).
Definition: NumberTraits.h:145
static double castToDouble(const T &aT)
Cast method to double (for I/O or board export uses only).
Definition: NumberTraits.h:154
static ReturnType max() noexcept
Return the maximum possible value (trigger an error since BitInteger is unbounded).
Definition: NumberTraits.h:434
typename BoolToTag< NL::is_integer >::type IsIntegral
Is the number of integral type.
Definition: NumberTraits.h:213
static unsigned int digits()
Return the number of significant binary digits for this integer type, or 0 if unbounded or unknown.
TagTrue IsUnsigned
A BigInteger can be signed and unsigned.
Definition: NumberTraits.h:391
static ReturnType min()
Return the minimum possible value for this type of integer or ONE if not bounded or unknown.
T UnsignedVersion
Alias to the unsigned version of the number type.
Definition: NumberTraits.h:90
static unsigned int digits() noexcept
Return the number of significant binary digits (trigger an error since BitInteger is unbounded).
Definition: NumberTraits.h:442
static constexpr bool even(ParamType aT) noexcept
Check the parity of a number.
Definition: NumberTraits.h:310
static constexpr bool even(typename NTIF::ParamType aT) noexcept
Check the parity of a number.
Definition: NumberTraits.h:352
SignEnum
Sign type of a number.
Definition: NumberTraits.h:57
TagFalse IsBounded
A BigInteger is not bounded.
Definition: NumberTraits.h:390
typename std::make_signed< T >::type SignedVersion
Alias to the signed version of the number type.
Definition: NumberTraits.h:343
TagTrue IsIntegral
A BigInteger is of integral type.
Definition: NumberTraits.h:389
static bool odd(ParamType aT) noexcept
Check the parity of a number.
Definition: NumberTraits.h:505
static constexpr double castToDouble(const T &aT) noexcept
Cast method to double (for I/O or board export uses only).
Definition: NumberTraits.h:299
typename BoolToTag< NL::is_bounded >::type IsBounded
Is the number bounded.
Definition: NumberTraits.h:210
boost::call_traits< T >::param_type ParamType
Defines a type that represents the "best" way to pass a parameter of type T to a function.
Definition: NumberTraits.h:96
mpz_class BigInteger
Multi-precision integer with GMP implementation.
Definition: BasicTypes.h:79
static constexpr unsigned int digits() noexcept
Return the number of significant binary digits for this type of number.
Definition: NumberTraits.h:259
static constexpr T ZERO
Constant Zero.
Definition: NumberTraits.h:224
TagFalse IsSpecialized
Is that a number type with specific traits.
Definition: NumberTraits.h:88
static ReturnType zero() noexcept
Return the zero of this integer.
Definition: NumberTraits.h:412
static bool even(ParamType aT)
Check the parity of a number.
Definition: NumberTraits.h:163
static constexpr SignEnum isSigned() noexcept
Return the sign type of the number.
Definition: NumberTraits.h:279
static ReturnType zero()
Return the zero of this integer.
static SignEnum isSigned()
Return the sign type of the number.
Convert a boolean to the corresponding DGtal tag (TagTrue or TagFalse).
Definition: NumberTraits.h:190
T ReturnType
Alias to the type that should be used as return type.
Definition: NumberTraits.h:216
typename std::make_unsigned< T >::type UnsignedVersion
Alias to the unsigned version of the number type.
Definition: NumberTraits.h:344
std::numeric_limits< T > NL
Type alias to std::numeric_limits.
Definition: NumberTraits.h:206
Aim: The traits class for all models of Cinteger.
Definition: NumberTraits.h:531
TagUnknown IsBounded
Is the number bounded.
Definition: NumberTraits.h:84
TagTrue IsSpecialized
Is that a number type with specific traits.
Definition: NumberTraits.h:393
Aim: The traits class for all models of Cinteger (implementation)
Definition: NumberTraits.h:81
BoundEnum
Bounding type of a number.
Definition: NumberTraits.h:54
TagTrue IsSigned
a BigInteger can be signed and unsigned.
Definition: NumberTraits.h:392
static constexpr ReturnType min() noexcept
Return the minimum possible value for this type of number.
Definition: NumberTraits.h:245
Warning_promote_trait_not_specialized_for_this_case promote_t
Definition: NumberTraits.h:541
static const T ONE
Constant One.
Definition: NumberTraits.h:103
DGtal is the top-level namespace which contains all DGtal functions and types.
typename BoolToTag<!NL::is_signed >::type IsUnsigned
Is the number unsigned.
Definition: NumberTraits.h:211
static const T ZERO
Constant Zero.
Definition: NumberTraits.h:100
static ReturnType min() noexcept
Return the minimum possible value (trigger an error since BitInteger is unbounded).
Definition: NumberTraits.h:426
int max(int a, int b)
static constexpr ReturnType one() noexcept
Return the one of this integer.
Definition: NumberTraits.h:238
static constexpr T ONE
Constant One.
Definition: NumberTraits.h:227
T SignedVersion
Alias to the signed version of the number type.
Definition: NumberTraits.h:89
TagUnknown IsSigned
Is the number signed.
Definition: NumberTraits.h:86
static constexpr BoundEnum isBounded() noexcept
Return the bounding type of the number.
Definition: NumberTraits.h:269
static constexpr bool odd(ParamType aT) noexcept
Check the parity of a number.
Definition: NumberTraits.h:321
static const DGtal::BigInteger ONE
Constant One.
Definition: NumberTraits.h:408
T UnsignedVersion
Alias to the unsigned version of a floating-point type (aka itself).
Definition: NumberTraits.h:376
static BoundEnum isBounded() noexcept
Return the bounding type of the number.
Definition: NumberTraits.h:453
static constexpr bool odd(typename NTIF::ParamType aT) noexcept
Check the parity of a number.
Definition: NumberTraits.h:363
static constexpr ReturnType zero() noexcept
Return the zero of this integer.
Definition: NumberTraits.h:231
DGtal::BigInteger SignedVersion
Alias to the signed version of a BigInteger (aka a BigInteger).
Definition: NumberTraits.h:395
static constexpr DGtal::int64_t castToInt64_t(const T &aT) noexcept
Cast method to DGtal::int64_t (for I/O or board export uses only).
Definition: NumberTraits.h:289
boost::int32_t int32_t
signed 32-bit integer.
Definition: BasicTypes.h:72
static SignEnum isSigned() noexcept
Return the sign type of the number.
Definition: NumberTraits.h:463
typename details::NumberTraitsImplFundamental< T > NTIF
Internal type alias to avoid repetitions.
Definition: NumberTraits.h:340
typename BoolToTag< NL::is_signed >::type IsSigned
Is the number signed.
Definition: NumberTraits.h:212
static const DGtal::BigInteger ZERO
Constant Zero.
Definition: NumberTraits.h:405
boost::call_traits< BigInteger >::param_type ParamType
Defines a type that represents the "best" way to pass a parameter of type T to a function.
Definition: NumberTraits.h:402
boost::int64_t int64_t
signed 94-bit integer.
Definition: BasicTypes.h:74
static bool even(ParamType aT) noexcept
Check the parity of a number.
Definition: NumberTraits.h:494
static bool odd(ParamType aT)
Check the parity of a number.
Definition: NumberTraits.h:173
TagUnknown IsUnsigned
Is the number unsigned.
Definition: NumberTraits.h:85
DGtal::BigInteger UnsignedVersion
Alias to the unsigned version of a BigInteger (aka a BigInteger).
Definition: NumberTraits.h:396
static BoundEnum isBounded()
Return the bounding type of the number.
typename boost::call_traits< T >::param_type ParamType
Defines a type that represents the "best" way to pass a parameter of type T to a function.
Definition: NumberTraits.h:221
T ReturnType
Alias to the type that should be used as return type.
Definition: NumberTraits.h:91