1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
discard """
output: "1\n10\n1\n10"
nimout: '''
bar instantiated with 1
bar instantiated with 10
'''
"""
import typetraits
type
Foo = object
proc defaultFoo: Foo = discard
proc defaultInt: int = 1
proc defaultTInt(T: type): int = 2
proc defaultTFoo[T](x: typedesc[T]): Foo = discard
proc defaultTOldSchool[T](x: typedesc[T]): T = discard
proc defaultTModern(T: type): T = discard
proc specializedDefault(T: type int): int = 10
proc specializedDefault(T: type string): string = "default"
converter intFromFoo(x: Foo): int = 3
proc consumeInt(x: int) =
discard
const activeTests = {1..100}
when true:
template test(n, body) =
when n in activeTests:
block:
body
template reject(x) =
static: assert(not compiles(x))
test 1:
proc t[T](val: T = defaultInt()) =
consumeInt val
t[int]()
reject t[string]()
test 2:
proc t1[T](val: T = defaultFoo()) =
static:
assert type(val).name == "int"
assert T.name == "int"
consumeInt val
# here, the converter should kick in, but notice
# how `val` is still typed `int` inside the proc.
t1[int]()
proc t2[T](val: T = defaultFoo()) =
discard
reject t2[string]()
test 3:
proc tInt[T](val = defaultInt()): string =
return type(val).name
doAssert tInt[int]() == "int"
doAssert tInt[string]() == "int"
proc tInt2[T](val = defaultTInt(T)): string =
return type(val).name
doAssert tInt2[int]() == "int"
doAssert tInt2[string]() == "int"
proc tDefTModern[T](val = defaultTModern(T)): string =
return type(val).name
doAssert tDefTModern[int]() == "int"
doAssert tDefTModern[string]() == "string"
doAssert tDefTModern[Foo]() == "Foo"
proc tDefTOld[T](val = defaultTOldSchool(T)): string =
return type(val).name
doAssert tDefTOld[int]() == "int"
doAssert tDefTOld[string]() == "string"
doAssert tDefTOld[Foo]() == "Foo"
test 4:
proc t[T](val: T = defaultTFoo(T)): string =
return type(val).name
doAssert t[int]() == "int"
doAssert t[Foo]() == "Foo"
reject t[string]()
test 5:
proc t1[T](a: T = specializedDefault(T)): T =
return a
doAssert t1[int]() == 10
doAssert t1[string]() == "default"
proc t2[T](a: T, b = specializedDefault(T)): auto =
return $a & $b
doAssert t2(5) == "510"
doAssert t2("string ") == "string default"
proc t3[T](a: T, b = specializedDefault(type(a))): auto =
return $a & $b
doAssert t3(100) == "10010"
doAssert t3("another ") == "another default"
test 6:
# https://github.com/nim-lang/Nim/issues/5595
type
Point[T] = object
x, y: T
proc getOrigin[T](): Point[T] = Point[T](x: 0, y: 0)
proc rotate[T](point: Point[T], radians: float,
origin = getOrigin[T]()): Point[T] =
discard
var p = getOrigin[float]()
var rotated = p.rotate(2.1)
test 7:
proc bar(x: static[int]) =
static: echo "bar instantiated with ", x
echo x
proc foo(x: static[int] = 1) =
bar(x)
foo()
foo(10)
foo(1)
foo(10)
|