summaryrefslogtreecommitdiff
path: root/include/o3tl/safeint.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'include/o3tl/safeint.hxx')
-rw-r--r--include/o3tl/safeint.hxx34
1 files changed, 34 insertions, 0 deletions
diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx
index 80a152b83290..4ab31b13ec8f 100644
--- a/include/o3tl/safeint.hxx
+++ b/include/o3tl/safeint.hxx
@@ -10,7 +10,11 @@
#ifndef INCLUDED_O3TL_SAFEINT_HXX
#define INCLUDED_O3TL_SAFEINT_HXX
+#include <sal/config.h>
+
#include <limits>
+#include <type_traits>
+
#if defined(_MSC_VER)
#include <safeint.h>
#else
@@ -22,6 +26,36 @@
namespace o3tl
{
+template<typename T> inline
+typename std::enable_if<std::is_signed<T>::value, T>::type saturating_add(
+ T a, T b)
+{
+ if (b >= 0) {
+ if (a <= std::numeric_limits<T>::max() - b) {
+ return a + b;
+ } else {
+ return std::numeric_limits<T>::max();
+ }
+ } else {
+ if (a >= std::numeric_limits<T>::min() + b) {
+ return a - b;
+ } else {
+ return std::numeric_limits<T>::min();
+ }
+ }
+}
+
+template<typename T> inline
+typename std::enable_if<std::is_unsigned<T>::value, T>::type saturating_add(
+ T a, T b)
+{
+ if (a <= std::numeric_limits<T>::max() - b) {
+ return a + b;
+ } else {
+ return std::numeric_limits<T>::max();
+ }
+}
+
#if defined(_MSC_VER)
template<typename T> inline bool checked_multiply(T a, T b, T& result)