Itasca C++ Interface
Loading...
Searching...
No Matches
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
27template <class D,class T>
28constexpr 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.
41template <>
42inline 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}
51template <class D>
52constexpr 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}
63template <class D>
64D 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}
74template <>
75inline 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
88template <class D,class T>
89D *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
103template <class D,class T>
104const 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
116template <class T>
117constexpr 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
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
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
std::numeric_limits shorthand, with debug overflow checking