From e2de229a924575ff66bbe09150b8f00caf2635a6 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 7 Jan 2020 14:53:47 -0800 Subject: [PATCH] typetraits: fix #6454; genericParams; tuple len; tuple type get --- lib/pure/typetraits.nim | 38 ++++++++++++++++++++++++++++++++++ tests/metatype/ttypetraits.nim | 14 +++++++++++++ 2 files changed, 52 insertions(+) diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 24aed52b0ed2e..ef0703b1387c6 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -77,6 +77,44 @@ proc isNamedTuple*(T: typedesc): bool = # see https://github.com/nim-lang/Nim/issues/8861#issue-356631191 return false +import std/macros + +macro len*(t: tuple): int = + ## Return number of elements of `t` + newLit t.len + +template len*(T: typedesc[tuple]): untyped = + ## Return number of elements of `T` + len(default(T)) + +template get*(T: typedesc[tuple], i: static int): untyped = + ## Return `i`th element of `T` + # Note: `[]` currently gives: `Error: no generic parameters allowed for ...` + type(default(T)[i]) + +macro 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) + result = newNimNode(nnkTupleConstr) + var impl = getTypeImpl(T) + expectKind(impl, nnkBracketExpr) + impl = impl[1] + while true: + case impl.kind + of nnkSym: + impl = impl.getImpl + continue + of nnkTypeDef: + impl = impl[2] + continue + of nnkBracketExpr: + for i in 1..