Skip to content

Commit 97a26fe

Browse files
committed
Concretize dropFirst/Last/sufix/prefix from Sequence
Remove split customization point Eliminate SubSequence from Sequence protocol Collapse LazyCollection Collapse LazyMapCollection Eliminate _SequenceWrapper Collapse LazyFilterCollection Collapse LazyDrop/PrefixWhileCollection Fix tests, ABI stability update Collapse FlattenSequence
1 parent 1820d70 commit 97a26fe

33 files changed

+327
-1435
lines changed

stdlib/private/StdlibCollectionUnittest/CheckSequenceType.swift

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,14 +1643,6 @@ extension TestSuite {
16431643

16441644
testNamePrefix += String(describing: S.Type.self)
16451645

1646-
let isMultiPass = makeSequence([])
1647-
._preprocessingPass { true } ?? false
1648-
let isEquatableMultiPass = makeSequenceOfEquatable([])
1649-
._preprocessingPass { true } ?? false
1650-
expectEqual(
1651-
isMultiPass, isEquatableMultiPass,
1652-
"Two sequence types are of different kinds?")
1653-
16541646
// FIXME: swift-3-indexing-model: add tests for `underestimatedCount`
16551647
// Check that it is non-negative, and an underestimate of the actual
16561648
// element count.
@@ -1667,12 +1659,6 @@ self.test("\(testNamePrefix).contains()/WhereElementIsEquatable/semantics") {
16671659
test.expected != nil,
16681660
s.contains(wrapValueIntoEquatable(test.element)),
16691661
stackTrace: SourceLocStack().with(test.loc))
1670-
1671-
if !isMultiPass {
1672-
expectEqualSequence(
1673-
test.expectedLeftoverSequence, s.map(extractValueFromEquatable),
1674-
stackTrace: SourceLocStack().with(test.loc))
1675-
}
16761662
}
16771663
}
16781664

stdlib/private/StdlibCollectionUnittest/LoggingWrappers.swift

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ public class SequenceLog {
8383
public static var prefixWhile = TypeIndexed(0)
8484
public static var prefixMaxLength = TypeIndexed(0)
8585
public static var suffixMaxLength = TypeIndexed(0)
86-
public static var split = TypeIndexed(0)
8786
public static var _customContainsEquatableElement = TypeIndexed(0)
8887
public static var _preprocessingPass = TypeIndexed(0)
8988
public static var _copyToContiguousArray = TypeIndexed(0)
@@ -202,7 +201,6 @@ extension LoggingSequence: LoggingType {
202201
extension LoggingSequence: Sequence {
203202
public typealias Element = Base.Element
204203
public typealias Iterator = LoggingIterator<Base.Iterator>
205-
public typealias SubSequence = Base.SubSequence
206204

207205
public func makeIterator() -> Iterator {
208206
SequenceLog.makeIterator[selfType] += 1
@@ -214,52 +212,6 @@ extension LoggingSequence: Sequence {
214212
return base.underestimatedCount
215213
}
216214

217-
public func dropFirst(_ n: Int) -> SubSequence {
218-
SequenceLog.dropFirst[selfType] += 1
219-
return base.dropFirst(n)
220-
}
221-
222-
public func dropLast(_ n: Int) -> SubSequence {
223-
SequenceLog.dropLast[selfType] += 1
224-
return base.dropLast(n)
225-
}
226-
227-
public func drop(
228-
while predicate: (Element) throws -> Bool
229-
) rethrows -> SubSequence {
230-
SequenceLog.dropWhile[selfType] += 1
231-
return try base.drop(while: predicate)
232-
}
233-
234-
public func prefix(_ maxLength: Int) -> SubSequence {
235-
SequenceLog.prefixMaxLength[selfType] += 1
236-
return base.prefix(maxLength)
237-
}
238-
239-
public func prefix(
240-
while predicate: (Element) throws -> Bool
241-
) rethrows -> SubSequence {
242-
SequenceLog.prefixWhile[selfType] += 1
243-
return try base.prefix(while: predicate)
244-
}
245-
246-
public func suffix(_ maxLength: Int) -> SubSequence {
247-
SequenceLog.suffixMaxLength[selfType] += 1
248-
return base.suffix(maxLength)
249-
}
250-
251-
public func split(
252-
maxSplits: Int = Int.max,
253-
omittingEmptySubsequences: Bool = true,
254-
whereSeparator isSeparator: (Element) throws -> Bool
255-
) rethrows -> [SubSequence] {
256-
SequenceLog.split[selfType] += 1
257-
return try base.split(
258-
maxSplits: maxSplits,
259-
omittingEmptySubsequences: omittingEmptySubsequences,
260-
whereSeparator: isSeparator)
261-
}
262-
263215
public func _customContainsEquatableElement(_ element: Element) -> Bool? {
264216
SequenceLog._customContainsEquatableElement[selfType] += 1
265217
return base._customContainsEquatableElement(element)
@@ -297,6 +249,7 @@ public typealias LoggingCollection<Base: Collection> = LoggingSequence<Base>
297249
extension LoggingCollection: Collection {
298250
public typealias Index = Base.Index
299251
public typealias Indices = Base.Indices
252+
public typealias SubSequence = Base.SubSequence
300253

301254
public var startIndex: Index {
302255
CollectionLog.startIndex[selfType] += 1

stdlib/private/StdlibUnittest/StdlibUnittest.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,7 @@ public func expectMutableSliceType<X : MutableCollection>(
499499
/// to be.
500500
public func expectSequenceAssociatedTypes<X : Sequence>(
501501
sequenceType: X.Type,
502-
iteratorType: X.Iterator.Type,
503-
subSequenceType: X.SubSequence.Type
502+
iteratorType: X.Iterator.Type
504503
) {}
505504

506505
/// Check that all associated types of a `Collection` are what we expect them

stdlib/public/core/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ set(SWIFTLIB_ESSENTIAL
122122
SipHash.swift
123123
Sequence.swift
124124
SequenceAlgorithms.swift
125-
SequenceWrapper.swift
126125
Set.swift
127126
SetAlgebra.swift
128127
SetAnyHashableExtensions.swift

stdlib/public/core/Collection.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ extension IndexingIterator: IteratorProtocol, Sequence {
332332
/// or bidirectional collection must traverse the entire collection to count
333333
/// the number of contained elements, accessing its `count` property is an
334334
/// O(*n*) operation.
335-
public protocol Collection: Sequence where SubSequence: Collection {
335+
public protocol Collection: Sequence {
336336
// FIXME: ideally this would be in MigrationSupport.swift, but it needs
337337
// to be on the protocol instead of as an extension
338338
@available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
@@ -390,7 +390,10 @@ public protocol Collection: Sequence where SubSequence: Collection {
390390
/// This associated type appears as a requirement in the `Sequence`
391391
/// protocol, but it is restated here with stricter constraints. In a
392392
/// collection, the subsequence should also conform to `Collection`.
393-
associatedtype SubSequence = Slice<Self> where SubSequence.Index == Index
393+
associatedtype SubSequence: Collection = Slice<Self>
394+
where SubSequence.Index == Index,
395+
Element == SubSequence.Element,
396+
SubSequence.SubSequence == SubSequence
394397

395398
/// Accesses the element at the specified position.
396399
///
@@ -1227,7 +1230,7 @@ extension Collection {
12271230
/// `RandomAccessCollection`; otherwise, O(*k*), where *k* is the number of
12281231
/// elements to drop from the beginning of the collection.
12291232
@inlinable
1230-
public __consuming func dropFirst(_ k: Int) -> SubSequence {
1233+
public __consuming func dropFirst(_ k: Int = 1) -> SubSequence {
12311234
_precondition(k >= 0, "Can't drop a negative number of elements from a collection")
12321235
let start = index(startIndex, offsetBy: k, limitedBy: endIndex) ?? endIndex
12331236
return self[start..<endIndex]
@@ -1254,15 +1257,15 @@ extension Collection {
12541257
/// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the length of
12551258
/// the collection.
12561259
@inlinable
1257-
public __consuming func dropLast(_ k: Int) -> SubSequence {
1260+
public __consuming func dropLast(_ k: Int = 1) -> SubSequence {
12581261
_precondition(
12591262
k >= 0, "Can't drop a negative number of elements from a collection")
12601263
let amount = Swift.max(0, count - k)
12611264
let end = index(startIndex,
12621265
offsetBy: amount, limitedBy: endIndex) ?? endIndex
12631266
return self[startIndex..<end]
12641267
}
1265-
1268+
12661269
/// Returns a subsequence by skipping elements while `predicate` returns
12671270
/// `true` and returning the remaining elements.
12681271
///

stdlib/public/core/Dictionary.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,8 @@ extension Dictionary {
618618
}
619619

620620
extension Dictionary: Collection {
621+
public typealias SubSequence = Slice<Dictionary>
622+
621623
/// The position of the first element in a nonempty dictionary.
622624
///
623625
/// If the collection is empty, `startIndex` is equal to `endIndex`.
@@ -1321,6 +1323,7 @@ extension Dictionary {
13211323
: Collection, Equatable,
13221324
CustomStringConvertible, CustomDebugStringConvertible {
13231325
public typealias Element = Key
1326+
public typealias SubSequence = Slice<Dictionary.Keys>
13241327

13251328
@usableFromInline
13261329
internal var _variant: Dictionary<Key, Value>._Variant

stdlib/public/core/DropWhile.swift

Lines changed: 9 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ extension LazyDropWhileSequence.Iterator: IteratorProtocol {
7878
}
7979

8080
extension LazyDropWhileSequence: Sequence {
81-
public typealias SubSequence = AnySequence<Element> // >:(
82-
8381
/// Returns an iterator over the elements of this sequence.
8482
///
8583
/// - Complexity: O(1).
@@ -119,140 +117,43 @@ extension LazySequenceProtocol {
119117
/// performance given by the `Collection` protocol. Be aware, therefore,
120118
/// that general operations on lazy collections may not have the
121119
/// documented complexity.
122-
@_fixed_layout // lazy-performance
123-
public struct LazyDropWhileCollection<Base: Collection> {
124-
public typealias Element = Base.Element
125-
126-
@inlinable // lazy-performance
127-
internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
128-
self._base = _base
129-
self._predicate = predicate
130-
}
131-
132-
@usableFromInline // lazy-performance
133-
internal var _base: Base
134-
@usableFromInline // lazy-performance
135-
internal let _predicate: (Element) -> Bool
136-
}
120+
public typealias LazyDropWhileCollection<T: Collection> = LazyDropWhileSequence<T>
137121

138-
extension LazyDropWhileCollection: Sequence {
139-
public typealias Iterator = LazyDropWhileSequence<Base>.Iterator
140-
141-
/// Returns an iterator over the elements of this sequence.
142-
///
143-
/// - Complexity: O(1).
144-
@inlinable // lazy-performance
145-
public __consuming func makeIterator() -> Iterator {
146-
return Iterator(_base: _base.makeIterator(), predicate: _predicate)
147-
}
148-
}
149-
150-
extension LazyDropWhileCollection {
122+
extension LazyDropWhileCollection: Collection {
151123
public typealias SubSequence = Slice<LazyDropWhileCollection<Base>>
124+
public typealias Index = Base.Index
152125

153-
/// A position in a `LazyDropWhileCollection` or
154-
/// `LazyDropWhileBidirectionalCollection` instance.
155-
@_fixed_layout // lazy-performance
156-
public struct Index {
157-
/// The position corresponding to `self` in the underlying collection.
158-
public let base: Base.Index
159-
160-
@inlinable // lazy-performance
161-
internal init(_base: Base.Index) {
162-
self.base = _base
163-
}
164-
}
165-
}
166-
167-
extension LazyDropWhileCollection.Index: Equatable, Comparable {
168-
@inlinable // lazy-performance
169-
public static func == (
170-
lhs: LazyDropWhileCollection<Base>.Index,
171-
rhs: LazyDropWhileCollection<Base>.Index
172-
) -> Bool {
173-
return lhs.base == rhs.base
174-
}
175-
176-
@inlinable // lazy-performance
177-
public static func < (
178-
lhs: LazyDropWhileCollection<Base>.Index,
179-
rhs: LazyDropWhileCollection<Base>.Index
180-
) -> Bool {
181-
return lhs.base < rhs.base
182-
}
183-
}
184-
185-
extension LazyDropWhileCollection.Index: Hashable where Base.Index: Hashable {
186-
/// The hash value.
187-
@inlinable
188-
public var hashValue: Int {
189-
return base.hashValue
190-
}
191-
192-
/// Hashes the essential components of this value by feeding them into the
193-
/// given hasher.
194-
///
195-
/// - Parameter hasher: The hasher to use when combining the components
196-
/// of this instance.
197-
@inlinable
198-
public func hash(into hasher: inout Hasher) {
199-
hasher.combine(base)
200-
}
201-
}
202-
203-
extension LazyDropWhileCollection: Collection {
204126
@inlinable // lazy-performance
205127
public var startIndex: Index {
206128
var index = _base.startIndex
207129
while index != _base.endIndex && _predicate(_base[index]) {
208130
_base.formIndex(after: &index)
209131
}
210-
return Index(_base: index)
132+
return index
211133
}
212134

213135
@inlinable // lazy-performance
214136
public var endIndex: Index {
215-
return Index(_base: _base.endIndex)
137+
return _base.endIndex
216138
}
217139

218140
@inlinable // lazy-performance
219141
public func index(after i: Index) -> Index {
220-
_precondition(i.base < _base.endIndex, "Can't advance past endIndex")
221-
return Index(_base: _base.index(after: i.base))
142+
_precondition(i < _base.endIndex, "Can't advance past endIndex")
143+
return _base.index(after: i)
222144
}
223145

224-
225146
@inlinable // lazy-performance
226147
public subscript(position: Index) -> Element {
227-
return _base[position.base]
148+
return _base[position]
228149
}
229150
}
230151

231-
extension LazyDropWhileCollection: LazyCollectionProtocol { }
232-
233152
extension LazyDropWhileCollection: BidirectionalCollection
234153
where Base: BidirectionalCollection {
235154
@inlinable // lazy-performance
236155
public func index(before i: Index) -> Index {
237156
_precondition(i > startIndex, "Can't move before startIndex")
238-
return Index(_base: _base.index(before: i.base))
157+
return _base.index(before: i)
239158
}
240159
}
241-
242-
extension LazyCollectionProtocol {
243-
/// Returns a lazy collection that skips any initial elements that satisfy
244-
/// `predicate`.
245-
///
246-
/// - Parameter predicate: A closure that takes an element of the collection
247-
/// as its argument and returns `true` if the element should be skipped or
248-
/// `false` otherwise. Once `predicate` returns `false` it will not be
249-
/// called again.
250-
@inlinable // lazy-performance
251-
public __consuming func drop(
252-
while predicate: @escaping (Elements.Element) -> Bool
253-
) -> LazyDropWhileCollection<Self.Elements> {
254-
return LazyDropWhileCollection(
255-
_base: self.elements, predicate: predicate)
256-
}
257-
}
258-

0 commit comments

Comments
 (0)