titerable.nim 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. discard """
  2. targets: "c js"
  3. """
  4. from stdtest/testutils import accept, reject, whenVMorJs
  5. # toSeq-like templates
  6. template toSeq2(a: iterable): auto =
  7. var ret: seq[typeof(a)]
  8. for ai in a: ret.add ai
  9. ret
  10. template toSeq3(a: iterable[string]): auto =
  11. var ret: seq[typeof(a)]
  12. for ai in a: ret.add ai
  13. ret
  14. template toSeq4[T](a: iterable[T]): auto =
  15. var ret: seq[typeof(a)]
  16. for ai in a: ret.add ai
  17. ret
  18. template toSeq5[T: SomeInteger](a: iterable[T]): auto =
  19. var ret: seq[typeof(a)]
  20. for ai in a: ret.add ai
  21. ret
  22. template toSeq6(a: iterable[int | float]): auto =
  23. var ret: seq[typeof(a)]
  24. for ai in a: ret.add ai
  25. ret
  26. template toSeq7(a: iterable[seq]): auto =
  27. var ret: seq[typeof(a)]
  28. for ai in a: ret.add ai
  29. ret
  30. template fn7b(a: untyped) = discard
  31. template fn7c(a: typed) = discard
  32. template fn7d(a: auto) = discard
  33. template fn7e[T](a: T) = discard
  34. template fn8a(a: iterable) = discard
  35. template fn8b[T](a: iterable[T]) = discard
  36. template fn8c(a: iterable[int]) = discard
  37. template bad1 =
  38. template fn4(a: int, b: iterable[float, int]) =
  39. discard
  40. template bad2 =
  41. proc fn4(a: iterable) = discard
  42. template bad3 =
  43. proc fn4(a: iterable[int]) = discard
  44. template good4 =
  45. template fn1(a: iterable) = discard
  46. template fn2(a: iterable[int]) = discard
  47. # iterators
  48. iterator iota(n: int): auto =
  49. for i in 0..<n: yield i
  50. iterator repeat[T](a: T, n: int): T =
  51. for i in 0..<n:
  52. yield a
  53. iterator myiter(n: int): auto =
  54. for i in 0..<n: yield $(i*2)
  55. when not defined(js):
  56. iterator iotaClosure(n: int): auto {.closure.} =
  57. for i in 0..<n: yield i
  58. template main() =
  59. let expected1 = @[0, 1, 2]
  60. let expected2 = @["0", "2"]
  61. doAssert toSeq2(myiter(2)) == expected2
  62. doAssert toSeq2(iota(3)) == expected1
  63. doAssert toSeq2(1.1.repeat(2)) == @[1.1, 1.1]
  64. whenVMorJs: discard
  65. do:
  66. doAssert toSeq2(iotaClosure(3)) == expected1
  67. when true:
  68. # MCS/UFCS
  69. doAssert iota(3).toSeq2() == expected1
  70. doAssert toSeq3(myiter(2)) == expected2
  71. accept toSeq3(myiter(2))
  72. reject toSeq3(iota(3))
  73. doAssert toSeq4(iota(3)) == expected1
  74. doAssert toSeq4(myiter(2)) == expected2
  75. doAssert toSeq4(0..2) == expected1
  76. doAssert toSeq4(items(0..2)) == expected1
  77. doAssert toSeq4(items(@[0,1,2])) == expected1
  78. reject toSeq4(@[0,1,2])
  79. reject toSeq4(13)
  80. block:
  81. accept fn8a(iota(3))
  82. accept fn7b(iota(3))
  83. reject fn7c(iota(3))
  84. reject fn7d(iota(3))
  85. reject fn7e(iota(3))
  86. block:
  87. fn8a(iota(3))
  88. reject fn8a(123)
  89. reject fn8c(123)
  90. reject fn8c(123.3)
  91. accept fn8c(items(@[1,2]))
  92. block:
  93. # shows that iterable is more restrictive than untyped
  94. reject fn8a(nonexistent)
  95. accept fn7b(nonexistent)
  96. reject fn7c(nonexistent)
  97. reject fn7d(nonexistent)
  98. reject fn7e(nonexistent)
  99. doAssert toSeq5(iota(3)) == expected1
  100. reject toSeq5(myiter(2))
  101. doAssert toSeq6(iota(3)) == expected1
  102. reject toSeq6(myiter(2))
  103. doAssert toSeq2("abc".repeat(3)) == @["abc", "abc", "abc"]
  104. doAssert toSeq2(@['x', 'y'].repeat(2)) == @[@['x', 'y'], @['x', 'y']]
  105. reject bad1
  106. reject bad2
  107. reject bad3
  108. accept good4
  109. static: main()
  110. main()