Itasca C++ Interface
to.h
Go to the documentation of this file.
1 #pragma once
8 #include "limit.h"
9 #include <cassert>
10 #include <stdexcept>
11 
12 #ifdef _WIN32
13 # ifdef __INTEL_COMPILER
14 # pragma warning(disable:2557)
15 # else
16 # pragma warning(disable:4018)
17 # endif
18 #endif
19 
27 template <class D,class T>
28 constexpr D to(const T &t) {
29  // SIMPLER VERSION - Just casts back in debug and checks value is the original
30  D ret = static_cast<D>(t);
31 #ifdef _DEBUG
32  T back = static_cast<T>(ret);
33  if (back != t)
34  throw std::runtime_error("Numeric Conversion error.");
35 #endif
36  return ret;
37 }
38 
39 // Checking to see if you get the same value back does not work if floating point is used (rounding).
40 // Now use a different template override for double/float.
41 template <>
42 inline constexpr float to(const double& t) {
43  float f = static_cast<float>(t);
44 #ifdef _DEBUG
45  double back = f;
46  if (back != t)
47  throw std::runtime_error("Numeric Conversion error.");
48 #endif
49  return f;
50 }
51 template <class D>
52 constexpr D to(const double& d) {
53 #ifdef _DEBUG
54  if (d > static_cast<double>(limits<D>::max()))
55  throw std::runtime_error("Numeric Conversion error.");
56  if (d < static_cast<double>(limits<D>::lowest()))
57  throw std::runtime_error("Numeric Conversion error.");
58 #endif
59  // SIMPLER VERSION - Just casts back in debug and checks value is the original
60  D ret = static_cast<D>(d);
61  return ret;
62 }
63 template <class D>
64 D constexpr to(const float &d) {
65 #ifdef _DEBUG
66  if (d > static_cast<float>(limits<D>::max()))
67  throw std::runtime_error("Numeric Conversion error.");
68  if (d < static_cast<float>(limits<D>::lowest()))
69  throw std::runtime_error("Numeric Conversion error.");
70 #endif
71  D ret = static_cast<D>(d);
72  return ret;
73 }
74 template <>
75 inline constexpr double to(const float &d) {
76  double ret = static_cast<double>(d);
77  return ret;
78 }
79 #ifdef _WIN32
80 # pragma warning(default:4018)
81 #endif
82 
88 template <class D,class T>
89 D *check_cast(T *t) {
90  D *d = (D *)t;
91 #ifdef _DEBUG
92  D *d2 = dynamic_cast<D *>(t);
93  assert(d2==d);
94 #endif
95  return d;
96 }
97 
103 template <class D,class T>
104 const D *check_cast(const T *t) {
105  const D *d = (const D *)t;
106  assert(dynamic_cast<const D *>(t)==d);
107  return d;
108 }
109 
116 template <class T>
117 constexpr const T safeDiv(const T num,const T denom) {
118  if (!denom) return num;
119  return num/denom;
120 }
121 
123 // EoF
debug checked shorthand for std::numeric_limits<T>::
Definition: limit.h:25
constexpr const T safeDiv(const T num, const T denom)
This function provids "safe" division operation, checks explicitly for zero.
Definition: to.h:117
constexpr D to(const T &t)
This template function serves as an alternative to static_cast<T>().
Definition: to.h:28
D * check_cast(T *t)
This template function serves as a fast alternative to dynamic_cast, when you know the base offset is...
Definition: to.h:89
std::numeric_limits shorthand, with debug overflow checking