From 50c67f59afca3a2a2edd85f71864cd7e561e20a1 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 14 May 2012 15:50:19 -0400 Subject: [PATCH] Bug 732875 - 5/8 - update CheckedInt docs - r=jwalden --- xpcom/ds/CheckedInt.h | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/xpcom/ds/CheckedInt.h b/xpcom/ds/CheckedInt.h index d0c92bc079f..94fc1332725 100644 --- a/xpcom/ds/CheckedInt.h +++ b/xpcom/ds/CheckedInt.h @@ -386,23 +386,25 @@ inline T opposite_if_signed(T x) { return opposite_if_signed_impl::run(x); } /** \class CheckedInt * \brief Integer wrapper class checking for integer overflow and other errors - * \param T the integer type to wrap. Can be any of int8_t, uint8_t, int16_t, uint16_t, - * int32_t, uint32_t, int64_t, uint64_t. + * \param T the integer type to wrap. Can be any type among the following: + * - any standard integer type like int, char, short, long, long long, and unsigned variants + * - any stdint type such as int8_t, uint64_t etc. + * - (Mozilla specific) and PR integer type like PRInt32 * * This class implements guarded integer arithmetic. Do a computation, check that * valid() returns true, you then have a guarantee that no problem, such as integer overflow, * happened during this computation. * - * The arithmetic operators in this class are guaranteed not to crash your app - * in case of a division by zero. + * The arithmetic operators in this class are guaranteed not to raise a signal + * (e.g. in case of a division by zero). * * For example, suppose that you want to implement a function that computes (x+y)/z, * that doesn't crash if z==0, and that reports on error (divide by zero or integer overflow). * You could code it as follows: \code - bool compute_x_plus_y_over_z(int32_t x, int32_t y, int32_t z, int32_t *result) + bool compute_x_plus_y_over_z(int x, int y, int z, int *result) { - CheckedInt checked_result = (CheckedInt(x) + y) / z; + CheckedInt checked_result = (CheckedInt(x) + y) / z; *result = checked_result.value(); return checked_result.valid(); } @@ -428,7 +430,7 @@ inline T opposite_if_signed(T x) { return opposite_if_signed_impl::run(x); } * * Checked integers of different types cannot be used in the same arithmetic expression. * - * There are convenience typedefs for all PR integer types, of the following form (these are just 2 examples): + * There are convenience typedefs for all stdint types, of the following form (these are just 2 examples): \code typedef CheckedInt CheckedInt32; typedef CheckedInt CheckedUint16; @@ -510,7 +512,15 @@ public: mIsValid & CheckedInt_internal::is_sub_valid(T(0), value(), result)); } - /** \returns true if the left and right hand sides are valid and have the same value. */ + /** \returns true if the left and right hand sides are valid and have the same value. + * + * Note that these semantics are the reason why we don't offer a operator!=. Indeed, we'd want + * to have a!=b be equivalent to !(a==b) but that would mean that whenever a or b is invalid, a!=b + * is always true, which would be very confusing. + * + * For similar reasons, operators <, >, <=, >= would be very tricky to specify, so we just avoid + * offering them. + */ bool operator ==(const CheckedInt& other) const { return bool(mIsValid & other.mIsValid & (value() == other.mValue));