Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions lib/pure/typetraits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ since (1, 1):
# Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
type(default(T)[i])

type StaticParam*[value] = object
## used to wrap a static value in `genericParams`

import std/macros

macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
## return tuple of generic params for generic `T`
runnableExamples:
type Foo[T1, T2]=object
doAssert genericParams(Foo[float, string]) is (float, string)
macro genericParamsImpl(T: typedesc): untyped =
# auxiliary macro needed, can't do it directly in `genericParams`
result = newNimNode(nnkTupleConstr)
var impl = getTypeImpl(T)
expectKind(impl, nnkBracketExpr)
Expand All @@ -107,11 +107,33 @@ macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
continue
of nnkBracketExpr:
for i in 1..<impl.len:
result.add impl[i]
let ai = impl[i]
var ret: NimNode
case ai.typeKind
of ntyStatic:
ret = newTree(nnkBracketExpr, @[bindSym"StaticParam", ai])
of ntyTypeDesc:
ret = ai
else:
assert false, $(ai.typeKind, ai.kind)
result.add ret
break
else:
error "wrong kind: " & $impl.kind

since (1, 1):
template genericParams*(T: typedesc): untyped =
## return tuple of generic params for generic `T`
runnableExamples:
type Foo[T1, T2]=object
doAssert genericParams(Foo[float, string]) is (float, string)
type Bar[N: static float, T] = object
doAssert genericParams(Bar[1.0, string]) is (StaticParam[1.0], string)
doAssert genericParams(Bar[1.0, string]).get(0).value == 1.0

type T2 = T
genericParamsImpl(T2)

when isMainModule:
static:
doAssert $type(42) == "int"
Expand Down
45 changes: 44 additions & 1 deletion tests/metatype/ttypetraits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ block: # lenTuple
doAssert T2.lenTuple == 2

block genericParams:

type Foo[T1, T2]=object
doAssert genericParams(Foo[float, string]) is (float, string)
type Foo1 = Foo[float, int]
Expand All @@ -140,6 +139,50 @@ block genericParams:
doAssert (int,).get(0) is int
doAssert (int, float).get(1) is float

type Bar[N: static int, T] = object
type Bar3 = Bar[3, float]
doAssert genericParams(Bar3) is (StaticParam[3], float)
doAssert genericParams(Bar3).get(0) is StaticParam
doAssert genericParams(Bar3).get(0).value == 3
doAssert genericParams(Bar[3, float]).get(0).value == 3

type
VectorElementType = SomeNumber | bool
Vec[N: static[int], T: VectorElementType] = object
arr: array[N, T]
Vec4[T: VectorElementType] = Vec[4,T]
Vec4f = Vec4[float32]

MyTupleType = (int,float,string)
MyGenericTuple[T] = (T,int,float)
MyGenericAlias = MyGenericTuple[string]
MyGenericTuple2[T,U] = (T,U,string)
MyGenericTuple2Alias[T] = MyGenericTuple2[T,int]
MyGenericTuple2Alias2 = MyGenericTuple2Alias[float]

doAssert genericParams(MyGenericAlias) is (string,)
doAssert genericHead(MyGenericAlias) is MyGenericTuple
doAssert genericParams(MyGenericTuple2Alias2) is (float,)
doAssert genericParams(MyGenericTuple2[float, int]) is (float, int)
doAssert genericParams(MyGenericAlias) is (string,)
doAssert genericParams(Vec4f) is (float32,)
doAssert genericParams(Vec[4, bool]) is (StaticParam[4], bool)

block:
type Foo[T1, T2]=object
doAssert genericParams(Foo[float, string]) is (float, string)
type Bar[N: static float, T] = object
doAssert genericParams(Bar[1.0, string]) is (StaticParam[1.0], string)
type Bar2 = Bar[2.0, string]
doAssert genericParams(Bar2) is (StaticParam[2.0], string)
type Bar3 = Bar[1.0 + 2.0, string]
doAssert genericParams(Bar3) is (StaticParam[3.0], string)

const F = 5.0
type Bar4 = Bar[F, string]
doAssert genericParams(Bar4) is (StaticParam[5.0], string)
doAssert genericParams(Bar[F, string]) is (StaticParam[5.0], string)

##############################################
# bug 13095

Expand Down