File: UnfoldSequence.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (80 lines) | stat: -rw-r--r-- 2,317 bytes parent folder | download
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
// RUN: %target-run-simple-swift
// REQUIRES: executable_test

import StdlibUnittest
import StdlibCollectionUnittest

var UnfoldTests = TestSuite("UnfoldSequence")

UnfoldTests.test("sequence(state:next:)") {
  // FIXME: The full type signatures on these closures should not be
  // necessary, but at the moment the compiler gives very confusing errors if
  // we don't have them.

  let s0 = sequence(state: 1, next: { (val: inout Int) -> Int? in
    defer { val *= 2 }; return val > 16 ? nil : val
  })
  checkSequence([1,2,4,8,16], s0)

  let s1 = sequence(state: (), next: { (_: inout ()) -> Int? in 1 })
  checkSequence([1, 1, 1], s1.prefix(3))

  let s2 = sequence(state: (1..<6).makeIterator(), next: {
    (iter: inout Range<Int>.Iterator) in
    iter.next()
  })
  checkSequence(1..<6, s2)

  // Make sure we don't evaluate any step in advance
  var calls = 0
  var s3 = sequence(state: 0, next: { (val: inout Int) -> Int? in
    calls += 1; val += 1; return val
  })
  for i in 1..<6 {
    expectEqual(i, s3.next())
    expectEqual(i, calls)
  }

  // Make sure we don't invoke next() after it returns nil
  calls = 0
  var s4 = sequence(state: 1, next : { (val: inout Int) -> Int? in
    calls += 1; defer { val *= 2 }; return val > 16 ? nil : val
  })
  checkSequence([1,2,4,8,16], s4)
  expectEqual(6, calls)

  let s5 = sequence(state: (), next: { (_: inout ()) -> Int? in nil })
  checkSequence([], s5)

  // This is similar to s0 except calling the `next` closure after it returns
  // nil starts returning values again.
  let s6 = sequence(state: 1, next: { (val: inout Int) -> Int? in
    defer { val *= 2 }
    return val == 32 ? nil : val
  })
  checkSequence([1,2,4,8,16], s6)
}

UnfoldTests.test("sequence(first:next:)") {
  let s0 = sequence(first: 1, next: { $0 < 50 ? $0 * 2 : nil })
  expectEqualSequence([1, 2, 4, 8, 16, 32, 64], s0)

  // Make sure we don't evaluate any step in advance
  var calls = 0
  var s1 = sequence(first: 0, next: { calls += 1; return $0 + 1 })
  for i in 0..<5 {
    expectEqual(i, s1.next())
    expectEqual(i, calls)
  }

  // Make sure we don't invoke next() after it returns nil
  calls = 0
  let s2 = sequence(first: 1, next: {
    calls += 1
    return $0 >= 16 ? nil : $0 * 2
  })
  checkSequence([1,2,4,8,16], s2)
  expectEqual(5, calls)
}

runAllTests()