Skip to content

Commit 87c467c

Browse files
committed
Extracted internal classes. Removed AnySequence.
1 parent 9228c04 commit 87c467c

File tree

4 files changed

+268
-203
lines changed

4 files changed

+268
-203
lines changed

stdlib/public/core/DropFirst.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//===-- DropFirst.swift ---------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// A sequence that lazily consumes and drops `n` elements from an underlying
14+
/// `Base` iterator before possibly returning the first available element.
15+
///
16+
/// The underlying iterator's sequence may be infinite.
17+
///
18+
/// This is a class - we require reference semantics to keep track
19+
/// of how many elements we've already dropped from the underlying sequence.
20+
@_versioned
21+
@_fixed_layout
22+
public class _DropFirstSequence<Base : IteratorProtocol>
23+
: Sequence, IteratorProtocol {
24+
25+
@_versioned
26+
internal var _iterator: Base
27+
@_versioned
28+
internal let _limit: Int
29+
@_versioned
30+
internal var _dropped: Int
31+
32+
@_versioned
33+
@_inlineable
34+
internal init(_iterator: Base, limit: Int, dropped: Int = 0) {
35+
self._iterator = _iterator
36+
self._limit = limit
37+
self._dropped = dropped
38+
}
39+
40+
@_versioned
41+
@_inlineable
42+
internal func makeIterator() -> _DropFirstSequence<Base> {
43+
return self
44+
}
45+
46+
@_versioned
47+
@_inlineable
48+
internal func next() -> Base.Element? {
49+
while _dropped < _limit {
50+
if _iterator.next() == nil {
51+
_dropped = _limit
52+
return nil
53+
}
54+
_dropped += 1
55+
}
56+
return _iterator.next()
57+
}
58+
59+
@_versioned
60+
@_inlineable
61+
internal func dropFirst(_ n: Int) -> AnySequence<Base.Element> {
62+
// If this is already a _DropFirstSequence, we need to fold in
63+
// the current drop count and drop limit so no data is lost.
64+
//
65+
// i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to
66+
// [1,2,3,4].dropFirst(2).
67+
return AnySequence(
68+
_DropFirstSequence(
69+
_iterator: _iterator, limit: _limit + n, dropped: _dropped))
70+
}
71+
}

stdlib/public/core/DropWhile.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===-- DropWhile.swift ---------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// A sequence that lazily consumes and drops `n` elements from an underlying
14+
/// `Base` iterator before possibly returning the first available element.
15+
///
16+
/// The underlying iterator's sequence may be infinite.
17+
///
18+
/// This is a class - we require reference semantics to keep track
19+
/// of how many elements we've already dropped from the underlying sequence.
20+
@_fixed_layout
21+
@_versioned
22+
public class _DropWhileSequence<Base : IteratorProtocol>
23+
: Sequence, IteratorProtocol {
24+
25+
typealias Element = Base.Element
26+
27+
@_versioned
28+
internal var _iterator: Base
29+
@_versioned
30+
internal var _nextElement: Base.Element?
31+
32+
@_versioned
33+
@_inlineable
34+
internal init(
35+
iterator: Base,
36+
nextElement: Base.Element?,
37+
predicate: (Base.Element) throws -> Bool
38+
) rethrows {
39+
self._iterator = iterator
40+
self._nextElement = nextElement ?? _iterator.next()
41+
42+
while try _nextElement.flatMap(predicate) == true {
43+
_nextElement = _iterator.next()
44+
}
45+
}
46+
47+
@_versioned
48+
@_inlineable
49+
internal func makeIterator() -> _DropWhileSequence<Base> {
50+
return self
51+
}
52+
53+
@_versioned
54+
@_inlineable
55+
internal func next() -> Element? {
56+
guard _nextElement != nil else {
57+
return _iterator.next()
58+
}
59+
60+
let next = _nextElement
61+
_nextElement = nil
62+
return next
63+
}
64+
65+
@_versioned
66+
@_inlineable
67+
internal func drop(
68+
while predicate: (Element) throws -> Bool
69+
) rethrows -> AnySequence<Element> {
70+
// If this is already a _DropWhileSequence, avoid multiple
71+
// layers of wrapping and keep the same iterator.
72+
return try AnySequence(
73+
_DropWhileSequence(
74+
iterator: _iterator, nextElement: _nextElement, predicate: predicate))
75+
}
76+
}

stdlib/public/core/Prefix.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===-- Prefix.swift ------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// A sequence that lazily consumes up to `n` elements from an underlying
14+
/// `Base` iterator.
15+
///
16+
/// The underlying iterator's sequence may be infinite.
17+
///
18+
/// This is a class - we require reference semantics to keep track
19+
/// of how many elements we've already taken from the underlying sequence.
20+
@_fixed_layout
21+
@_versioned
22+
public class _PrefixSequence<Base : IteratorProtocol>
23+
: Sequence, IteratorProtocol {
24+
@_versioned
25+
internal let _maxLength: Int
26+
@_versioned
27+
internal var _iterator: Base
28+
@_versioned
29+
internal var _taken: Int
30+
31+
@_versioned
32+
@_inlineable
33+
internal init(_iterator: Base, maxLength: Int, taken: Int = 0) {
34+
self._iterator = _iterator
35+
self._maxLength = maxLength
36+
self._taken = taken
37+
}
38+
39+
@_versioned
40+
@_inlineable
41+
internal func makeIterator() -> _PrefixSequence<Base> {
42+
return self
43+
}
44+
45+
@_versioned
46+
@_inlineable
47+
internal func next() -> Base.Element? {
48+
if _taken >= _maxLength { return nil }
49+
_taken += 1
50+
51+
if let next = _iterator.next() {
52+
return next
53+
}
54+
55+
_taken = _maxLength
56+
return nil
57+
}
58+
59+
@_versioned
60+
@_inlineable
61+
internal func prefix(_ maxLength: Int) -> AnySequence<Base.Element> {
62+
return AnySequence(
63+
_PrefixSequence(
64+
_iterator: _iterator,
65+
maxLength: Swift.min(maxLength, self._maxLength),
66+
taken: _taken))
67+
}
68+
}

0 commit comments

Comments
 (0)