diff options
-rw-r--r-- | src/base/sat_counter.hh | 23 | ||||
-rw-r--r-- | src/base/sat_counter.test.cc | 39 |
2 files changed, 56 insertions, 6 deletions
diff --git a/src/base/sat_counter.hh b/src/base/sat_counter.hh index 6aeca681d..946da4f26 100644 --- a/src/base/sat_counter.hh +++ b/src/base/sat_counter.hh @@ -44,6 +44,7 @@ #ifndef __BASE_SAT_COUNTER_HH__ #define __BASE_SAT_COUNTER_HH__ +#include <cassert> #include <cstdint> #include "base/logging.hh" @@ -172,6 +173,7 @@ class SatCounter SatCounter& operator>>=(const int& shift) { + assert(shift >= 0); this->counter >>= shift; return *this; } @@ -180,6 +182,7 @@ class SatCounter SatCounter& operator<<=(const int& shift) { + assert(shift >= 0); this->counter <<= shift; if (this->counter > maxVal) { this->counter = maxVal; @@ -191,10 +194,14 @@ class SatCounter SatCounter& operator+=(const int& value) { - if (maxVal - this->counter >= value) { - this->counter += value; + if (value >= 0) { + if (maxVal - this->counter >= value) { + this->counter += value; + } else { + this->counter = maxVal; + } } else { - this->counter = maxVal; + *this -= -value; } return *this; } @@ -203,10 +210,14 @@ class SatCounter SatCounter& operator-=(const int& value) { - if (this->counter > value) { - this->counter -= value; + if (value >= 0) { + if (this->counter > value) { + this->counter -= value; + } else { + this->counter = 0; + } } else { - this->counter = 0; + *this += -value; } return *this; } diff --git a/src/base/sat_counter.test.cc b/src/base/sat_counter.test.cc index 817f2c7ac..d9a377f9f 100644 --- a/src/base/sat_counter.test.cc +++ b/src/base/sat_counter.test.cc @@ -28,6 +28,7 @@ * Authors: Daniel Carvalho */ +#include <gtest/gtest-spi.h> #include <gtest/gtest.h> #include <utility> @@ -184,6 +185,11 @@ TEST(SatCounterTest, Shift) ASSERT_EQ(counter, value); counter >>= saturated_counter; ASSERT_EQ(counter, 0); + + // Make sure the counters cannot be shifted by negative numbers, since + // that is undefined behaviour + ASSERT_DEATH(counter >>= -1, ""); + ASSERT_DEATH(counter <<= -1, ""); } /** @@ -319,3 +325,36 @@ TEST(SatCounterTest, AddSubAssignment) ASSERT_EQ(counter, 0); } +/** + * Test add-assignment and subtract assignment using negative numbers. + */ +TEST(SatCounterTest, NegativeAddSubAssignment) +{ + const unsigned bits = 3; + const unsigned max_value = (1 << bits) - 1; + SatCounter counter(bits, max_value); + int value = max_value; + + // Test add-assignment for a few negative values until zero is reached + counter += -2; + value += -2; + ASSERT_EQ(counter, value); + counter += -3; + value += -3; + ASSERT_EQ(counter, value); + counter += (int)-max_value; + value = 0; + ASSERT_EQ(counter, value); + + // Test subtract-assignment for a few negative values until saturation + counter -= -2; + value -= -2; + ASSERT_EQ(counter, value); + counter -= -3; + value -= -3; + ASSERT_EQ(counter, value); + counter -= (int)-max_value; + value = max_value; + ASSERT_EQ(counter, value); +} + |