Skip to content

Commit 6f61c6a

Browse files
committed
make genericParams support static[T] generic params
1 parent 273a935 commit 6f61c6a

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

lib/pure/typetraits.nim

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ since (1, 1):
8686
# Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
8787
type(default(T)[i])
8888

89+
type WrapStatic*[Val] = object
90+
## used to wrap a static value in `genericParams`
91+
8992
import std/macros
9093

91-
macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
92-
## return tuple of generic params for generic `T`
93-
runnableExamples:
94-
type Foo[T1, T2]=object
95-
doAssert genericParams(Foo[float, string]) is (float, string)
94+
macro genericParamsImpl(T: typedesc): untyped =
95+
# auxiliary macro needed, can't do it directly in `genericParams`
9696
result = newNimNode(nnkTupleConstr)
9797
var impl = getTypeImpl(T)
9898
expectKind(impl, nnkBracketExpr)
@@ -107,11 +107,33 @@ macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
107107
continue
108108
of nnkBracketExpr:
109109
for i in 1..<impl.len:
110-
result.add impl[i]
110+
let ai = impl[i]
111+
var ret: NimNode
112+
case ai.typeKind
113+
of ntyStatic:
114+
ret = newTree(nnkBracketExpr, @[bindSym"WrapStatic", ai])
115+
of ntyTypeDesc:
116+
ret = ai
117+
else:
118+
assert false, $(ai.typeKind, ai.kind)
119+
result.add ret
111120
break
112121
else:
113122
error "wrong kind: " & $impl.kind
114123

124+
since (1, 1):
125+
template genericParams*(T: typedesc): untyped =
126+
## return tuple of generic params for generic `T`
127+
runnableExamples:
128+
type Foo[T1, T2]=object
129+
doAssert genericParams(Foo[float, string]) is (float, string)
130+
type Bar[N: static float, T] = object
131+
doAssert genericParams(Bar[1.0, string]) is (WrapStatic[1.0], string)
132+
doAssert genericParams(Bar[1.0, string]).get(0).Val == 1.0
133+
134+
type T2 = T
135+
genericParamsImpl(T2)
136+
115137
when isMainModule:
116138
static:
117139
doAssert $type(42) == "int"

tests/metatype/ttypetraits.nim

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ block: # lenTuple
128128
doAssert T2.lenTuple == 2
129129

130130
block genericParams:
131-
132131
type Foo[T1, T2]=object
133132
doAssert genericParams(Foo[float, string]) is (float, string)
134133
type Foo1 = Foo[float, int]
@@ -140,6 +139,50 @@ block genericParams:
140139
doAssert (int,).get(0) is int
141140
doAssert (int, float).get(1) is float
142141

142+
type Bar[N: static int, T] = object
143+
type Bar3 = Bar[3, float]
144+
doAssert genericParams(Bar3) is (WrapStatic[3], float)
145+
doAssert genericParams(Bar3).get(0) is WrapStatic
146+
doAssert genericParams(Bar3).get(0).Val == 3
147+
doAssert genericParams(Bar[3, float]).get(0).Val == 3
148+
149+
type
150+
VectorElementType = SomeNumber | bool
151+
Vec[N: static[int], T: VectorElementType] = object
152+
arr: array[N, T]
153+
Vec4[T: VectorElementType] = Vec[4,T]
154+
Vec4f = Vec4[float32]
155+
156+
MyTupleType = (int,float,string)
157+
MyGenericTuple[T] = (T,int,float)
158+
MyGenericAlias = MyGenericTuple[string]
159+
MyGenericTuple2[T,U] = (T,U,string)
160+
MyGenericTuple2Alias[T] = MyGenericTuple2[T,int]
161+
MyGenericTuple2Alias2 = MyGenericTuple2Alias[float]
162+
163+
doAssert genericParams(MyGenericAlias) is (string,)
164+
doAssert genericHead(MyGenericAlias) is MyGenericTuple
165+
doAssert genericParams(MyGenericTuple2Alias2) is (float,)
166+
doAssert genericParams(MyGenericTuple2[float, int]) is (float, int)
167+
doAssert genericParams(MyGenericAlias) is (string,)
168+
doAssert genericParams(Vec4f) is (float32,)
169+
doAssert genericParams(Vec[4, bool]) is (WrapStatic[4], bool)
170+
171+
block:
172+
type Foo[T1, T2]=object
173+
doAssert genericParams(Foo[float, string]) is (float, string)
174+
type Bar[N: static float, T] = object
175+
doAssert genericParams(Bar[1.0, string]) is (WrapStatic[1.0], string)
176+
type Bar2 = Bar[2.0, string]
177+
doAssert genericParams(Bar2) is (WrapStatic[2.0], string)
178+
type Bar3 = Bar[1.0 + 2.0, string]
179+
doAssert genericParams(Bar3) is (WrapStatic[3.0], string)
180+
181+
const F = 5.0
182+
type Bar4 = Bar[F, string]
183+
doAssert genericParams(Bar4) is (WrapStatic[5.0], string)
184+
doAssert genericParams(Bar[F, string]) is (WrapStatic[5.0], string)
185+
143186
##############################################
144187
# bug 13095
145188

0 commit comments

Comments
 (0)