summaryrefslogtreecommitdiff
path: root/include/o3tl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-01-28 14:15:44 +0000
committerCaolán McNamara <caolanm@redhat.com>2018-01-28 18:15:07 +0100
commit94823392874be9c9249e312f6783394edf0e731f (patch)
treefa2afea3550d90d1b6fd49c3cc44c797cfd2a370 /include/o3tl
parentcd4c5e3b2afe767091884d8c1b507d78963e17c4 (diff)
ofz#5621 Integer-overflow
Change-Id: Ie0a7c29428e686e5c480997b84b8d12e5be4539f Reviewed-on: https://gerrit.libreoffice.org/48790 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'include/o3tl')
-rw-r--r--include/o3tl/safeint.hxx30
1 files changed, 30 insertions, 0 deletions
diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx
index 67af99cf810c..fa08b6dfc899 100644
--- a/include/o3tl/safeint.hxx
+++ b/include/o3tl/safeint.hxx
@@ -57,6 +57,36 @@ typename std::enable_if<std::is_unsigned<T>::value, T>::type saturating_add(
}
template<typename T> inline
+typename std::enable_if<std::is_signed<T>::value, T>::type saturating_sub(
+ T a, T b)
+{
+ if (b >= 0) {
+ if (a >= std::numeric_limits<T>::min() + b) {
+ return a - b;
+ } else {
+ return std::numeric_limits<T>::min();
+ }
+ } else {
+ if (a <= std::numeric_limits<T>::max() + b) {
+ return a - b;
+ } else {
+ return std::numeric_limits<T>::max();
+ }
+ }
+}
+
+template<typename T> inline
+typename std::enable_if<std::is_unsigned<T>::value, T>::type saturating_sub(
+ T a, T b)
+{
+ 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_signed<T>::value, T>::type saturating_toggle_sign(
T a)
{