Itasca C++ Interface
Loading...
Searching...
No Matches
to.h
Go to the documentation of this file.
1#pragma once
7
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
120
121PUSHWARNING
122VSWARNING(5030)
123template <class T>
124[[clang::optnone]] constexpr const T safeDiv(const T num, const T denom, const T safeVal=0) {
125 if (abs(denom) < 1.0 and abs(num) >= std::numeric_limits<T>::max()*abs(denom)) return safeVal;
126 return num / denom;
127}
128
129[[clang::optnone]] static inline double safeSquare(const double v) {
130 static constexpr double maxRad = 1e150;
131 if (std::abs(v)>maxRad) return std::abs(v);
132 return v*v;
133}
134POPWARNING
135
136template <typename T>
138 template <typename U>
139 struct by {
140 using type = typename std::conditional<
141 std::is_const<U>::value,
142 typename std::add_const<T>::type,
143 typename std::remove_const<T>::type
144 >::type;
145 };
146};
147
149// 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 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
Definition to.h:139
Definition to.h:137