From a8f50c4dbec8a79fb29ed80d9f161b76224dac7c Mon Sep 17 00:00:00 2001 From: mratsim Date: Fri, 16 Feb 2018 21:07:51 +0100 Subject: [PATCH] small quality of life fix + auto conversion of booleans --- src/mpint.nim | 2 +- src/private/utils.nim | 10 +++++----- src/uint_binary_ops.nim | 13 +++++++------ src/uint_bitwise_ops.nim | 12 ++++++------ src/uint_type.nim | 12 +++++++++++- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/mpint.nim b/src/mpint.nim index 4dd8f10..8899899 100644 --- a/src/mpint.nim +++ b/src/mpint.nim @@ -11,4 +11,4 @@ export uint_type, uint_init, uint_bitwise_ops, uint_binary_ops, - uint_comparison \ No newline at end of file + uint_comparison diff --git a/src/private/utils.nim b/src/private/utils.nim index 23994e3..0f6134a 100644 --- a/src/private/utils.nim +++ b/src/private/utils.nim @@ -4,6 +4,11 @@ import ../uint_type, macros +macro getSubType*(T: typedesc): untyped = + ## Returns the subtype of a generic type + ## MpUint[uint32] --> uint32 + getTypeInst(T)[1][1] + proc bit_length*[T: BaseUint](n: T): int {.noSideEffect.}= ## Calculates how many bits are necessary to represent the number @@ -54,11 +59,6 @@ proc asDoubleUint*[T: BaseUint](n: T): auto {.noSideEffect, inline.} = n.asUint.Double -macro getSubType*(T: typedesc): untyped = - ## Returns the subtype of a generic type - ## MpUint[uint32] --> uint32 - getTypeInst(T)[1][1] - proc toMpUint*[T: SomeInteger](n: T): auto {.noSideEffect, inline.} = ## Cast an integer to the corresponding size MpUint diff --git a/src/uint_binary_ops.nim b/src/uint_binary_ops.nim index cd552a5..fc06207 100644 --- a/src/uint_binary_ops.nim +++ b/src/uint_binary_ops.nim @@ -10,11 +10,11 @@ proc `+=`*[T: MpUint](x: var T, y: T) {.noSideEffect.}= # # Optimized assembly should contain adc instruction (add with carry) # Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64) - type Base = type x.lo + type MpBase = type x.lo let tmp = x.lo x.lo += y.lo - x.hi += (x.lo < tmp).Base + y.hi + x.hi += MpBase(x.lo < tmp) + y.hi proc `+`*[T: MpUint](x, y: T): T {.noSideEffect, noInit, inline.}= # Addition for multi-precision unsigned int @@ -26,11 +26,11 @@ proc `-=`*[T: MpUint](x: var T, y: T) {.noSideEffect.}= # # Optimized assembly should contain sbb instruction (substract with borrow) # Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64) - type MPBase = type x.lo + type MpBase = type x.lo let tmp = x.lo x.lo -= y.lo - x.hi -= (x.lo > tmp).MPBase + y.hi + x.hi -= MpBase(x.lo > tmp) + y.hi proc `-`*[T: MpUint](x, y: T): T {.noSideEffect, noInit, inline.}= # Substraction for multi-precision unsigned int @@ -79,7 +79,7 @@ template naiveMulImpl[T: MpUint](x, y: T): MpUint[T] = # - More total operations means more register moves let # cannot be const, compile-time sizeof only works for simple types - size = (T.sizeof * 8) + size = T.sizeof * 8 halfSize = size div 2 let z0 = naiveMul(x.lo, y.lo) @@ -104,4 +104,5 @@ proc naiveMul[T: BaseUint](x, y: T): MpUint[T] {.noSideEffect, noInit, inline.}= naiveMulImpl(x.toMpUint, y.toMpUint) else: # Case: at least uint128 * uint128 --> uint256 - naiveMulImpl(x, y) \ No newline at end of file + naiveMulImpl(x, y) + diff --git a/src/uint_bitwise_ops.nim b/src/uint_bitwise_ops.nim index 3aafe8f..59fd05a 100644 --- a/src/uint_bitwise_ops.nim +++ b/src/uint_bitwise_ops.nim @@ -35,10 +35,10 @@ proc `shl`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}= return x let # cannot be const, compile-time sizeof only works for simple types - size = (T.sizeof * 8) + size = T.sizeof * 8 halfSize = size div 2 - type Sub = getSubType T + type Sub = type x.lo if y < halfSize: result.hi = (x.hi shl y) or (x.lo shr (halfSize - y)) @@ -54,10 +54,10 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}= return x let # cannot be const, compile-time sizeof only works for simple types - size = (T.sizeof * 8) + size = T.sizeof * 8 halfSize = size div 2 - type Sub = getSubType T + type Sub = type x.lo if y < halfSize: result.lo = (x.lo shr y) or (x.hi shl (halfSize - y)) @@ -80,7 +80,7 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}= # proc `shl`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}= # ## Compute the `shift left` operation of x and y -# type Sub = getSubType T +# type Sub = type x.lo # # let # cannot be const, compile-time sizeof only works for simple types # size = Sub(T.sizeof * 8) @@ -102,7 +102,7 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}= # proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}= # ## Compute the `shift right` operation of x and y -# type Sub = getSubType T +# type Sub = type x.lo # # let # cannot be const, compile-time sizeof only works for simple types # size = Sub(T.sizeof * 8) diff --git a/src/uint_type.nim b/src/uint_type.nim index bf0099a..50f4572 100644 --- a/src/uint_type.nim +++ b/src/uint_type.nim @@ -13,4 +13,14 @@ type UInt128* = MpUint[uint64] - UInt256* = MpUint[UInt128] \ No newline at end of file + UInt256* = MpUint[UInt128] + + +template convBool(typ: typedesc): untyped = + converter boolMpUint*(b: bool): MpUint[typ] {.noSideEffect, inline.}= + result.lo = b.typ + +convBool(uint8) +convBool(uint16) +convBool(uint32) +convBool(uint64) \ No newline at end of file