Add assertions that `GetRandInt*` functions are called with `nMax >= 0`.

All existing uses have been checked to ensure they are consistent with
this assertion.

Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Emma Hopwood 2023-04-18 12:44:43 +01:00
parent 75030610f2
commit 9af901e1a9
4 changed files with 15 additions and 4 deletions

View File

@ -47,6 +47,7 @@ uint128_t GetRandUInt128(uint128_t nMax)
int128_t GetRandInt128(int128_t nMax)
{
assert(nMax >= 0);
return GetRandUInt128(nMax);
}
@ -57,11 +58,13 @@ uint64_t GetRand(uint64_t nMax)
int64_t GetRandInt64(int64_t nMax)
{
assert(nMax >= 0);
return GetRand(nMax);
}
int GetRandInt(int nMax)
{
assert(nMax >= 0);
return GetRand(nMax);
}

View File

@ -24,7 +24,9 @@ void GetRandBytes(unsigned char* buf, size_t num);
template <typename I>
I GetRandGeneric(I nMax)
{
// I must be an unsigned numeric type.
static_assert(std::numeric_limits<I>::min() == 0);
// I() for primitive signed integer types returns 0.
if (nMax == I())
return I();

View File

@ -31,6 +31,7 @@ public:
int RandomInt(int nMax)
{
assert(nMax >= 0);
state = (CHashWriter(SER_GETHASH, 0) << state).GetHash().GetCheapHash();
return (unsigned int)(state % nMax);
}

View File

@ -22,13 +22,17 @@
// weights of the children. This allows for addition, removal, and random
// selection/dropping in logarithmic time.
//
// random(w) must be defined to return a uniform random value between zero
// inclusive and w exclusive. The type W must support addition, binary and
// unary -, and < comparisons, and W() must construct the zero value (these
// constraints are met for primitive signed integer types).
// random(w) (which will only be called with positive w) must be defined to
// return a uniform random value between zero inclusive and w exclusive.
// The type W must be a signed numeric type that supports addition, binary
// and unary -, and < and <= comparisons, and W() must construct the zero value
// (these constraints are met for primitive signed integer types).
template <typename K, typename V, typename W, W random(W)>
class WeightedMap
{
// W must be a signed numeric type.
static_assert(std::numeric_limits<W>::min() < W());
struct Node {
K key;
V value;
@ -180,6 +184,7 @@ public:
return std::nullopt;
}
W totalWeight = getTotalWeight();
assert(W() < totalWeight);
W randomWeight = random(totalWeight);
assert(W() <= randomWeight && randomWeight < totalWeight);
size_t index = findByWeight(0, randomWeight);