Unify counter clamp arithmetic into shared addClamped() helper

- Add addClamped() in new header clamped_arithmetic.h; uses a 64-bit
  intermediate so the addition cannot overflow int.
- Use it in Server_Card::incrementCounter() (clamps [0, MAX_COUNTERS_ON_CARD])
  and Server_Counter::incrementCount() (clamps [INT_MIN, INT_MAX]), removing
  the duplicated overflow-safe logic and its keep-in-sync TODO.
- Inline incrementCount() into server_counter.h; server_counter.cpp now holds
  only the constructor and getInfo().
- Clarify the card-counter bounds comment in trice_limits.h.
This commit is contained in:
DawnFire42 2026-06-19 12:20:50 -04:00
parent fcac7493ad
commit 7aed233bd8
No known key found for this signature in database
GPG key ID: 24BB855EE2911B33
6 changed files with 39 additions and 17 deletions

View file

@ -26,6 +26,7 @@
#include <libcockatrice/protocol/pb/event_set_card_attr.pb.h>
#include <libcockatrice/protocol/pb/event_set_card_counter.pb.h>
#include <libcockatrice/protocol/pb/serverinfo_card.pb.h>
#include <libcockatrice/utility/clamped_arithmetic.h>
#include <libcockatrice/utility/trice_limits.h>
#include <limits>
@ -139,10 +140,8 @@ bool Server_Card::setCounter(int _id, int value, Event_SetCardCounter *event)
bool Server_Card::incrementCounter(int counterId, int delta, Event_SetCardCounter *event)
{
const int oldValue = counters.value(counterId, 0);
const auto result = static_cast<int64_t>(oldValue) + static_cast<int64_t>(delta);
// Clamp to [0, MAX_COUNTERS_ON_CARD] for card counters
const int newValue =
static_cast<int>(qBound(static_cast<int64_t>(0), result, static_cast<int64_t>(MAX_COUNTERS_ON_CARD)));
const int newValue = addClamped(oldValue, delta, 0, MAX_COUNTERS_ON_CARD);
if (newValue == oldValue) {
return false;

View file

@ -1,24 +1,12 @@
#include "server_counter.h"
#include <libcockatrice/protocol/pb/serverinfo_counter.pb.h>
#include <limits>
Server_Counter::Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count)
: id(_id), name(_name), counterColor(_counterColor), radius(_radius), count(_count)
{
}
//! \todo Extract overflow-safe arithmetic into shared helper.
//! Duplicated in Server_Card::incrementCounter() - keep in sync if modified.
bool Server_Counter::incrementCount(int delta)
{
const int oldCount = count;
const auto result = static_cast<int64_t>(count) + static_cast<int64_t>(delta);
count = static_cast<int>(qBound(static_cast<int64_t>(std::numeric_limits<int>::min()), result,
static_cast<int64_t>(std::numeric_limits<int>::max())));
return count != oldCount;
}
void Server_Counter::getInfo(ServerInfo_Counter *info)
{
info->set_id(id);

View file

@ -22,6 +22,8 @@
#include <QString>
#include <libcockatrice/protocol/pb/color.pb.h>
#include <libcockatrice/utility/clamped_arithmetic.h>
#include <limits>
class ServerInfo_Counter;
@ -92,7 +94,12 @@ public:
* @return true if the value changed, false otherwise.
* @note Clamps result to [INT_MIN, INT_MAX] to prevent overflow.
*/
[[nodiscard]] bool incrementCount(int delta);
[[nodiscard]] bool incrementCount(int delta)
{
const int oldCount = count;
count = addClamped(count, delta, std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
return count != oldCount;
}
/**
* @brief Populates info with this counter's current state for network serialization.