mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 09:24:36 +00:00
146 lines
3.1 KiB
Nim
146 lines
3.1 KiB
Nim
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)
|
|
|