mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-24 00:05:25 +00:00
Enable range checking for unsigned integers (#11313)
* Enable range checking for unsigned integers * Make the tests green
This commit is contained in:
committed by
Andreas Rumpf
parent
70fb3a93e9
commit
3a06022071
@@ -33,6 +33,12 @@ const useICC_builtins = defined(icc) and useBuiltins
|
||||
const useVCC_builtins = defined(vcc) and useBuiltins
|
||||
const arch64 = sizeof(int) == 8
|
||||
|
||||
template toUnsigned(x: int8): uint8 = cast[uint8](x)
|
||||
template toUnsigned(x: int16): uint16 = cast[uint16](x)
|
||||
template toUnsigned(x: int32): uint32 = cast[uint32](x)
|
||||
template toUnsigned(x: int64): uint64 = cast[uint64](x)
|
||||
template toUnsigned(x: int): uint = cast[uint](x)
|
||||
|
||||
template forwardImpl(impl, arg) {.dirty.} =
|
||||
when sizeof(x) <= 4:
|
||||
when x is SomeSignedInt:
|
||||
@@ -242,6 +248,8 @@ proc countSetBits*(x: SomeInteger): int {.inline, nosideeffect.} =
|
||||
## Counts the set bits in integer. (also called `Hamming weight`:idx:.)
|
||||
# TODO: figure out if ICC support _popcnt32/_popcnt64 on platform without POPCNT.
|
||||
# like GCC and MSVC
|
||||
when x is SomeSignedInt:
|
||||
let x = x.toUnsigned
|
||||
when nimvm:
|
||||
result = forwardImpl(countSetBits_nim, x)
|
||||
else:
|
||||
@@ -272,6 +280,8 @@ proc parityBits*(x: SomeInteger): int {.inline, nosideeffect.} =
|
||||
## is odd parity is 1, otherwise 0.
|
||||
# Can be used a base if creating ASM version.
|
||||
# https://stackoverflow.com/questions/21617970/how-to-check-if-value-has-even-parity-of-bits-or-odd
|
||||
when x is SomeSignedInt:
|
||||
let x = x.toUnsigned
|
||||
when nimvm:
|
||||
result = forwardImpl(parity_impl, x)
|
||||
else:
|
||||
@@ -287,6 +297,8 @@ proc firstSetBit*(x: SomeInteger): int {.inline, nosideeffect.} =
|
||||
## If `x` is zero, when ``noUndefinedBitOpts`` is set, result is 0,
|
||||
## otherwise result is undefined.
|
||||
# GCC builtin 'builtin_ffs' already handle zero input.
|
||||
when x is SomeSignedInt:
|
||||
let x = x.toUnsigned
|
||||
when nimvm:
|
||||
when noUndefined:
|
||||
if x == 0:
|
||||
@@ -321,6 +333,8 @@ proc fastLog2*(x: SomeInteger): int {.inline, nosideeffect.} =
|
||||
## Quickly find the log base 2 of an integer.
|
||||
## If `x` is zero, when ``noUndefinedBitOpts`` is set, result is -1,
|
||||
## otherwise result is undefined.
|
||||
when x is SomeSignedInt:
|
||||
let x = x.toUnsigned
|
||||
when noUndefined:
|
||||
if x == 0:
|
||||
return -1
|
||||
@@ -352,6 +366,8 @@ proc countLeadingZeroBits*(x: SomeInteger): int {.inline, nosideeffect.} =
|
||||
## Returns the number of leading zero bits in integer.
|
||||
## If `x` is zero, when ``noUndefinedBitOpts`` is set, result is 0,
|
||||
## otherwise result is undefined.
|
||||
when x is SomeSignedInt:
|
||||
let x = x.toUnsigned
|
||||
when noUndefined:
|
||||
if x == 0:
|
||||
return 0
|
||||
@@ -369,6 +385,8 @@ proc countTrailingZeroBits*(x: SomeInteger): int {.inline, nosideeffect.} =
|
||||
## Returns the number of trailing zeros in integer.
|
||||
## If `x` is zero, when ``noUndefinedBitOpts`` is set, result is 0,
|
||||
## otherwise result is undefined.
|
||||
when x is SomeSignedInt:
|
||||
let x = x.toUnsigned
|
||||
when noUndefined:
|
||||
if x == 0:
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user