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)