From 680064d39132c452176c64bd15203d2d7e58d277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Thu, 21 Dec 2023 18:39:18 +0100 Subject: [PATCH] Don't store right end of the interval in uniform_integer_distribution --- .../catch_uniform_integer_distribution.hpp | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/catch2/internal/catch_uniform_integer_distribution.hpp b/src/catch2/internal/catch_uniform_integer_distribution.hpp index 3b623579..afa2015d 100644 --- a/src/catch2/internal/catch_uniform_integer_distribution.hpp +++ b/src/catch2/internal/catch_uniform_integer_distribution.hpp @@ -46,12 +46,12 @@ class uniform_integer_distribution { using UnsignedIntegerType = Detail::make_unsigned_t; - // We store the left range bound converted to internal representation, - // because it will be used in computation in the () operator. + // Only the left bound is stored, and we store it converted to its + // unsigned image. This avoids having to do the conversions inside + // the operator(), at the cost of having to do the conversion in + // the a() getter. The right bound is only needed in the b() getter, + // so we recompute it there from other stored data. UnsignedIntegerType m_a; - // After initialization, right bound is only used for the b() getter, - // so we keep it in the original type. - IntegerType m_b; // How many different values are there in [a, b]. a == b => 1, can be 0 for distribution over all values in the type. UnsignedIntegerType m_ab_distance; @@ -64,11 +64,10 @@ class uniform_integer_distribution { // distribution will be reused many times and this is an optimization. UnsignedIntegerType m_rejection_threshold = 0; - // Assumes m_b and m_a are already filled - UnsignedIntegerType computeDistance() const { - // This overflows and returns 0 if ua == 0 and ub == TYPE_MAX. + UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) const { + // This overflows and returns 0 if a == 0 and b == TYPE_MAX. // We handle that later when generating the number. - return transposeTo(m_b) - m_a + 1; + return transposeTo(b) - transposeTo(a) + 1; } static UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) { @@ -92,8 +91,7 @@ public: uniform_integer_distribution( IntegerType a, IntegerType b ): m_a( transposeTo(a) ), - m_b( b ), - m_ab_distance( computeDistance() ), + m_ab_distance( computeDistance(a, b) ), m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) { assert( a <= b ); } @@ -118,7 +116,7 @@ public: } result_type a() const { return transposeBack(m_a); } - result_type b() const { return m_b; } + result_type b() const { return transposeBack(m_ab_distance + m_a - 1); } }; } // end namespace Catch