[PATCH] Fix private constructor for ScaledNumber.
Duncan P. N. Exon Smith
dexonsmith at apple.com
Wed Apr 29 13:52:07 PDT 2015
> On 2015-Apr-29, at 13:32, Diego Novillo <dnovillo at google.com> wrote:
>
> Hi dexonsmith,
>
> It was using uint64_t instead of DigitsT. This was preventing
> instantiations of ScaledNumber with anything other than uint64_t types.
>
> In implementing the tests, I ran into another issue. Operators >>= and
> <<= did not have variants for accepting other ScaledNumber as the shift
> argument. This is expected by the SCALED_NUMBER_BOP.
>
> I'm not sure it makes sense to allow shifting a ScaledNumber by another
> ScaledNumber, so I generated a new template for shifting ScaledNumbers
> using a new macro SCALED_NUMBER_SHIFT.
>
> http://reviews.llvm.org/D9350
>
> Files:
> include/llvm/Support/ScaledNumber.h
> unittests/Support/ScaledNumberTest.cpp
LGTM, with some minor comments below. Thanks for the fixes!
> Index: include/llvm/Support/ScaledNumber.h
> ===================================================================
> --- include/llvm/Support/ScaledNumber.h
> +++ include/llvm/Support/ScaledNumber.h
> @@ -514,7 +514,7 @@
> : Digits(Digits), Scale(Scale) {}
>
> private:
> - ScaledNumber(const std::pair<uint64_t, int16_t> &X)
> + ScaledNumber(const std::pair<DigitsT, int16_t> &X)
> : Digits(X.first), Scale(X.second) {}
>
> public:
> @@ -732,10 +732,18 @@
> SCALED_NUMBER_BOP(-, -= )
> SCALED_NUMBER_BOP(*, *= )
> SCALED_NUMBER_BOP(/, /= )
> -SCALED_NUMBER_BOP(<<, <<= )
> -SCALED_NUMBER_BOP(>>, >>= )
> #undef SCALED_NUMBER_BOP
>
> +#define SCALED_NUMBER_SHIFT(op, base) \
> + template <class DigitsT> \
> + ScaledNumber<DigitsT> operator op(const ScaledNumber<DigitsT> &L, \
> + int16_t Shift) { \
> + return ScaledNumber<DigitsT>(L) base Shift; \
> + }
> +SCALED_NUMBER_SHIFT(<<, <<= )
> +SCALED_NUMBER_SHIFT(>>, >>= )
> +#undef SCALED_NUMBER_SHIFT
With only two in this group, do you think the macro is still adding
value? If not, feel free to rewrite without the macro. Up to you.
> +
> template <class DigitsT>
> raw_ostream &operator<<(raw_ostream &OS, const ScaledNumber<DigitsT> &X) {
> return X.print(OS, 10);
> Index: unittests/Support/ScaledNumberTest.cpp
> ===================================================================
> --- unittests/Support/ScaledNumberTest.cpp
> +++ unittests/Support/ScaledNumberTest.cpp
> @@ -155,7 +155,7 @@
> EXPECT_EQ(SP32(0xaaaaaaab, -33), getQuotient32(1, 3));
> EXPECT_EQ(SP32(0xd5555555, -31), getQuotient32(5, 3));
>
> - // 64-bit division is hard to test, since divide64 doesn't canonicalized its
> + // 64-bit division is hard to test, since divide64 doesn't canonicalize its
Maybe commit this separately? It seems unrelated.
> // output. However, this is the algorithm the implementation uses:
> //
> // - Shift divisor right.
> @@ -532,4 +532,17 @@
> EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, -1));
> }
>
> +TEST(ScaledNumberHelpersTest, arithmeticOperators) {
Can you duplicate all the EXPECTs here for `uint64_t` as well?
> + EXPECT_EQ(ScaledNumber<uint32_t>(1, 3) + ScaledNumber<uint32_t>(1, 1),
> + ScaledNumber<uint32_t>(10, 0));
IIRC, the error messages for EXPECT look better if the expected value
is the LHS of the macro. It prints something like this when it fails:
Expected value: <LHS>
Actual value: <RHS>
So it would be better if you reversed the arguments for all of these.
> + EXPECT_EQ(ScaledNumber<uint32_t>(1, 3) - ScaledNumber<uint32_t>(1, 1),
> + ScaledNumber<uint32_t>(6, 0));
> + EXPECT_EQ(ScaledNumber<uint32_t>(1, 3) * ScaledNumber<uint32_t>(1, 1),
> + ScaledNumber<uint32_t>(2, 3));
> + EXPECT_EQ(ScaledNumber<uint32_t>(1, 3) / ScaledNumber<uint32_t>(1, 1),
> + ScaledNumber<uint32_t>(1, 2));
> + EXPECT_EQ(ScaledNumber<uint32_t>(1, 3) >> 1, ScaledNumber<uint32_t>(1, 2));
> + EXPECT_EQ(ScaledNumber<uint32_t>(1, 3) << 1, ScaledNumber<uint32_t>(2, 3));
For clarity, I'd spell this last expected value as
`ScaledNumber<uint32_t>(1, 4)`. I think that makes it easier to
compare with the previous line.
For clarity, these last two didn't previously compile for `uint64_t`,
did they? (If they did, then I'm confused...)
> +}
> +
> } // end namespace
>
More information about the llvm-commits
mailing list