typetraits: add toSigned, toUnsigned (#18445)
* typetraits: add toSigned, toUnsigned * improve and add tests Co-authored-by: Andreas Rumpf <rumpf_a@web.de> Co-authored-by: flywind <xzsflywind@gmail.com>
This commit is contained in:
parent
1807de38e5
commit
e78ef57c93
7 changed files with 85 additions and 33 deletions
|
|
@ -35,7 +35,7 @@ runnableExamples:
|
|||
assert C[float] is HoleyEnum
|
||||
|
||||
proc name*(t: typedesc): string {.magic: "TypeTrait".} =
|
||||
## Returns the name of the given type.
|
||||
## Returns the name of `t`.
|
||||
##
|
||||
## Alias for `system.\`$\`(t) <dollars.html#$,typedesc>`_ since Nim v0.20.
|
||||
runnableExamples:
|
||||
|
|
@ -43,7 +43,7 @@ proc name*(t: typedesc): string {.magic: "TypeTrait".} =
|
|||
doAssert name(seq[string]) == "seq[string]"
|
||||
|
||||
proc arity*(t: typedesc): int {.magic: "TypeTrait".} =
|
||||
## Returns the arity of the given type. This is the number of "type"
|
||||
## Returns the arity of `t`. This is the number of "type"
|
||||
## components or the number of generic parameters a given type `t` has.
|
||||
runnableExamples:
|
||||
doAssert arity(int) == 0
|
||||
|
|
@ -92,8 +92,7 @@ proc stripGenericParams*(t: typedesc): typedesc {.magic: "TypeTrait".} =
|
|||
doAssert stripGenericParams(int) is int
|
||||
|
||||
proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
|
||||
## This trait returns true if the type `t` is safe to use for
|
||||
## `copyMem`:idx:.
|
||||
## Returns true if `t` is safe to use for `copyMem`:idx:.
|
||||
##
|
||||
## Other languages name a type like these `blob`:idx:.
|
||||
|
||||
|
|
@ -289,9 +288,38 @@ since (1, 1):
|
|||
proc hasClosureImpl(n: NimNode): bool = discard "see compiler/vmops.nim"
|
||||
|
||||
proc hasClosure*(fn: NimNode): bool {.since: (1, 5, 1).} =
|
||||
## Return true if the func/proc/etc `fn` has `closure`.
|
||||
## Returns true if the func/proc/etc `fn` has `closure`.
|
||||
## `fn` has to be a resolved symbol of kind `nnkSym`. This
|
||||
## implies that the macro that calls this proc should accept `typed`
|
||||
## arguments and not `untyped` arguments.
|
||||
expectKind fn, nnkSym
|
||||
result = hasClosureImpl(fn)
|
||||
|
||||
template toUnsigned*(T: typedesc[SomeInteger and not range]): untyped =
|
||||
## Returns an unsigned type with same bit size as `T`.
|
||||
runnableExamples:
|
||||
assert int8.toUnsigned is uint8
|
||||
assert uint.toUnsigned is uint
|
||||
assert int.toUnsigned is uint
|
||||
# range types are currently unsupported:
|
||||
assert not compiles(toUnsigned(range[0..7]))
|
||||
when T is int8: uint8
|
||||
elif T is int16: uint16
|
||||
elif T is int32: uint32
|
||||
elif T is int64: uint64
|
||||
elif T is int: uint
|
||||
else: T
|
||||
|
||||
template toSigned*(T: typedesc[SomeInteger and not range]): untyped =
|
||||
## Returns a signed type with same bit size as `T`.
|
||||
runnableExamples:
|
||||
assert int8.toSigned is int8
|
||||
assert uint16.toSigned is int16
|
||||
# range types are currently unsupported:
|
||||
assert not compiles(toSigned(range[0..7]))
|
||||
when T is uint8: int8
|
||||
elif T is uint16: int16
|
||||
elif T is uint32: int32
|
||||
elif T is uint64: int64
|
||||
elif T is uint: int
|
||||
else: T
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue