Add explicit generic conversion operators (#56)

The new `to` operators that can be used to constuct Stint types from
regular integer types. These are intented for usage in generic code
such as rlp.nim

Also fixes a bug preventing construction of Stint values from unsigned
integers (because they lack an unary `-` operator).
This commit is contained in:
zah 2018-06-27 13:18:48 +03:00 committed by Mamy Ratsimbazafy
parent 36ec850c4f
commit 6ae8de932d
2 changed files with 23 additions and 3 deletions

View File

@ -56,14 +56,23 @@ func stint*[T: SomeInteger](n: T, bits: static[int]): StInt[bits] {.inline.}=
when result.data is IntImpl:
static_check_size(T, bits)
if n < 0:
assign_least_significant_words(result, -n)
result = -result
when T is SomeSignedInt:
if n < 0:
assign_least_significant_words(result, -n)
result = -result
else:
assign_least_significant_words(result, n)
else:
assign_least_significant_words(result, n)
else:
result.data = (type result.data)(n)
func to*(x: SomeInteger, T: typedesc[Stint]): T =
stint(x, result.bits)
func to*(x: SomeUnsignedInt, T: typedesc[StUint]): T =
stuint(x, result.bits)
func toInt*(num: Stint or StUint): int {.inline.}=
# Returns as int. Result is modulo 2^(sizeof(int)
num.data.least_significant_word.int

View File

@ -113,6 +113,17 @@ suite "Testing conversion functions: Hex, Bytes, Endianness using secp256k1 curv
SECPK1_N = "115792089237316195423570985008687907852837564279074904382605163141518161494337".u256
SECPK1_N_BYTES = [byte(255), 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 186, 174, 220, 230, 175, 72, 160, 59, 191, 210, 94, 140, 208, 54, 65, 65]
test "explicit conversions from basic types":
type
UInt256 = Stuint[256]
Int128 = Stint[128]
let x = 10.uint16
check:
x.to(UInt256).bits == 256
x.to(Int128).bits == 128
test "hex -> uint256":
check: SECPK1_N_HEX.parse(Stuint[256], base = 16) == SECPK1_N