diff --git a/stdlib/public/core/Filter.swift.gyb b/stdlib/public/core/Filter.swift.gyb index 7f12d20d60ee0..5b3cec6cd597a 100644 --- a/stdlib/public/core/Filter.swift.gyb +++ b/stdlib/public/core/Filter.swift.gyb @@ -97,65 +97,8 @@ public struct LazyFilterSequence } /// The `Index` used for subscripting a `LazyFilterCollection`. -/// -/// The positions of a `LazyFilterIndex` correspond to those positions -/// `p` in its underlying collection `c` such that `c[p]` -/// satisfies the predicate with which the `LazyFilterIndex` was -/// initialized. -/// -/// - Note: The performance of advancing a `LazyFilterIndex` -/// depends on how sparsely the filtering predicate is satisfied, -/// and may not offer the usual performance given by models of -/// `Collection`. -public struct LazyFilterIndex { - - /// The position corresponding to `self` in the underlying collection. - public let base: Base.Index -} - -extension LazyFilterIndex : Comparable { - public static func == ( - lhs: LazyFilterIndex, - rhs: LazyFilterIndex - ) -> Bool { - return lhs.base == rhs.base - } - - public static func != ( - lhs: LazyFilterIndex, - rhs: LazyFilterIndex - ) -> Bool { - return lhs.base != rhs.base - } - - public static func < ( - lhs: LazyFilterIndex, - rhs: LazyFilterIndex - ) -> Bool { - return lhs.base < rhs.base - } - - public static func <= ( - lhs: LazyFilterIndex, - rhs: LazyFilterIndex - ) -> Bool { - return lhs.base <= rhs.base - } - - public static func >= ( - lhs: LazyFilterIndex, - rhs: LazyFilterIndex - ) -> Bool { - return lhs.base >= rhs.base - } - - public static func > ( - lhs: LazyFilterIndex, - rhs: LazyFilterIndex - ) -> Bool { - return lhs.base > rhs.base - } -} +@available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use Base.Index") +public typealias LazyFilterIndex = Base.Index // FIXME(ABI)#27 (Conditional Conformance): `LazyFilter*Collection` types should be // collapsed into one `LazyFilterCollection` using conditional conformances. @@ -170,20 +113,23 @@ extension LazyFilterIndex : Comparable { /// underlying collection that satisfy a predicate. /// /// - Note: The performance of accessing `startIndex`, `first`, any methods -/// that depend on `startIndex`, or of advancing a `LazyFilterIndex` depends +/// that depend on `startIndex`, or of advancing an index depends /// on how sparsely the filtering predicate is satisfied, and may not offer /// the usual performance given by `Collection`. Be aware, therefore, that /// general operations on `LazyFilterCollection` instances may not have the /// documented complexity. public struct ${Self}< Base : ${collectionForTraversal(Traversal)} -> : LazyCollectionProtocol, ${collectionForTraversal(Traversal)} { +> : LazyCollectionProtocol, ${collectionForTraversal(Traversal)} +// FIXME(ABI): Recursive protocol conformances + where Base.SubSequence: ${collectionForTraversal(Traversal)} +{ /// A type that represents a valid position in the collection. /// /// Valid indices consist of the position of every element and a /// "past the end" position that's not valid for use as a subscript. - public typealias Index = LazyFilterIndex + public typealias Index = Base.Index public typealias IndexDistance = Base.IndexDistance @@ -209,7 +155,7 @@ public struct ${Self}< while index != _base.endIndex && !_predicate(_base[index]) { _base.formIndex(after: &index) } - return LazyFilterIndex(base: index) + return index } /// The collection's "past the end" position---that is, the position one @@ -218,7 +164,7 @@ public struct ${Self}< /// `endIndex` is always reachable from `startIndex` by zero or more /// applications of `index(after:)`. public var endIndex: Index { - return LazyFilterIndex(base: _base.endIndex) + return _base.endIndex } // TODO: swift-3-indexing-model - add docs @@ -230,12 +176,12 @@ public struct ${Self}< public func formIndex(after i: inout Index) { // TODO: swift-3-indexing-model: _failEarlyRangeCheck i? - var index = i.base + var index = i _precondition(index != _base.endIndex, "can't advance past endIndex") repeat { _base.formIndex(after: &index) } while index != _base.endIndex && !_predicate(_base[index]) - i = LazyFilterIndex(base: index) + i = index } % if Traversal == 'Bidirectional': @@ -247,12 +193,12 @@ public struct ${Self}< public func formIndex(before i: inout Index) { // TODO: swift-3-indexing-model: _failEarlyRangeCheck i? - var index = i.base + var index = i _precondition(index != _base.startIndex, "can't retreat before startIndex") repeat { _base.formIndex(before: &index) } while !_predicate(_base[index]) - i = LazyFilterIndex(base: index) + i = index } % end @@ -261,22 +207,14 @@ public struct ${Self}< /// - Precondition: `position` is a valid position in `self` and /// `position != endIndex`. public subscript(position: Index) -> Base.Iterator.Element { - return _base[position.base] + return _base[position] } - public subscript(bounds: Range) -> ${Slice}<${Self}> { - return ${Slice}(base: self, bounds: bounds) + public subscript(bounds: Range) -> ${Self} { + return ${Self}(_base: _base[bounds], _predicate) } - // FIXME(ABI)#28 (Associated Types with where clauses): we actually want to add: - // - // typealias SubSequence = ${Self} - // - // so that all slicing optimizations of the base collection can kick in. - // - // We can't do that right now though, because that would force a lot of - // constraints on `Base.SubSequence`, limiting the possible contexts where - // the `.lazy.filter` API can be used. + public typealias SubSequence = ${Self} /// Returns an iterator over the elements of this sequence. /// @@ -310,11 +248,12 @@ extension LazySequenceProtocol { % for Traversal in ['Forward', 'Bidirectional']: extension LazyCollectionProtocol -% if Traversal != 'Forward': where +% if Traversal != 'Forward': Self : ${collectionForTraversal(Traversal)}, - Elements : ${collectionForTraversal(Traversal)} + Elements : ${collectionForTraversal(Traversal)}, % end + Self.Elements.SubSequence : ${collectionForTraversal(Traversal)} { /// Returns the elements of `self` that satisfy `predicate`. /// diff --git a/test/stdlib/Filter.swift b/test/stdlib/Filter.swift index 83721212c12ae..bb5bce762853b 100644 --- a/test/stdlib/Filter.swift +++ b/test/stdlib/Filter.swift @@ -32,12 +32,6 @@ extension LazyFilterSequence where Base : TestProtocol1 { } } -extension LazyFilterIndex where Base : TestProtocol1 { - var _baseIsTestProtocol1: Bool { - fatalError("not implemented") - } -} - extension LazyFilterCollection where Base : TestProtocol1 { var _baseIsTestProtocol1: Bool { fatalError("not implemented") diff --git a/test/stdlib/Renames.swift b/test/stdlib/Renames.swift index 34f1c4d401a08..d1daaf4a91cdf 100644 --- a/test/stdlib/Renames.swift +++ b/test/stdlib/Renames.swift @@ -171,7 +171,7 @@ func _Filter(s: S) { func _Filter(s: LazyFilterSequence) { _ = s.generate() // expected-error {{'generate()' has been renamed to 'makeIterator()'}} {{9-17=makeIterator}} {{none}} } -func _Filter(c: C) { +func _Filter(c: C) where C.SubSequence: Collection { _ = LazyFilterCollection(c) { _ in true} // expected-error {{'init(_:whereElementsSatisfy:)' is unavailable: use '.lazy.filter' on the collection}} } func _Filter(c: LazyFilterCollection) { diff --git a/validation-test/stdlib/Lazy.swift.gyb b/validation-test/stdlib/Lazy.swift.gyb index db741c9ece8ec..f8ffca239a94e 100644 --- a/validation-test/stdlib/Lazy.swift.gyb +++ b/validation-test/stdlib/Lazy.swift.gyb @@ -638,10 +638,10 @@ tests.test("LazySequence/Sequence") { } func expectSequencePassthrough< - S : Sequence, + S : LazySequenceProtocol, Base : Sequence >(_ s: S, base: Base, arbitraryElement: S.Iterator.Element, count: Int) -where S : LazySequenceProtocol, Base : LoggingType, +where Base : LoggingType, Base.Iterator.Element == S.Iterator.Element { let baseType = type(of: base) @@ -825,7 +825,7 @@ tests.test("LazyMapCollection/Passthrough") { let startIndex = CollectionLog.startIndex.expectIncrement(type(of: base)) { mapped.startIndex } - let endIndex = CollectionLog.endIndex.expectIncrement(type(of: base)) { + _ = CollectionLog.endIndex.expectIncrement(type(of: base)) { mapped.endIndex } // Not exactly passthrough, because mapping transforms the result @@ -1023,9 +1023,7 @@ tests.test("ReversedCollection/Lazy") { // Given a couple of sequences backed by FilterGenerator's, check that // the first selects even numbers and the second selects odd numbers, // both from an underlying sequence of whole numbers. -func checkFilterIteratorBase< - S : Sequence, I : IteratorProtocol ->(_ s1: S, _ s2: S) +func checkFilterIteratorBase< S : Sequence, I>(_ s1: S, _ s2: S) where S.Iterator == LazyFilterIterator, I.Element == OpaqueValue { var iter1 = s1.makeIterator() expectEqual(0, iter1.next()!.value) @@ -1098,16 +1096,16 @@ tests.test("LazyFilterIndex/base") { let evens = base.lazy.filter { $0.value % 2 == 0 } let odds = base.lazy.filter { $0.value % 2 != 0 } - expectEqual(base.startIndex, evens.startIndex.base) - expectEqual(base.index(after: base.startIndex), odds.startIndex.base) + expectEqual(base.startIndex, evens.startIndex) + expectEqual(base.index(after: base.startIndex), odds.startIndex) expectEqual( base.index(after: base.index(after: base.startIndex)), - evens.index(after: evens.startIndex).base) + evens.index(after: evens.startIndex)) expectEqual( base.index(after: base.index(after: base.index(after: base.startIndex))), - odds.index(after: odds.startIndex).base) + odds.index(after: odds.startIndex)) } tests.test("LazyFilterCollection") { @@ -1157,8 +1155,7 @@ tests.test("LazyFilterCollection/AssociatedTypes") { expectCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyFilterIterator.self, - // FIXME(ABI)#80 (Associated Types with where clauses): SubSequence should be `LazyFilterCollection`. - subSequenceType: Slice.self, + subSequenceType: LazyFilterCollection.self, indexType: LazyFilterIndex.self, indexDistanceType: Base.IndexDistance.self, indicesType: DefaultIndices.self) @@ -1170,8 +1167,7 @@ tests.test("LazyFilterBidirectionalCollection/AssociatedTypes") { expectBidirectionalCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyFilterIterator.self, - // FIXME(ABI)#81 (Associated Types with where clauses): SubSequence should be `LazyFilterBidirectionalCollection`. - subSequenceType: BidirectionalSlice.self, + subSequenceType: LazyFilterBidirectionalCollection.self, indexType: LazyFilterIndex.self, indexDistanceType: Base.IndexDistance.self, indicesType: DefaultBidirectionalIndices.self)