#ifndef __BASE_SAT_COUNTER_HH__
#define __BASE_SAT_COUNTER_HH__
+#include <cassert>
#include <cstdint>
#include "base/logging.hh"
SatCounter&
operator>>=(const int& shift)
{
+ assert(shift >= 0);
this->counter >>= shift;
return *this;
}
SatCounter&
operator<<=(const int& shift)
{
+ assert(shift >= 0);
this->counter <<= shift;
if (this->counter > maxVal) {
this->counter = maxVal;
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;
}
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;
}
* Authors: Daniel Carvalho
*/
+#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <utility>
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, "");
}
/**
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);
+}
+