Add boolean not and comparison tests
This commit is contained in:
parent
acd06e1174
commit
8d6e328397
|
@ -56,6 +56,17 @@ func `-`*(x: HardBase): HardBase {.inline.}=
|
||||||
## of an unsigned integer
|
## of an unsigned integer
|
||||||
{.emit:"`result` = -`x`;".}
|
{.emit:"`result` = -`x`;".}
|
||||||
|
|
||||||
|
# ############################################################
|
||||||
|
#
|
||||||
|
# Bit hacks
|
||||||
|
#
|
||||||
|
# ############################################################
|
||||||
|
|
||||||
|
func isMsbSet*[T: HardBase](x: T): HardBool[T] {.inline.} =
|
||||||
|
## Returns the most significant bit of an integer
|
||||||
|
const msb_pos = T.sizeof * 8 - 1
|
||||||
|
result = (HardBool[T])(x shr msb_pos)
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
# Hardened Boolean primitives
|
# Hardened Boolean primitives
|
||||||
|
@ -77,22 +88,19 @@ func select*[T: HardBase](ctl: HardBool[T], x, y: T): T {.inline.}=
|
||||||
# is optimized into a branch by Clang :/
|
# is optimized into a branch by Clang :/
|
||||||
y xor (-ctl.T and (x xor y))
|
y xor (-ctl.T and (x xor y))
|
||||||
|
|
||||||
func `!=`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
func noteq[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||||
const msb = T.sizeof * 8 - 1
|
const msb = T.sizeof * 8 - 1
|
||||||
let z = x xor y
|
let z = x xor y
|
||||||
result = (type result)((z or -z) shr msb)
|
result = (type result)((z or -z) shr msb)
|
||||||
|
|
||||||
func `==`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
func `==`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||||
not(x != y)
|
not(noteq(x, y))
|
||||||
|
|
||||||
func `<`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
func `<`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||||
const msb = T.sizeof * 8 - 1
|
result = isMsbSet(
|
||||||
result = (type result)(
|
|
||||||
(
|
|
||||||
x xor (
|
x xor (
|
||||||
(x xor y) or ((x - y) xor y)
|
(x xor y) or ((x - y) xor y)
|
||||||
)
|
)
|
||||||
) shr msb
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func `<=`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
func `<=`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||||
|
@ -100,14 +108,16 @@ func `<=`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
# Bit hacks
|
# Workaround system.nim `!=` template
|
||||||
#
|
#
|
||||||
# ############################################################
|
# ############################################################
|
||||||
|
|
||||||
func isMsbSet*[T: HardBase](x: T): HardBool[T] {.inline.} =
|
# system.nim defines `!=` as a catchall template
|
||||||
## Returns the most significant bit of an integer
|
# in terms of `==` while we define `==` in terms of `!=`
|
||||||
const msb_pos = T.sizeof * 8 - 1
|
# So we would have not(not(noteq(x,y)))
|
||||||
result = (HardBool[T])(x shr msb_pos)
|
|
||||||
|
template trmFixSystemNotEq*{x != y}[T: HardBase](x, y: T): HardBool[T] =
|
||||||
|
noteq(x, y)
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
|
|
|
@ -24,10 +24,10 @@ type
|
||||||
## Note that constant-time allocation is very involved for
|
## Note that constant-time allocation is very involved for
|
||||||
## heap-allocated types (i.e. requires a memory pool)
|
## heap-allocated types (i.e. requires a memory pool)
|
||||||
|
|
||||||
func htrue*(T: type(BaseUint)): auto {.compileTime.}=
|
func htrue*(T: type(BaseUint)): auto {.inline.}=
|
||||||
(HardBool[HardBase[T]])(true)
|
(HardBool[HardBase[T]])(true)
|
||||||
|
|
||||||
func hfalse*(T: type(BaseUint)): auto {.compileTime.}=
|
func hfalse*(T: type(BaseUint)): auto {.inline.}=
|
||||||
(HardBool[HardBase[T]])(false)
|
(HardBool[HardBase[T]])(false)
|
||||||
|
|
||||||
func hard*[T: BaseUint](x: T): HardBase[T] {.inline.}=
|
func hard*[T: BaseUint](x: T): HardBase[T] {.inline.}=
|
||||||
|
|
|
@ -132,3 +132,37 @@ suite "Hardened unsigned integers":
|
||||||
undistinct(-y1.hard) == undistinct(not(y1.hard) + hard(1'u64))
|
undistinct(-y1.hard) == undistinct(not(y1.hard) + hard(1'u64))
|
||||||
undistinct(-y2.hard) == undistinct(not(y2.hard) + hard(1'u64))
|
undistinct(-y2.hard) == undistinct(not(y2.hard) + hard(1'u64))
|
||||||
undistinct(-y3.hard) == undistinct(not(y3.hard) + hard(1'u64))
|
undistinct(-y3.hard) == undistinct(not(y3.hard) + hard(1'u64))
|
||||||
|
|
||||||
|
suite "Hardened booleans":
|
||||||
|
test "Boolean not":
|
||||||
|
check:
|
||||||
|
not(htrue(uint32)).bool == false
|
||||||
|
not(hfalse(uint32)).bool == true
|
||||||
|
|
||||||
|
test "Comparison":
|
||||||
|
check:
|
||||||
|
bool(hard(0'u32) != hard(0'u32)) == false
|
||||||
|
bool(hard(0'u32) != hard(1'u32)) == true
|
||||||
|
|
||||||
|
bool(hard(10'u32) == hard(10'u32)) == true
|
||||||
|
bool(hard(10'u32) != hard(20'u32)) == true
|
||||||
|
|
||||||
|
bool(hard(10'u32) <= hard(10'u32)) == true
|
||||||
|
bool(hard(10'u32) <= hard(20'u32)) == true
|
||||||
|
bool(hard(10'u32) <= hard(5'u32)) == false
|
||||||
|
bool(hard(10'u32) <= hard(0xFFFFFFFF'u32)) == true
|
||||||
|
|
||||||
|
bool(hard(10'u32) < hard(10'u32)) == false
|
||||||
|
bool(hard(10'u32) < hard(20'u32)) == true
|
||||||
|
bool(hard(10'u32) < hard(5'u32)) == false
|
||||||
|
bool(hard(10'u32) < hard(0xFFFFFFFF'u32)) == true
|
||||||
|
|
||||||
|
bool(hard(10'u32) > hard(10'u32)) == false
|
||||||
|
bool(hard(10'u32) > hard(20'u32)) == false
|
||||||
|
bool(hard(10'u32) > hard(5'u32)) == true
|
||||||
|
bool(hard(10'u32) > hard(0xFFFFFFFF'u32)) == false
|
||||||
|
|
||||||
|
bool(hard(10'u32) >= hard(10'u32)) == true
|
||||||
|
bool(hard(10'u32) >= hard(20'u32)) == false
|
||||||
|
bool(hard(10'u32) >= hard(5'u32)) == true
|
||||||
|
bool(hard(10'u32) >= hard(0xFFFFFFFF'u32)) == false
|
||||||
|
|
Loading…
Reference in New Issue