@@ -274,42 +274,59 @@ extension MutableCollection where Self: RandomAccessCollection {
274
274
}
275
275
}
276
276
277
- //===--- ConcatenatedCollection -------------------------------------------===//
277
+ //===--- Concatenation --------- -------------------------------------------===//
278
278
//===----------------------------------------------------------------------===//
279
279
280
- // ConcatenatedCollection improves on a flattened array or other collection by
280
+ // Concatenation improves on a flattened array or other collection by
281
281
// allowing random-access traversal if the underlying collections are
282
282
// random-access.
283
- //
284
- // Q: Add a ConcatenatedSequence for consistency? Would be nice to be able to
285
- // call `let seqAB = concatenate(seqA, seqB)`.
286
283
287
- /// A concatenation of two collections with the same element type.
288
- public struct Concatenation < C1 : Collection , C2 : Collection > : Collection
289
- where C1 . Element == C2 . Element
284
+ /// A concatenation of two sequences with the same element type.
285
+ public struct Concatenation < Base1 : Sequence , Base2 : Sequence > : Sequence
286
+ where Base1 . Element == Base2 . Element
290
287
{
291
- let _base1 : C1
292
- let _base2 : C2
288
+ let _base1 : Base1
289
+ let _base2 : Base2
293
290
294
- init ( _base1: C1 , base2: C2 ) {
291
+ init ( _base1: Base1 , base2: Base2 ) {
295
292
self . _base1 = _base1
296
293
self . _base2 = base2
297
294
}
295
+
296
+ public struct Iterator : IteratorProtocol {
297
+ var _iterator1 : Base1 . Iterator
298
+ var _iterator2 : Base2 . Iterator
299
+
300
+ init ( _ concatenation: Concatenation ) {
301
+ _iterator1 = concatenation. _base1. makeIterator ( )
302
+ _iterator2 = concatenation. _base2. makeIterator ( )
303
+ }
304
+
305
+ public mutating func next( ) -> Base1 . Element ? {
306
+ return _iterator1. next ( ) ?? _iterator2. next ( )
307
+ }
308
+ }
309
+
310
+ public func makeIterator( ) -> Iterator {
311
+ Iterator ( self )
312
+ }
313
+ }
298
314
315
+ extension Concatenation : Collection where Base1: Collection , Base2: Collection {
299
316
/// A position in a `Concatenation`.
300
317
public struct Index : Comparable {
301
318
internal enum _Representation : Equatable {
302
- case first( C1 . Index )
303
- case second( C2 . Index )
319
+ case first( Base1 . Index )
320
+ case second( Base2 . Index )
304
321
}
305
322
306
323
/// Creates a new index into the first underlying collection.
307
- internal init ( first i: C1 . Index ) {
324
+ internal init ( first i: Base1 . Index ) {
308
325
_position = . first( i)
309
326
}
310
327
311
328
/// Creates a new index into the second underlying collection.
312
- internal init ( second i: C2 . Index ) {
329
+ internal init ( second i: Base2 . Index ) {
313
330
_position = . second( i)
314
331
}
315
332
@@ -341,7 +358,7 @@ public struct Concatenation<C1 : Collection, C2: Collection>: Collection
341
358
return Index ( second: _base2. endIndex)
342
359
}
343
360
344
- public subscript( i: Index ) -> C1 . Element {
361
+ public subscript( i: Index ) -> Base1 . Element {
345
362
switch i. _position {
346
363
case let . first( i) :
347
364
return _base1 [ i]
@@ -365,7 +382,7 @@ public struct Concatenation<C1 : Collection, C2: Collection>: Collection
365
382
}
366
383
367
384
extension Concatenation : BidirectionalCollection
368
- where C1 : BidirectionalCollection , C2 : BidirectionalCollection
385
+ where Base1 : BidirectionalCollection , Base2 : BidirectionalCollection
369
386
{
370
387
public func index( before i: Index ) -> Index {
371
388
assert ( i != startIndex, " Can't advance before startIndex " )
@@ -381,7 +398,7 @@ extension Concatenation : BidirectionalCollection
381
398
}
382
399
383
400
extension Concatenation : RandomAccessCollection
384
- where C1 : RandomAccessCollection , C2 : RandomAccessCollection
401
+ where Base1 : RandomAccessCollection , Base2 : RandomAccessCollection
385
402
{
386
403
public func index( _ i: Index , offsetBy n: Int ) -> Index {
387
404
if n == 0 { return i }
@@ -425,14 +442,22 @@ extension Concatenation : RandomAccessCollection
425
442
426
443
/// Returns a new collection that presents a view onto the elements of the
427
444
/// first collection and then the elements of the second collection.
428
- func concatenate< C1 : Collection , C2 : Collection > (
429
- _ first: C1 ,
430
- _ second: C2 )
431
- -> Concatenation < C1 , C2 > where C1 . Element == C2 . Element
445
+ func concatenate< S1 : Sequence , S2 : Sequence > (
446
+ _ first: S1 ,
447
+ _ second: S2 )
448
+ -> Concatenation < S1 , S2 > where S1 . Element == S2 . Element
432
449
{
433
450
return Concatenation ( _base1: first, base2: second)
434
451
}
435
452
453
+ extension Sequence {
454
+ func followed< S: Sequence > ( by other: S ) -> Concatenation < Self , S >
455
+ where Element == S . Element
456
+ {
457
+ return concatenate ( self , other)
458
+ }
459
+ }
460
+
436
461
//===--- RotatedCollection ------------------------------------------------===//
437
462
//===----------------------------------------------------------------------===//
438
463
@@ -763,6 +788,9 @@ suite.test("concatenate") {
763
788
let w = " world! "
764
789
let hw = concatenate ( h, w)
765
790
expectEqual ( " Hello, world! " , String ( hw) )
791
+
792
+ let run = ( 1 ... ) . prefix ( 10 ) . followed ( by: 20 ... )
793
+ expectEqual ( Array ( run. prefix ( 20 ) ) , Array ( 1 ... 10 ) + ( 20 ..< 30 ) )
766
794
}
767
795
768
796
suite. test ( " stablePartition " ) {
0 commit comments