summaryrefslogtreecommitdiff
path: root/src/core/overflowsafe_type.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/overflowsafe_type.hpp')
-rw-r--r--src/core/overflowsafe_type.hpp45
1 files changed, 24 insertions, 21 deletions
diff --git a/src/core/overflowsafe_type.hpp b/src/core/overflowsafe_type.hpp
index 3f2948551..01400df0a 100644
--- a/src/core/overflowsafe_type.hpp
+++ b/src/core/overflowsafe_type.hpp
@@ -12,6 +12,8 @@
#include "math_func.hpp"
+#include <limits>
+
#ifdef __has_builtin
# if __has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_sub_overflow) && __has_builtin(__builtin_mul_overflow)
# define HAS_OVERFLOW_BUILTINS
@@ -23,13 +25,14 @@
* you multiply the maximum value with 2, or add 2, or subtract something from
* the minimum value, etc.
* @param T the type these integers are stored with.
- * @param T_MAX the maximum value for the integers.
- * @param T_MIN the minimum value for the integers.
*/
-template <class T, T T_MAX, T T_MIN>
+template <class T>
class OverflowSafeInt
{
private:
+ static constexpr T T_MAX = std::numeric_limits<T>::max();
+ static constexpr T T_MIN = std::numeric_limits<T>::min();
+
/** The non-overflow safe backend to store the value in. */
T m_value;
public:
@@ -175,31 +178,31 @@ public:
};
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly */
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
+template <class T> inline OverflowSafeInt<T> operator + (int64 a, OverflowSafeInt<T> b) { return b + a; }
+template <class T> inline OverflowSafeInt<T> operator - (int64 a, OverflowSafeInt<T> b) { return -b + a; }
+template <class T> inline OverflowSafeInt<T> operator * (int64 a, OverflowSafeInt<T> b) { return b * a; }
+template <class T> inline OverflowSafeInt<T> operator / (int64 a, OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly */
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
+template <class T> inline OverflowSafeInt<T> operator + (int a, OverflowSafeInt<T> b) { return b + a; }
+template <class T> inline OverflowSafeInt<T> operator - (int a, OverflowSafeInt<T> b) { return -b + a; }
+template <class T> inline OverflowSafeInt<T> operator * (int a, OverflowSafeInt<T> b) { return b * a; }
+template <class T> inline OverflowSafeInt<T> operator / (int a, OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
/* Sometimes we got uint operator OverflowSafeInt instead of vice versa. Handle that properly */
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
+template <class T> inline OverflowSafeInt<T> operator + (uint a, OverflowSafeInt<T> b) { return b + a; }
+template <class T> inline OverflowSafeInt<T> operator - (uint a, OverflowSafeInt<T> b) { return -b + a; }
+template <class T> inline OverflowSafeInt<T> operator * (uint a, OverflowSafeInt<T> b) { return b * a; }
+template <class T> inline OverflowSafeInt<T> operator / (uint a, OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly */
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + (uint)a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + (uint)a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * (uint)a; }
-template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
+template <class T> inline OverflowSafeInt<T> operator + (byte a, OverflowSafeInt<T> b) { return b + (uint)a; }
+template <class T> inline OverflowSafeInt<T> operator - (byte a, OverflowSafeInt<T> b) { return -b + (uint)a; }
+template <class T> inline OverflowSafeInt<T> operator * (byte a, OverflowSafeInt<T> b) { return b * (uint)a; }
+template <class T> inline OverflowSafeInt<T> operator / (byte a, OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
-typedef OverflowSafeInt<int64, INT64_MAX, INT64_MIN> OverflowSafeInt64;
-typedef OverflowSafeInt<int32, INT32_MAX, INT32_MIN> OverflowSafeInt32;
+typedef OverflowSafeInt<int64> OverflowSafeInt64;
+typedef OverflowSafeInt<int32> OverflowSafeInt32;
#undef HAS_OVERFLOW_BUILTINS