Skip to content

Commit f625f46

Browse files
[stdlib] Simplify internal DropFirst/PrefixSequence types (#19970)
* Simplify internal DropFirstSequence type * Simplify internal PrefixSequence type
1 parent 2bc198e commit f625f46

File tree

2 files changed

+89
-68
lines changed

2 files changed

+89
-68
lines changed

stdlib/public/core/Sequence.swift

Lines changed: 66 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -646,52 +646,44 @@ extension Sequence where Self.Iterator == Self {
646646
/// `Base` iterator before possibly returning the first available element.
647647
///
648648
/// The underlying iterator's sequence may be infinite.
649-
@usableFromInline
650649
@_fixed_layout
651-
internal struct _DropFirstSequence<Base : IteratorProtocol>
652-
: Sequence, IteratorProtocol {
653-
650+
@usableFromInline
651+
internal struct DropFirstSequence<Base: Sequence> {
654652
@usableFromInline
655-
internal var _iterator: Base
653+
internal let _base: Base
656654
@usableFromInline
657655
internal let _limit: Int
658-
@usableFromInline
659-
internal var _dropped: Int
660-
661-
@inlinable
662-
internal init(_iterator: Base, limit: Int, dropped: Int = 0) {
663-
self._iterator = _iterator
664-
self._limit = limit
665-
self._dropped = dropped
666-
}
667-
668-
@inlinable
669-
__consuming internal func makeIterator() -> _DropFirstSequence<Base> {
670-
return self
656+
657+
@inlinable
658+
public init(_ base: Base, dropping limit: Int) {
659+
_precondition(limit >= 0,
660+
"Can't drop a negative number of elements from a sequence")
661+
_base = base
662+
_limit = limit
671663
}
664+
}
672665

666+
extension DropFirstSequence: Sequence {
667+
public typealias Element = Base.Element
668+
public typealias Iterator = Base.Iterator
669+
public typealias SubSequence = AnySequence<Element>
670+
673671
@inlinable
674-
internal mutating func next() -> Base.Element? {
675-
while _dropped < _limit {
676-
if _iterator.next() == nil {
677-
_dropped = _limit
678-
return nil
679-
}
680-
_dropped += 1
681-
}
682-
return _iterator.next()
672+
public __consuming func makeIterator() -> Iterator {
673+
var it = _base.makeIterator()
674+
var dropped = 0
675+
while dropped < _limit, it.next() != nil { dropped &+= 1 }
676+
return it
683677
}
684678

685679
@inlinable
686-
internal __consuming func dropFirst(_ k: Int) -> AnySequence<Base.Element> {
680+
public __consuming func dropFirst(_ k: Int) -> AnySequence<Element> {
687681
// If this is already a _DropFirstSequence, we need to fold in
688682
// the current drop count and drop limit so no data is lost.
689683
//
690684
// i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to
691685
// [1,2,3,4].dropFirst(2).
692-
return AnySequence(
693-
_DropFirstSequence(
694-
_iterator: _iterator, limit: _limit + k, dropped: _dropped))
686+
return AnySequence(DropFirstSequence(_base, dropping: _limit + k))
695687
}
696688
}
697689

@@ -701,47 +693,60 @@ internal struct _DropFirstSequence<Base : IteratorProtocol>
701693
/// The underlying iterator's sequence may be infinite.
702694
@_fixed_layout
703695
@usableFromInline
704-
internal struct _PrefixSequence<Base : IteratorProtocol>
705-
: Sequence, IteratorProtocol {
706-
@usableFromInline
707-
internal let _maxLength: Int
696+
internal struct PrefixSequence<Base: Sequence> {
708697
@usableFromInline
709-
internal var _iterator: Base
698+
internal var _base: Base
710699
@usableFromInline
711-
internal var _taken: Int
700+
internal let _maxLength: Int
712701

713702
@inlinable
714-
internal init(_iterator: Base, maxLength: Int, taken: Int = 0) {
715-
self._iterator = _iterator
716-
self._maxLength = maxLength
717-
self._taken = taken
703+
public init(_ base: Base, maxLength: Int) {
704+
_precondition(maxLength >= 0, "Can't take a prefix of negative length")
705+
_base = base
706+
_maxLength = maxLength
718707
}
708+
}
719709

720-
@inlinable
721-
__consuming internal func makeIterator() -> _PrefixSequence<Base> {
722-
return self
723-
}
710+
extension PrefixSequence {
711+
@_fixed_layout
712+
public struct Iterator {
713+
@usableFromInline
714+
internal var _base: Base.Iterator
715+
@usableFromInline
716+
internal var _remaining: Int
717+
718+
@inlinable
719+
internal init(_ base: Base.Iterator, maxLength: Int) {
720+
_base = base
721+
_remaining = maxLength
722+
}
723+
}
724+
}
724725

726+
extension PrefixSequence.Iterator: IteratorProtocol {
727+
public typealias Element = Base.Element
728+
725729
@inlinable
726-
internal mutating func next() -> Base.Element? {
727-
if _taken >= _maxLength { return nil }
728-
_taken += 1
729-
730-
if let next = _iterator.next() {
731-
return next
730+
internal mutating func next() -> Element? {
731+
if _remaining != 0 {
732+
_remaining &-= 1
733+
return _base.next()
734+
} else {
735+
return nil
732736
}
737+
}
738+
}
733739

734-
_taken = _maxLength
735-
return nil
740+
extension PrefixSequence: Sequence {
741+
@inlinable
742+
public __consuming func makeIterator() -> Iterator {
743+
return Iterator(_base.makeIterator(), maxLength: _maxLength)
736744
}
737745

738746
@inlinable
739-
internal __consuming func prefix(_ maxLength: Int) -> AnySequence<Base.Element> {
740-
return AnySequence(
741-
_PrefixSequence(
742-
_iterator: _iterator,
743-
maxLength: Swift.min(maxLength, self._maxLength),
744-
taken: _taken))
747+
public __consuming func prefix(_ maxLength: Int) -> AnySequence<Element> {
748+
let length = Swift.min(maxLength, self._maxLength)
749+
return AnySequence(PrefixSequence(_base, maxLength: length))
745750
}
746751
}
747752

@@ -1223,9 +1228,7 @@ extension Sequence where SubSequence == AnySequence<Element> {
12231228
/// the sequence.
12241229
@inlinable
12251230
public __consuming func dropFirst(_ k: Int) -> AnySequence<Element> {
1226-
_precondition(k >= 0, "Can't drop a negative number of elements from a sequence")
1227-
if k == 0 { return AnySequence(self) }
1228-
return AnySequence(_DropFirstSequence(_iterator: makeIterator(), limit: k))
1231+
return AnySequence(DropFirstSequence(self, dropping: k))
12291232
}
12301233

12311234
/// Returns a subsequence containing all but the given number of final
@@ -1325,12 +1328,7 @@ extension Sequence where SubSequence == AnySequence<Element> {
13251328
/// - Complexity: O(1)
13261329
@inlinable
13271330
public __consuming func prefix(_ maxLength: Int) -> AnySequence<Element> {
1328-
_precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
1329-
if maxLength == 0 {
1330-
return AnySequence(EmptyCollection<Element>())
1331-
}
1332-
return AnySequence(
1333-
_PrefixSequence(_iterator: makeIterator(), maxLength: maxLength))
1331+
return AnySequence(PrefixSequence(self, maxLength: maxLength))
13341332
}
13351333

13361334
/// Returns a subsequence containing the initial, consecutive elements that
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
11

22
/* Generic Signature Changes */
3+
Func _DropFirstSequence.dropFirst(_:) has generic signature change from <τ_0_0 where τ_0_0 : IteratorProtocol> to <τ_0_0 where τ_0_0 : Sequence>
4+
Func _DropFirstSequence.makeIterator() has generic signature change from <τ_0_0 where τ_0_0 : IteratorProtocol> to <τ_0_0 where τ_0_0 : Sequence>
5+
Func _PrefixSequence.makeIterator() has generic signature change from <τ_0_0 where τ_0_0 : IteratorProtocol> to <τ_0_0 where τ_0_0 : Sequence>
6+
Func _PrefixSequence.prefix(_:) has generic signature change from <τ_0_0 where τ_0_0 : IteratorProtocol> to <τ_0_0 where τ_0_0 : Sequence>
7+
Struct _DropFirstSequence has generic signature change from <τ_0_0 where τ_0_0 : IteratorProtocol> to <τ_0_0 where τ_0_0 : Sequence>
8+
Struct _PrefixSequence has generic signature change from <τ_0_0 where τ_0_0 : IteratorProtocol> to <τ_0_0 where τ_0_0 : Sequence>
39

410
/* RawRepresentable Changes */
511

612
/* Removed Decls */
13+
Constructor _DropFirstSequence.init(_iterator:limit:dropped:) has been removed
14+
Constructor _PrefixSequence.init(_iterator:maxLength:taken:) has been removed
15+
Func _DropFirstSequence.next() has been removed
16+
Func _PrefixSequence.next() has been removed
17+
Var _DropFirstSequence._dropped has been removed
18+
Var _DropFirstSequence._iterator has been removed
19+
Var _PrefixSequence._iterator has been removed
20+
Var _PrefixSequence._taken has been removed
721

822
/* Moved Decls */
23+
Struct _DropFirstSequence has been renamed to Struct DropFirstSequence
24+
Struct _PrefixSequence has been renamed to Struct PrefixSequence
925

1026
/* Renamed Decls */
1127

1228
/* Type Changes */
29+
Func _DropFirstSequence.makeIterator() has return type change from _DropFirstSequence<τ_0_0> to τ_0_0.Iterator
30+
Func _PrefixSequence.makeIterator() has return type change from _PrefixSequence<τ_0_0> to PrefixSequence<τ_0_0>.Iterator
31+
Var DropFirstSequence._base is added to a non-resilient type
32+
Var PrefixSequence._base is added to a non-resilient type
33+
Var _PrefixSequence._maxLength in a non-resilient type changes position from 0 to 1
1334

1435
/* Decl Attribute changes */
1536

1637
/* Protocol Requirement Changes */
38+
Struct _DropFirstSequence has removed conformance to IteratorProtocol
39+
Struct _PrefixSequence has removed conformance to IteratorProtocol

0 commit comments

Comments
 (0)