Add optional recursive arg to distinctBase (v2) (#18659)
* Add optional recursive arg to distinctBase * Add docs and examples Co-authored-by: ALANVF <alan.invents@gmail.com>
This commit is contained in:
parent
988c02b7cb
commit
8ce782d463
4 changed files with 18 additions and 10 deletions
|
|
@ -190,9 +190,10 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
||||||
result = newIntNodeT(toInt128(operand.len), traitCall, c.idgen, c.graph)
|
result = newIntNodeT(toInt128(operand.len), traitCall, c.idgen, c.graph)
|
||||||
of "distinctBase":
|
of "distinctBase":
|
||||||
var arg = operand.skipTypes({tyGenericInst})
|
var arg = operand.skipTypes({tyGenericInst})
|
||||||
|
let rec = semConstExpr(c, traitCall[2]).intVal != 0
|
||||||
while arg.kind == tyDistinct:
|
while arg.kind == tyDistinct:
|
||||||
arg = arg.base
|
arg = arg.base.skipTypes(skippedTypes + {tyGenericInst})
|
||||||
arg = arg.skipTypes(skippedTypes + {tyGenericInst})
|
if not rec: break
|
||||||
result = getTypeDescNode(c, arg, operand.owner, traitCall.info)
|
result = getTypeDescNode(c, arg, operand.owner, traitCall.info)
|
||||||
else:
|
else:
|
||||||
localError(c.config, traitCall.info, "unknown trait: " & s)
|
localError(c.config, traitCall.info, "unknown trait: " & s)
|
||||||
|
|
|
||||||
|
|
@ -110,25 +110,32 @@ template pointerBase*[T](_: typedesc[ptr T | ref T]): typedesc =
|
||||||
assert (var s = "abc"; s[0].addr).typeof.pointerBase is char
|
assert (var s = "abc"; s[0].addr).typeof.pointerBase is char
|
||||||
T
|
T
|
||||||
|
|
||||||
proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".} =
|
proc distinctBase*(T: typedesc, recursive: static bool = true): typedesc {.magic: "TypeTrait".} =
|
||||||
## Returns the base type for distinct types, or the type itself otherwise.
|
## Returns the base type for distinct types, or the type itself otherwise.
|
||||||
|
## If `recursive` is false, only the immediate distinct base will be returned.
|
||||||
##
|
##
|
||||||
## **See also:**
|
## **See also:**
|
||||||
## * `distinctBase template <#distinctBase.t,T>`_
|
## * `distinctBase template <#distinctBase.t,T,static[bool]>`_
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
type MyInt = distinct int
|
type MyInt = distinct int
|
||||||
|
type MyOtherInt = distinct MyInt
|
||||||
doAssert distinctBase(MyInt) is int
|
doAssert distinctBase(MyInt) is int
|
||||||
|
doAssert distinctBase(MyOtherInt) is int
|
||||||
|
doAssert distinctBase(MyOtherInt, false) is MyInt
|
||||||
doAssert distinctBase(int) is int
|
doAssert distinctBase(int) is int
|
||||||
|
|
||||||
since (1, 1):
|
since (1, 1):
|
||||||
template distinctBase*[T](a: T): untyped =
|
template distinctBase*[T](a: T, recursive: static bool = true): untyped =
|
||||||
## Overload of `distinctBase <#distinctBase,typedesc>`_ for values.
|
## Overload of `distinctBase <#distinctBase,typedesc,static[bool]>`_ for values.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
type MyInt = distinct int
|
type MyInt = distinct int
|
||||||
|
type MyOtherInt = distinct MyInt
|
||||||
doAssert 12.MyInt.distinctBase == 12
|
doAssert 12.MyInt.distinctBase == 12
|
||||||
|
doAssert 12.MyOtherInt.distinctBase == 12
|
||||||
|
doAssert 12.MyOtherInt.distinctBase(false) is MyInt
|
||||||
doAssert 12.distinctBase == 12
|
doAssert 12.distinctBase == 12
|
||||||
when T is distinct:
|
when T is distinct:
|
||||||
distinctBase(typeof(a))(a)
|
distinctBase(typeof(a), recursive)(a)
|
||||||
else: # avoids hint ConvFromXtoItselfNotNeeded
|
else: # avoids hint ConvFromXtoItselfNotNeeded
|
||||||
a
|
a
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ proc initToJsonOptions*(): ToJsonOptions =
|
||||||
## initializes `ToJsonOptions` with sane options.
|
## initializes `ToJsonOptions` with sane options.
|
||||||
ToJsonOptions(enumMode: joptEnumOrd, jsonNodeMode: joptJsonNodeAsRef)
|
ToJsonOptions(enumMode: joptEnumOrd, jsonNodeMode: joptJsonNodeAsRef)
|
||||||
|
|
||||||
proc distinctBase(T: typedesc): typedesc {.magic: "TypeTrait".}
|
proc distinctBase(T: typedesc, recursive: static bool = true): typedesc {.magic: "TypeTrait".}
|
||||||
template distinctBase[T](a: T): untyped = distinctBase(typeof(a))(a)
|
template distinctBase[T](a: T, recursive: static bool = true): untyped = distinctBase(typeof(a), recursive)(a)
|
||||||
|
|
||||||
macro getDiscriminants(a: typedesc): seq[string] =
|
macro getDiscriminants(a: typedesc): seq[string] =
|
||||||
## return the discriminant keys
|
## return the discriminant keys
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
|
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
|
||||||
## imported from typetraits
|
## imported from typetraits
|
||||||
|
|
||||||
proc distinctBase(T: typedesc): typedesc {.magic: "TypeTrait".}
|
proc distinctBase(T: typedesc, recursive: static bool = true): typedesc {.magic: "TypeTrait".}
|
||||||
## imported from typetraits
|
## imported from typetraits
|
||||||
|
|
||||||
proc repr*(x: NimNode): string {.magic: "Repr", noSideEffect.}
|
proc repr*(x: NimNode): string {.magic: "Repr", noSideEffect.}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue