diff --git a/tests/test_int_comparison.nim b/tests/test_int_comparison.nim index ba49c36..4a58e85 100644 --- a/tests/test_int_comparison.nim +++ b/tests/test_int_comparison.nim @@ -9,6 +9,379 @@ import ../stint, unittest +template chkLT(chk: untyped, a, b: string, bits: int) = + chk fromHex(Stint[bits], a) < fromHex(Stint[bits], b) + +template chknotLT(chk: untyped, a, b: string, bits: int) = + chk not(fromHex(Stint[bits], b) < fromHex(Stint[bits], a)) + +template chkLTE(chk: untyped, a, b: string, bits: int) = + chk fromHex(Stint[bits], a) <= fromHex(Stint[bits], b) + +template chknotLTE(chk: untyped, a, b: string, bits: int) = + chk not(fromHex(Stint[bits], b) <= fromHex(Stint[bits], a)) + +template chkEQ(chk: untyped, a, b: string, bits: int) = + chk fromHex(Stint[bits], a) == fromHex(Stint[bits], b) + +template chknotEQ(chk: untyped, a, b: string, bits: int) = + chk not(fromHex(Stint[bits], a) == fromHex(Stint[bits], b)) + +template chkisZero(chk: untyped, a: string, bits: int) = + chk fromHex(Stint[bits], a).isZero() + +template chknotisZero(chk: untyped, a: string, bits: int) = + chk not fromHex(Stint[bits], a).isZero() + +template chkisNegative(chk: untyped, a: string, bits: int) = + chk fromHex(Stint[bits], a).isNegative() + +template chknotisNegative(chk: untyped, a: string, bits: int) = + chk not fromHex(Stint[bits], a).isNegative() + +template chkisOdd(chk: untyped, a: string, bits: int) = + chk fromHex(Stint[bits], a).isOdd() + +template chknotisOdd(chk: untyped, a: string, bits: int) = + chk (not fromHex(Stint[bits], a).isOdd()) + +template chkisEven(chk: untyped, a: string, bits: int) = + chk fromHex(Stint[bits], a).isEven() + +template chknotisEven(chk: untyped, a: string, bits: int) = + chk not fromHex(Stint[bits], a).isEven() + +template ctTest(name: string, body: untyped) = + body + echo "[OK] compile time ", name + +template testComparison(chk, tst: untyped) = + tst "operator `LT`": + chkLT(chk, "0", "F", 8) + chkLT(chk, "F", "7F", 8) + chkLT(chk, "FF", "7F", 8) + + chkLT(chk, "0", "F", 16) + chkLT(chk, "F", "FF", 16) + chkLT(chk, "FF", "FFF", 16) + chkLT(chk, "FFFF", "FFF", 16) + + chkLT(chk, "0", "F", 32) + chkLT(chk, "F", "FF", 32) + chkLT(chk, "FF", "FFF", 32) + chkLT(chk, "FFFF", "FFFFF", 32) + chkLT(chk, "FFFFFFFF", "FFFFF", 32) + + chkLT(chk, "0", "F", 64) + chkLT(chk, "F", "FF", 64) + chkLT(chk, "FF", "FFF", 64) + chkLT(chk, "FFFF", "FFFFF", 64) + chkLT(chk, "FFFFF", "FFFFFFFF", 64) + chkLT(chk, "FFFFFFFFFFFFFFFF", "FFFFFFFF", 64) + + chkLT(chk, "0", "F", 128) + chkLT(chk, "F", "FF", 128) + chkLT(chk, "FF", "FFF", 128) + chkLT(chk, "FFFF", "FFFFF", 128) + chkLT(chk, "FFFFF", "FFFFFFFF", 128) + chkLT(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + chkLT(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + + tst "operator not `LT`": + chknotLT(chk, "0", "F", 8) + chknotLT(chk, "F", "7F", 8) + chknotLT(chk, "FF", "7F", 8) + + chknotLT(chk, "0", "F", 16) + chknotLT(chk, "F", "FF", 16) + chknotLT(chk, "FF", "FFF", 16) + chknotLT(chk, "FFFF", "FFF", 16) + + chknotLT(chk, "0", "F", 32) + chknotLT(chk, "F", "FF", 32) + chknotLT(chk, "FF", "FFF", 32) + chknotLT(chk, "FFFF", "FFFFF", 32) + chknotLT(chk, "FFFFFFFF", "FFFFF", 32) + + chknotLT(chk, "0", "F", 64) + chknotLT(chk, "F", "FF", 64) + chknotLT(chk, "FF", "FFF", 64) + chknotLT(chk, "FFFF", "FFFFF", 64) + chknotLT(chk, "FFFFF", "FFFFFFFF", 64) + chknotLT(chk, "FFFFFFFFFFFFFFFF", "FFFFFFFF", 64) + + chknotLT(chk, "0", "F", 128) + chknotLT(chk, "F", "FF", 128) + chknotLT(chk, "FF", "FFF", 128) + chknotLT(chk, "FFFF", "FFFFF", 128) + chknotLT(chk, "FFFFF", "FFFFFFFF", 128) + chknotLT(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + chknotLT(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + + tst "operator `LTE`": + chkLTE(chk, "0", "F", 8) + chkLTE(chk, "F", "7F", 8) + chkLTE(chk, "F", "F", 8) + chkLTE(chk, "FF", "7F", 8) + + chkLTE(chk, "0", "F", 16) + chkLTE(chk, "F", "FF", 16) + chkLTE(chk, "FF", "FFF", 16) + chkLTE(chk, "FFF", "FFF", 16) + chkLTE(chk, "FFFF", "FFF", 16) + + chkLTE(chk, "0", "F", 32) + chkLTE(chk, "F", "FF", 32) + chkLTE(chk, "FF", "FFF", 32) + chkLTE(chk, "FFFF", "FFFFF", 32) + chkLTE(chk, "FFFFF", "FFFFF", 32) + chkLTE(chk, "FFFFFFFF", "FFFFF", 32) + + chkLTE(chk, "0", "F", 64) + chkLTE(chk, "F", "FF", 64) + chkLTE(chk, "FF", "FFF", 64) + chkLTE(chk, "FFFF", "FFFFF", 64) + chkLTE(chk, "FFFFF", "FFFFFFFF", 64) + chkLTE(chk, "FFFFFFFF", "FFFFFFFF", 64) + chkLTE(chk, "FFFFFFFFFFFFFFFF", "FFFFFFFF", 64) + + chkLTE(chk, "0", "F", 128) + chkLTE(chk, "F", "FF", 128) + chkLTE(chk, "FF", "FFF", 128) + chkLTE(chk, "FFFF", "FFFFF", 128) + chkLTE(chk, "FFFFF", "FFFFFFFF", 128) + chkLTE(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + chkLTE(chk, "FFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + chkLTE(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + + tst "operator not `LTE`": + chknotLTE(chk, "0", "F", 8) + chknotLTE(chk, "F", "7F", 8) + chknotLTE(chk, "FF", "7F", 8) + + chknotLTE(chk, "0", "F", 16) + chknotLTE(chk, "F", "FF", 16) + chknotLTE(chk, "FF", "FFF", 16) + chknotLTE(chk, "FFFF", "FFF", 16) + + chknotLTE(chk, "0", "F", 32) + chknotLTE(chk, "F", "FF", 32) + chknotLTE(chk, "FF", "FFF", 32) + chknotLTE(chk, "FFFF", "FFFFF", 32) + chknotLTE(chk, "FFFFFFFF", "FFFFF", 32) + + chknotLTE(chk, "0", "F", 64) + chknotLTE(chk, "F", "FF", 64) + chknotLTE(chk, "FF", "FFF", 64) + chknotLTE(chk, "FFFF", "FFFFF", 64) + chknotLTE(chk, "FFFFF", "FFFFFFFF", 64) + chknotLTE(chk, "FFFFFFFFFFFFFFFF", "FFFFFFFF", 64) + + chknotLTE(chk, "0", "F", 128) + chknotLTE(chk, "F", "FF", 128) + chknotLTE(chk, "FF", "FFF", 128) + chknotLTE(chk, "FFFF", "FFFFF", 128) + chknotLTE(chk, "FFFFF", "FFFFFFFF", 128) + chknotLTE(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + chknotLTE(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + + tst "operator `EQ`": + chkEQ(chk, "0", "0", 8) + chkEQ(chk, "FF", "FF", 8) + chkEQ(chk, "F", "F", 8) + + chkEQ(chk, "0", "0", 16) + chkEQ(chk, "F", "F", 16) + chkEQ(chk, "FF", "FF", 16) + chkEQ(chk, "FFF", "FFF", 16) + chkEQ(chk, "FFFF", "FFFF", 16) + + chkEQ(chk, "0", "0", 32) + chkEQ(chk, "F", "F", 32) + chkEQ(chk, "FF", "FF", 32) + chkEQ(chk, "FFFF", "FFFF", 32) + chkEQ(chk, "FFFFF", "FFFFF", 32) + + chkEQ(chk, "0", "0", 64) + chkEQ(chk, "F", "F", 64) + chkEQ(chk, "FF", "FF", 64) + chkEQ(chk, "FFFF", "FFFF", 64) + chkEQ(chk, "FFFFF", "FFFFF", 64) + chkEQ(chk, "FFFFFFFF", "FFFFFFFF", 64) + + chkEQ(chk, "0", "0", 128) + chkEQ(chk, "F", "F", 128) + chkEQ(chk, "FF", "FF", 128) + chkEQ(chk, "FFFF", "FFFF", 128) + chkEQ(chk, "FFFFF", "FFFFF", 128) + chkEQ(chk, "FFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128) + + tst "operator not `EQ`": + chknotEQ(chk, "0", "F", 8) + chknotEQ(chk, "F", "FF", 8) + + chknotEQ(chk, "0", "F", 16) + chknotEQ(chk, "F", "FF", 16) + chknotEQ(chk, "FF", "FFA", 16) + + chknotEQ(chk, "0", "F", 32) + chknotEQ(chk, "F", "FF", 32) + chknotEQ(chk, "FF", "FFF", 32) + chknotEQ(chk, "FFFF", "FAFFF", 32) + + chknotEQ(chk, "0", "F", 64) + chknotEQ(chk, "F", "FF", 64) + chknotEQ(chk, "FF", "FFF", 64) + chknotEQ(chk, "FFFF", "FFFFF", 64) + chknotEQ(chk, "FFFFF", "FAFFFFFFF", 64) + + chknotEQ(chk, "0", "F", 128) + chknotEQ(chk, "F", "FF", 128) + chknotEQ(chk, "FF", "FFF", 128) + chknotEQ(chk, "FFFF", "FFFFF", 128) + chknotEQ(chk, "FFFFF", "FFAFFFFF", 128) + chknotEQ(chk, "FFFFFFFFFFF", "AFFFFFFFFFFFFFFFFFFFFFFF", 128) + + tst "operator `isZero`": + chkIsZero(chk, "0", 8) + chkIsZero(chk, "0", 16) + chkIsZero(chk, "0", 32) + chkIsZero(chk, "0", 64) + chkIsZero(chk, "0", 128) + chkIsZero(chk, "0", 256) + + tst "operator not `isZero`": + chknotIsZero(chk, "1", 8) + chknotIsZero(chk, "2", 16) + chknotIsZero(chk, "3", 32) + chknotIsZero(chk, "4", 64) + chknotIsZero(chk, "5", 128) + chknotIsZero(chk, "6", 256) + + chknotIsZero(chk, "FF", 8) + chknotIsZero(chk, "FFFF", 16) + chknotIsZero(chk, "FFFFFFFF", 32) + chknotIsZero(chk, "FFFFFFFFFFFFFFFF", 64) + chknotIsZero(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 128) + chknotIsZero(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 256) + + tst "operator `isNegative`": + chkisNegative(chk, "F0", 8) + chkisNegative(chk, "F000", 16) + chkisNegative(chk, "F0000000", 32) + chkisNegative(chk, "F000000000000000", 64) + chkisNegative(chk, "F0000000000000000000000000000000", 128) + chkisNegative(chk, "F000000000000000000000000000000000000000000000000000000000000000", 256) + + chkisNegative(chk, "A1", 8) + chkisNegative(chk, "A200", 16) + chkisNegative(chk, "A3000000", 32) + chkisNegative(chk, "A400000000000000", 64) + chkisNegative(chk, "A5000000000000000000000000000000", 128) + chkisNegative(chk, "A600000000000000000000000000000000000000000000000000000000000000", 256) + + tst "operator not `isNegative`": + chknotIsNegative(chk, "0", 8) + chknotIsNegative(chk, "0", 16) + chknotIsNegative(chk, "0", 32) + chknotIsNegative(chk, "0", 64) + chknotIsNegative(chk, "0", 128) + chknotIsNegative(chk, "0", 256) + + chknotIsNegative(chk, "1", 8) + chknotIsNegative(chk, "2", 16) + chknotIsNegative(chk, "3", 32) + chknotIsNegative(chk, "4", 64) + chknotIsNegative(chk, "5", 128) + chknotIsNegative(chk, "6", 256) + + chknotIsNegative(chk, "71", 8) + chknotIsNegative(chk, "7200", 16) + chknotIsNegative(chk, "73000000", 32) + chknotIsNegative(chk, "7400000000000000", 64) + chknotIsNegative(chk, "75000000000000000000000000000000", 128) + chknotIsNegative(chk, "7600000000000000000000000000000000000000000000000000000000000000", 256) + + tst "operator `isOdd`": + chkIsOdd(chk, "1", 8) + chkIsOdd(chk, "1", 16) + chkIsOdd(chk, "1", 32) + chkIsOdd(chk, "1", 64) + chkIsOdd(chk, "1", 128) + chkIsOdd(chk, "1", 256) + + chkIsOdd(chk, "FF", 8) + chkIsOdd(chk, "FFF", 16) + chkIsOdd(chk, "FFFFF", 32) + chkIsOdd(chk, "FFFFFF", 64) + chkIsOdd(chk, "FFFFFFFFFFFFFFF", 128) + chkIsOdd(chk, "FFFFFFFFFFFFFFFFFF", 256) + + tst "operator not `isOdd`": + chkNotIsOdd(chk, "0", 8) + chkNotIsOdd(chk, "0", 16) + chkNotIsOdd(chk, "0", 32) + chkNotIsOdd(chk, "0", 64) + chkNotIsOdd(chk, "0", 128) + chkNotIsOdd(chk, "0", 256) + + chkNotIsOdd(chk, "4", 8) + chkNotIsOdd(chk, "4", 16) + chkNotIsOdd(chk, "4", 32) + chkNotIsOdd(chk, "4", 64) + chkNotIsOdd(chk, "4", 128) + chkNotIsOdd(chk, "4", 256) + + chkNotIsOdd(chk, "A", 8) + chkNotIsOdd(chk, "AAA", 16) + chkNotIsOdd(chk, "AAAA", 32) + chkNotIsOdd(chk, "FFFFFA", 64) + chkNotIsOdd(chk, "FFFFFFFFFFFFFFA", 128) + chkNotIsOdd(chk, "FFFFFFFFFFFFFFFFFA", 256) + + tst "operator `isEven`": + chkNotIsOdd(chk, "0", 8) + chkNotIsOdd(chk, "0", 16) + chkNotIsOdd(chk, "0", 32) + chkNotIsOdd(chk, "0", 64) + chkNotIsOdd(chk, "0", 128) + chkNotIsOdd(chk, "0", 256) + + chkNotIsOdd(chk, "4", 8) + chkNotIsOdd(chk, "4", 16) + chkNotIsOdd(chk, "4", 32) + chkNotIsOdd(chk, "4", 64) + chkNotIsOdd(chk, "4", 128) + chkNotIsOdd(chk, "4", 256) + + chkNotIsOdd(chk, "A", 8) + chkNotIsOdd(chk, "AAA", 16) + chkNotIsOdd(chk, "AAAA", 32) + chkNotIsOdd(chk, "FFFFFA", 64) + chkNotIsOdd(chk, "FFFFFFFFFFFFFFA", 128) + chkNotIsOdd(chk, "FFFFFFFFFFFFFFFFFA", 256) + + tst "operator not `isEven`": + chkIsOdd(chk, "1", 8) + chkIsOdd(chk, "1", 16) + chkIsOdd(chk, "1", 32) + chkIsOdd(chk, "1", 64) + chkIsOdd(chk, "1", 128) + chkIsOdd(chk, "1", 256) + + chkIsOdd(chk, "FF", 8) + chkIsOdd(chk, "FFF", 16) + chkIsOdd(chk, "FFFFF", 32) + chkIsOdd(chk, "FFFFFF", 64) + chkIsOdd(chk, "FFFFFFFFFFFFFFF", 128) + chkIsOdd(chk, "FFFFFFFFFFFFFFFFFF", 256) + +static: + testComparison(doAssert, ctTest) + +suite "Wider signed int comparison coverage": + testComparison(check, test) + suite "Signed int - Testing comparison operators": let a = 10'i16.stint(16)