tlateboundgenericparams.nim 3.1 KB

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