Skip to content

Commit b927254

Browse files
author
Max Moiseev
committed
[stdlib] Conditional conformances for LazyMapCollection
1 parent 833721a commit b927254

File tree

5 files changed

+47
-74
lines changed

5 files changed

+47
-74
lines changed

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ set(SWIFTLIB_ESSENTIAL
8282
LazySequence.swift
8383
LifetimeManager.swift
8484
ManagedBuffer.swift
85-
Map.swift.gyb
85+
Map.swift
8686
MemoryLayout.swift
8787
UnicodeScalar.swift # ORDER DEPENDENCY: Must precede Mirrors.swift
8888
Mirrors.swift.gyb

stdlib/public/core/FlatMap.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ extension LazyCollectionProtocol {
9595
extension LazyCollectionProtocol
9696
where
9797
Self : BidirectionalCollection,
98-
Elements : BidirectionalCollection
99-
{
98+
Elements : BidirectionalCollection {
10099
/// Returns the concatenated results of mapping the given transformation over
101100
/// this collection.
102101
///
@@ -111,7 +110,7 @@ extension LazyCollectionProtocol
111110
_ transform: @escaping (Elements.Element) -> SegmentOfResult
112111
) -> LazyCollection<
113112
FlattenBidirectionalCollection<
114-
LazyMapBidirectionalCollection<Elements, SegmentOfResult>>> {
113+
LazyMapCollection<Elements, SegmentOfResult>>> {
115114
return self.map(transform).joined()
116115
}
117116

@@ -128,9 +127,9 @@ extension LazyCollectionProtocol
128127
@_inlineable // FIXME(sil-serialize-all)
129128
public func flatMap<ElementOfResult>(
130129
_ transform: @escaping (Elements.Element) -> ElementOfResult?
131-
) -> LazyMapBidirectionalCollection<
130+
) -> LazyMapCollection<
132131
LazyFilterCollection<
133-
LazyMapBidirectionalCollection<Elements, ElementOfResult?>>,
132+
LazyMapCollection<Elements, ElementOfResult?>>,
134133
ElementOfResult
135134
> {
136135
return self.map(transform).filter { $0 != nil }.map { $0! }

stdlib/public/core/Map.swift.gyb renamed to stdlib/public/core/Map.swift

Lines changed: 31 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- Map.swift.gyb - Lazily map over a Sequence -----------*- swift -*-===//
1+
//===--- Map.swift - Lazily map over a Sequence ---------------*- swift -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -10,13 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
%{
14-
from gyb_stdlib_support import (
15-
TRAVERSALS,
16-
collectionForTraversal
17-
)
18-
}%
19-
2013
/// The `IteratorProtocol` used by `MapSequence` and `MapCollection`.
2114
/// Produces each element by passing the output of the `Base`
2215
/// `IteratorProtocol` through a transform function returning `Element`.
@@ -52,8 +45,7 @@ public struct LazyMapIterator<
5245
}
5346
}
5447

55-
/// A `Sequence` whose elements consist of those in a `Base`
56-
/// `Sequence` passed through a transform function returning `Element`.
48+
/// A `Sequence` whose elements consist of those in a `Base` /// `Sequence` passed through a transform function returning `Element`.
5749
/// These elements are computed lazily, each time they're read, by
5850
/// calling the transform function on a base element.
5951
@_fixed_layout
@@ -96,22 +88,14 @@ public struct LazyMapSequence<Base : Sequence, Element>
9688

9789
//===--- Collections ------------------------------------------------------===//
9890

99-
// FIXME(ABI)#45 (Conditional Conformance): `LazyMap*Collection` types should be
100-
// collapsed into one `LazyMapCollection` using conditional conformances.
101-
// Maybe even combined with `LazyMapSequence`.
102-
// rdar://problem/17144340
103-
104-
% for Traversal in TRAVERSALS:
105-
% Self = "LazyMap" + collectionForTraversal(Traversal)
106-
10791
/// A `Collection` whose elements consist of those in a `Base`
10892
/// `Collection` passed through a transform function returning `Element`.
10993
/// These elements are computed lazily, each time they're read, by
11094
/// calling the transform function on a base element.
11195
@_fixed_layout
112-
public struct ${Self}<
113-
Base : ${collectionForTraversal(Traversal)}, Element
114-
> : LazyCollectionProtocol, ${collectionForTraversal(Traversal)} {
96+
public struct LazyMapCollection<
97+
Base : Collection, Element
98+
> : LazyCollectionProtocol, Collection {
11599

116100
// FIXME(compiler limitation): should be inferable.
117101
public typealias Index = Base.Index
@@ -129,16 +113,6 @@ public struct ${Self}<
129113
_base.formIndex(after: &i)
130114
}
131115

132-
% if Traversal in ['Bidirectional', 'RandomAccess']:
133-
@_inlineable
134-
public func index(before i: Index) -> Index { return _base.index(before: i) }
135-
136-
@_inlineable
137-
public func formIndex(before i: inout Index) {
138-
_base.formIndex(before: &i)
139-
}
140-
% end
141-
142116
/// Accesses the element at `position`.
143117
///
144118
/// - Precondition: `position` is a valid position in `self` and
@@ -148,7 +122,7 @@ public struct ${Self}<
148122
return _transform(_base[position])
149123
}
150124

151-
public typealias SubSequence = ${Self}<Base.SubSequence, Element>
125+
public typealias SubSequence = LazyMapCollection<Base.SubSequence, Element>
152126

153127
@_inlineable
154128
public subscript(bounds: Range<Base.Index>) -> SubSequence {
@@ -183,11 +157,6 @@ public struct ${Self}<
183157
@_inlineable
184158
public var first: Element? { return _base.first.map(_transform) }
185159

186-
% if Traversal in ['Bidirectional', 'RandomAccess']:
187-
@_inlineable
188-
public var last: Element? { return _base.last.map(_transform) }
189-
% end
190-
191160
@_inlineable
192161
public func index(_ i: Index, offsetBy n: Int) -> Index {
193162
return _base.index(i, offsetBy: n)
@@ -233,7 +202,24 @@ public struct ${Self}<
233202
internal let _transform: (Base.Element) -> Element
234203
}
235204

236-
% end
205+
extension LazyMapCollection : BidirectionalCollection
206+
where Base : BidirectionalCollection {
207+
208+
@_inlineable
209+
public func index(before i: Index) -> Index { return _base.index(before: i) }
210+
211+
@_inlineable
212+
public func formIndex(before i: inout Index) {
213+
_base.formIndex(before: &i)
214+
}
215+
216+
@_inlineable
217+
public var last: Element? { return _base.last.map(_transform) }
218+
}
219+
220+
extension LazyMapCollection : RandomAccessCollection
221+
where Base : RandomAccessCollection {}
222+
237223

238224
//===--- Support for s.lazy -----------------------------------------------===//
239225

@@ -249,30 +235,18 @@ extension LazySequenceProtocol {
249235
}
250236
}
251237

252-
% for Traversal in TRAVERSALS:
253-
254-
extension LazyCollectionProtocol
255-
% if Traversal != 'Forward':
256-
where
257-
Self : ${collectionForTraversal(Traversal)},
258-
Elements : ${collectionForTraversal(Traversal)}
259-
% end
260-
{
238+
extension LazyCollectionProtocol {
261239
/// Returns a `LazyMapCollection` over this `Collection`. The elements of
262240
/// the result are computed lazily, each time they are read, by
263241
/// calling `transform` function on a base element.
264242
@_inlineable
265243
public func map<U>(
266244
_ transform: @escaping (Elements.Element) -> U
267-
) -> LazyMap${collectionForTraversal(Traversal)}<Self.Elements, U> {
268-
return LazyMap${collectionForTraversal(Traversal)}(
269-
_base: self.elements,
270-
transform: transform)
245+
) -> LazyMapCollection<Self.Elements, U> {
246+
return LazyMapCollection(_base: self.elements, transform: transform)
271247
}
272248
}
273249

274-
% end
275-
276250
extension LazyMapCollection {
277251
// This overload is needed to re-enable Swift 3 source compatibility related
278252
// to a bugfix in ranking behavior of the constraint solver.
@@ -289,6 +263,7 @@ extension LazyMapCollection {
289263
}
290264
}
291265

292-
// ${'Local Variables'}:
293-
// eval: (read-only-mode 1)
294-
// End:
266+
@available(*, deprecated, renamed: "LazyMapCollection")
267+
public typealias LazyMapBidirectionalCollection<T, E> = LazyMapCollection<T, E> where T : BidirectionalCollection
268+
@available(*, deprecated, renamed: "LazyMapCollection")
269+
public typealias LazyMapRandomAccessCollection<T, E> = LazyMapCollection<T, E> where T : RandomAccessCollection

validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ var CollectionTests = TestSuite("Collection")
1515

1616
// Test collections using value types as elements.
1717
CollectionTests.addBidirectionalCollectionTests(
18-
makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
18+
makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapCollection<MinimalBidirectionalCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
1919
MinimalBidirectionalCollection(elements: elements).lazy.map(identity)
2020
},
2121
wrapValue: identity,
2222
extractValue: identity,
23-
makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<MinimalEquatableValue>, MinimalEquatableValue> in
23+
makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapCollection<MinimalBidirectionalCollection<MinimalEquatableValue>, MinimalEquatableValue> in
2424
MinimalBidirectionalCollection(elements: elements).lazy.map(identityEq)
2525
},
2626
wrapValueIntoEquatable: identityEq,
@@ -29,7 +29,7 @@ CollectionTests.addBidirectionalCollectionTests(
2929

3030
// Test collections using reference types as elements.
3131
CollectionTests.addBidirectionalCollectionTests(
32-
makeCollection: { (elements: [LifetimeTracked]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
32+
makeCollection: { (elements: [LifetimeTracked]) -> LazyMapCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
3333
MinimalBidirectionalCollection(elements: elements).lazy.map { $0 }
3434
},
3535
wrapValue: { (element: OpaqueValue<Int>) in
@@ -38,7 +38,7 @@ CollectionTests.addBidirectionalCollectionTests(
3838
extractValue: { (element: LifetimeTracked) in
3939
OpaqueValue(element.value, identity: element.identity)
4040
},
41-
makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
41+
makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
4242
MinimalBidirectionalCollection(elements: elements).lazy.map { $0 }
4343
},
4444
wrapValueIntoEquatable: { (element: MinimalEquatableValue) in

validation-test/stdlib/Lazy.swift.gyb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -880,22 +880,22 @@ tests.test("LazyMapCollection/AssociatedTypes") {
880880

881881
tests.test("LazyMapBidirectionalCollection/AssociatedTypes") {
882882
typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
883-
typealias Subject = LazyMapBidirectionalCollection<Base, OpaqueValue<Int32>>
883+
typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
884884
expectBidirectionalCollectionAssociatedTypes(
885885
collectionType: Subject.self,
886886
iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
887-
subSequenceType: LazyMapBidirectionalCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
887+
subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
888888
indexType: Base.Index.self,
889889
indicesType: Base.Indices.self)
890890
}
891891

892892
tests.test("LazyMapRandomAccessCollection/AssociatedTypes") {
893893
typealias Base = MinimalRandomAccessCollection<OpaqueValue<Int>>
894-
typealias Subject = LazyMapRandomAccessCollection<Base, OpaqueValue<Int32>>
894+
typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
895895
expectRandomAccessCollectionAssociatedTypes(
896896
collectionType: Subject.self,
897897
iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
898-
subSequenceType: LazyMapRandomAccessCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
898+
subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
899899
indexType: Base.Index.self,
900900
indicesType: Base.Indices.self)
901901
}
@@ -936,7 +936,7 @@ tests.test("lazy.mapped/TypeInference") {
936936
var mapped = MinimalRandomAccessCollection(elements: baseArray)
937937
.lazy.map { _ in OpaqueValue<Int8>(0) }
938938
expectType(
939-
LazyMapRandomAccessCollection<
939+
LazyMapCollection<
940940
MinimalRandomAccessCollection<OpaqueValue<Int>>,
941941
OpaqueValue<Int8>
942942
>.self,
@@ -985,7 +985,7 @@ tests.test("ReversedCollection/Lazy") {
985985

986986
let base = Array(stride(from: 11, through: 0, by: -1)).lazy.map { $0 }
987987

988-
typealias Base = LazyMapRandomAccessCollection<[Int], Int>
988+
typealias Base = LazyMapCollection<[Int], Int>
989989
ExpectType<Base>.test(base)
990990

991991
typealias LazyReversedBase = LazyRandomAccessCollection<
@@ -1007,8 +1007,7 @@ tests.test("ReversedCollection/Lazy") {
10071007
>
10081008

10091009
let base = "foobar".characters.lazy.map { $0 }
1010-
typealias Base = LazyMapBidirectionalCollection<
1011-
String.CharacterView, Character>
1010+
typealias Base = LazyMapCollection<String.CharacterView, Character>
10121011
ExpectType<Base>.test(base)
10131012

10141013
typealias LazyReversedBase = LazyBidirectionalCollection<

0 commit comments

Comments
 (0)