Skip to content

Commit 04bdf61

Browse files
committed
typetraits: fix #6454; genericParams; tuple len; tuple type get
1 parent 15043d3 commit 04bdf61

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

lib/pure/typetraits.nim

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,44 @@ proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".}
7070
## Returns base type for distinct types, works only for distinct types.
7171
## compile time error otherwise
7272

73+
import std/macros
74+
75+
macro len*(t: tuple): int =
76+
## Return number of elements of `t`
77+
newLit t.len
78+
79+
template len*(T: typedesc[tuple]): untyped =
80+
## Return number of elements of `T`
81+
len(default(T))
82+
83+
template get*(T: typedesc[tuple], i: static int): untyped =
84+
## Return `i`th element of `T`
85+
# Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
86+
type(default(T)[i])
87+
88+
macro genericParams*(T: typedesc): untyped =
89+
## return tuple of generic params for generic `T`
90+
runnableExamples:
91+
type Foo[T1, T2]=object
92+
doAssert genericParams(Foo[float, string]) is (float, string)
93+
result = newNimNode(nnkTupleConstr)
94+
var impl = getTypeImpl(T)
95+
expectKind(impl, nnkBracketExpr)
96+
impl = impl[1]
97+
while true:
98+
case impl.kind
99+
of nnkSym:
100+
impl = impl.getImpl
101+
continue
102+
of nnkTypeDef:
103+
impl = impl[2]
104+
continue
105+
of nnkBracketExpr:
106+
for i in 1..<impl.len:
107+
result.add impl[i]
108+
break
109+
else:
110+
error "wrong kind: " & $impl.kind
73111

74112
when isMainModule:
75113
static:

tests/metatype/ttypetraits.nim

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ block: # typeToString
4444
doAssert (tuple[a: C2b[MyInt, C4[cstring]], b: cint, c: float]).name3 ==
4545
"tuple[a: C2b{C}[MyInt{int}, C4[cstring]], b: cint{int32}, c: float]"
4646

47-
48-
#----------------------------------------------------
49-
5047
block distinctBase:
5148
block:
5249
type
@@ -90,4 +87,17 @@ block distinctBase:
9087
doAssert($distinctBase(typeof(b2)) == "string")
9188
doAssert($distinctBase(typeof(c2)) == "int")
9289

93-
90+
block genericParams:
91+
type Foo[T1, T2]=object
92+
doAssert genericParams(Foo[float, string]) is (float, string)
93+
type Foo1 = Foo[float, int]
94+
doAssert genericParams(Foo1) is (float, int)
95+
type Foo2 = Foo[float, Foo1]
96+
doAssert genericParams(Foo2) is (float, Foo[float, int])
97+
doAssert genericParams(Foo2) is (float, Foo1)
98+
doAssert genericParams(Foo2).get(1) is Foo1
99+
doAssert (int,).get(0) is int
100+
doAssert (int, float).get(1) is float
101+
static: doAssert (int, float).len == 2
102+
static: doAssert (1, ).len == 1
103+
static: doAssert ().len == 0

0 commit comments

Comments
 (0)