diff options
-rw-r--r-- | compiler/semmagic.nim | 4 | ||||
-rw-r--r-- | lib/pure/typetraits.nim | 15 | ||||
-rw-r--r-- | tests/metatype/ttypetraits.nim | 40 |
3 files changed, 48 insertions, 11 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 0571032dc..1671a8a26 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -187,6 +187,10 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym) var operand = operand.skipTypes({tyGenericInst}) let cond = operand.kind == tyTuple and operand.n != nil result = newIntNodeT(toInt128(ord(cond)), traitCall, c.graph) + of "lenTuple": + var operand = operand.skipTypes({tyGenericInst}) + assert operand.kind == tyTuple, $operand.kind + result = newIntNodeT(toInt128(operand.len), traitCall, c.graph) of "distinctBase": var arg = operand.skipTypes({tyGenericInst}) if arg.kind == tyDistinct: diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index fd729b59e..04231db09 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -71,15 +71,14 @@ proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".} ## Returns base type for distinct types, works only for distinct types. ## compile time error otherwise -import std/macros - -macro lenTuple*(t: tuple): int {.since: (1, 1).} = - ## Return number of elements of `t` - newLit t.len -macro lenTuple*(t: typedesc[tuple]): int {.since: (1, 1).} = +proc lenTuple*(T: typedesc[tuple]): int {.magic: "TypeTrait", since: (1, 1).} ## Return number of elements of `T` - newLit t.len + +since (1, 1): + template lenTuple*(t: tuple): int = + ## Return number of elements of `t` + lenTuple(type(t)) since (1, 1): template get*(T: typedesc[tuple], i: static int): untyped = @@ -87,6 +86,8 @@ since (1, 1): # Note: `[]` currently gives: `Error: no generic parameters allowed for ...` type(default(T)[i]) +import std/macros + macro genericParams*(T: typedesc): untyped {.since: (1, 1).} = ## return tuple of generic params for generic `T` runnableExamples: diff --git a/tests/metatype/ttypetraits.nim b/tests/metatype/ttypetraits.nim index 218ffadc2..a6813ed00 100644 --- a/tests/metatype/ttypetraits.nim +++ b/tests/metatype/ttypetraits.nim @@ -92,7 +92,43 @@ block distinctBase: doAssert($distinctBase(typeof(b2)) == "string") doAssert($distinctBase(typeof(c2)) == "int") +block: # lenTuple + doAssert not compiles(lenTuple(int)) + + type + MyTupleType = (int,float,string) + + static: doAssert MyTupleType.lenTuple == 3 + + type + MyGenericTuple[T] = (T,int,float) + MyGenericAlias = MyGenericTuple[string] + static: doAssert MyGenericAlias.lenTuple == 3 + + type + MyGenericTuple2[T,U] = (T,U,string) + MyGenericTuple2Alias[T] = MyGenericTuple2[T,int] + + MyGenericTuple2Alias2 = MyGenericTuple2Alias[float] + static: doAssert MyGenericTuple2Alias2.lenTuple == 3 + + static: doAssert (int, float).lenTuple == 2 + static: doAssert (1, ).lenTuple == 1 + static: doAssert ().lenTuple == 0 + + let x = (1,2,) + doAssert x.lenTuple == 2 + doAssert ().lenTuple == 0 + doAssert (1,).lenTuple == 1 + doAssert (int,).lenTuple == 1 + doAssert type(x).lenTuple == 2 + doAssert type(x).default.lenTuple == 2 + type T1 = (int,float) + type T2 = T1 + doAssert T2.lenTuple == 2 + block genericParams: + type Foo[T1, T2]=object doAssert genericParams(Foo[float, string]) is (float, string) type Foo1 = Foo[float, int] @@ -103,10 +139,6 @@ block genericParams: doAssert genericParams(Foo2).get(1) is Foo1 doAssert (int,).get(0) is int doAssert (int, float).get(1) is float - static: doAssert (int, float).lenTuple == 2 - static: doAssert (1, ).lenTuple == 1 - static: doAssert ().lenTuple == 0 - ############################################## # bug 13095 |