File: titerable.nim

package info (click to toggle)
nim 2.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,911,644 kB
  • sloc: sh: 24,603; ansic: 1,761; python: 1,492; makefile: 1,013; sql: 298; asm: 141; xml: 13
file content (143 lines) | stat: -rw-r--r-- 3,131 bytes parent folder | download | duplicates (3)
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
discard """
  targets: "c js"
"""

from stdtest/testutils import accept, reject, whenVMorJs

# toSeq-like templates

template toSeq2(a: iterable): auto =
  var ret: seq[typeof(a)]
  for ai in a: ret.add ai
  ret

template toSeq3(a: iterable[string]): auto =
  var ret: seq[typeof(a)]
  for ai in a: ret.add ai
  ret

template toSeq4[T](a: iterable[T]): auto =
  var ret: seq[typeof(a)]
  for ai in a: ret.add ai
  ret

template toSeq5[T: SomeInteger](a: iterable[T]): auto =
  var ret: seq[typeof(a)]
  for ai in a: ret.add ai
  ret

template toSeq6(a: iterable[int | float]): auto =
  var ret: seq[typeof(a)]
  for ai in a: ret.add ai
  ret

template toSeq7(a: iterable[seq]): auto =
  var ret: seq[typeof(a)]
  for ai in a: ret.add ai
  ret

template fn7b(a: untyped) = discard
template fn7c(a: typed) = discard
template fn7d(a: auto) = discard
template fn7e[T](a: T) = discard

template fn8a(a: iterable) = discard
template fn8b[T](a: iterable[T]) = discard
template fn8c(a: iterable[int]) = discard

template bad1 =
  template fn4(a: int, b: iterable[float, int]) =
    discard

template bad2 =
  proc fn4(a: iterable) = discard

template bad3 =
  proc fn4(a: iterable[int]) = discard

template good4 =
  template fn1(a: iterable) = discard
  template fn2(a: iterable[int]) = discard

# iterators
iterator iota(n: int): auto =
  for i in 0..<n: yield i

iterator repeat[T](a: T, n: int): T =
  for i in 0..<n:
    yield a

iterator myiter(n: int): auto =
  for i in 0..<n: yield $(i*2)

when not defined(js):
  iterator iotaClosure(n: int): auto {.closure.} =
    for i in 0..<n: yield i

template main() =
  let expected1 = @[0, 1, 2]
  let expected2 = @["0", "2"]

  doAssert toSeq2(myiter(2)) == expected2
  doAssert toSeq2(iota(3)) == expected1
  doAssert toSeq2(1.1.repeat(2)) == @[1.1, 1.1]

  whenVMorJs: discard
  do:
    doAssert toSeq2(iotaClosure(3)) == expected1

  when true:
    # MCS/UFCS
    doAssert iota(3).toSeq2() == expected1

  doAssert toSeq3(myiter(2)) == expected2
  accept toSeq3(myiter(2))
  reject toSeq3(iota(3))

  doAssert toSeq4(iota(3)) == expected1
  doAssert toSeq4(myiter(2)) == expected2
  
  doAssert toSeq4(0..2) == expected1
  doAssert toSeq4(items(0..2)) == expected1
  doAssert toSeq4(items(@[0,1,2])) == expected1
  reject toSeq4(@[0,1,2])
  reject toSeq4(13)

  block:
    accept fn8a(iota(3))
    accept fn7b(iota(3))
    reject fn7c(iota(3))
    reject fn7d(iota(3))
    reject fn7e(iota(3))

  block:
    fn8a(iota(3))
    reject fn8a(123)
    reject fn8c(123)
    reject fn8c(123.3)
    accept fn8c(items(@[1,2]))

  block:
    # shows that iterable is more restrictive than untyped
    reject fn8a(nonexistent)
    accept fn7b(nonexistent)
    reject fn7c(nonexistent)
    reject fn7d(nonexistent)
    reject fn7e(nonexistent)

  doAssert toSeq5(iota(3)) == expected1
  reject toSeq5(myiter(2))

  doAssert toSeq6(iota(3)) == expected1
  reject toSeq6(myiter(2))

  doAssert toSeq2("abc".repeat(3)) == @["abc", "abc", "abc"]
  doAssert toSeq2(@['x', 'y'].repeat(2)) == @[@['x', 'y'], @['x', 'y']]

  reject bad1
  reject bad2
  reject bad3
  accept good4

static: main()
main()