9
9
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10
10
//
11
11
//===----------------------------------------------------------------------===//
12
- // RUN: %empty-directory(%t)
13
- // RUN: %gyb -DWORD_BITS=%target-ptrsize %s -o %t/out.swift
14
- // RUN: %line-directive %t/out.swift -- %target-build-swift -parse-stdlib %t/out.swift -o %t/a.out -Onone -swift-version 4
15
- // RUN: %line-directive %t/out.swift -- %target-run %t/a.out
16
-
12
+ // RUN: %target-run-stdlib-swift
17
13
// REQUIRES: executable_test
18
14
19
15
import Swift
20
16
import StdlibUnittest
21
17
22
- % {
23
-
24
- from gyb_stdlib_support import (
25
- TRAVERSALS,
26
- collectionForTraversal,
27
- )
28
-
29
- } %
30
-
31
18
//===--- Rotate -----------------------------------------------------------===//
32
19
//===----------------------------------------------------------------------===//
33
20
@@ -286,86 +273,61 @@ extension MutableCollection where Self: RandomAccessCollection {
286
273
// Q: Add a ConcatenatedSequence for consistency? Would be nice to be able to
287
274
// call `let seqAB = concatenate(seqA, seqB)`.
288
275
289
- /// Represents a position in either the first or second collection of a
290
- /// `ConcatenatedCollection`.
291
- internal enum _ConcatenatedCollectionIndexRepresentation <
292
- I1 : Comparable , I2 : Comparable
293
- > {
294
- case first( I1 )
295
- case second( I2 )
296
- }
276
+ /// A concatenation of two collections with the same element type.
277
+ public struct Concatenation < C1 : Collection , C2: Collection > : Collection
278
+ where C1. Element == C2 . Element
279
+ {
280
+ let _base1 : C1
281
+ let _base2 : C2
297
282
298
- /// A position in a `ConcatenatedCollection` collection.
299
- public struct ConcatenatedCollectionIndex <
300
- C1 : Collection , C2 : Collection
301
- > : Comparable {
302
- /// Creates a new index into the first underlying collection.
303
- internal init ( first i: C1 . Index ) {
304
- _position = . first( i)
305
- }
306
-
307
- /// Creates a new index into the second underlying collection.
308
- internal init ( second i: C2 . Index ) {
309
- _position = . second( i)
310
- }
311
-
312
- internal let _position :
313
- _ConcatenatedCollectionIndexRepresentation < C1 . Index , C2 . Index >
314
-
315
- public static func < (
316
- lhs: ConcatenatedCollectionIndex , rhs: ConcatenatedCollectionIndex
317
- ) -> Bool {
318
- switch ( lhs. _position, rhs. _position) {
319
- case ( . first, . second) :
320
- return true
321
- case ( . second, . first) :
322
- return false
323
- case let ( . first( l) , . first( r) ) :
324
- return l < r
325
- case let ( . second( l) , . second( r) ) :
326
- return l < r
327
- }
283
+ init ( _base1: C1 , base2: C2 ) {
284
+ self . _base1 = _base1
285
+ self . _base2 = base2
328
286
}
329
287
330
- public static func == (
331
- lhs: ConcatenatedCollectionIndex , rhs: ConcatenatedCollectionIndex
332
- ) -> Bool {
333
- switch ( lhs. _position, rhs. _position) {
334
- case let ( . first( l) , . first( r) ) :
335
- return l == r
336
- case let ( . second( l) , . second( r) ) :
337
- return l == r
338
- default :
339
- return false
288
+ /// A position in a `Concatenation`.
289
+ public struct Index : Comparable {
290
+ internal enum _Representation : Equatable {
291
+ case first( C1 . Index )
292
+ case second( C2 . Index )
340
293
}
341
- }
342
- }
343
294
344
- % for Traversal in TRAVERSALS:
345
- % Collection = collectionForTraversal ( Traversal)
346
- % Self = " Concatenated " + Collection
295
+ /// Creates a new index into the first underlying collection.
296
+ internal init ( first i: C1 . Index ) {
297
+ _position = . first( i)
298
+ }
347
299
348
- /// A concatenation of two collections with the same element type.
349
- public struct ${ Self} < C1 : ${ Collection} , C2 : ${ Collection} > : ${ Collection}
350
- where C1 . Element == C2 . Element {
300
+ /// Creates a new index into the second underlying collection.
301
+ internal init ( second i: C2 . Index ) {
302
+ _position = . second( i)
303
+ }
351
304
352
- init ( _base1: C1 , base2: C2 ) {
353
- self . _base1 = _base1
354
- self . _base2 = base2
305
+ internal let _position : _Representation
306
+
307
+ public static func < ( lhs: Index , rhs: Index ) -> Bool {
308
+ switch ( lhs. _position, rhs. _position) {
309
+ case ( . first, . second) :
310
+ return true
311
+ case ( . second, . first) :
312
+ return false
313
+ case let ( . first( l) , . first( r) ) :
314
+ return l < r
315
+ case let ( . second( l) , . second( r) ) :
316
+ return l < r
317
+ }
318
+ }
355
319
}
356
320
357
- public typealias Index = ConcatenatedCollectionIndex < C1 , C2 >
358
-
359
321
public var startIndex : Index {
360
322
// If `_base1` is empty, then `_base2.startIndex` is either a valid position
361
323
// of an element or equal to `_base2.endIndex`.
362
324
return _base1. isEmpty
363
- ? ConcatenatedCollectionIndex ( second: _base2. startIndex)
364
- : ConcatenatedCollectionIndex ( first: _base1. startIndex)
325
+ ? Index ( second: _base2. startIndex)
326
+ : Index ( first: _base1. startIndex)
365
327
}
366
328
367
329
public var endIndex : Index {
368
- return ConcatenatedCollectionIndex ( second: _base2. endIndex)
330
+ return Index ( second: _base2. endIndex)
369
331
}
370
332
371
333
public subscript( i: Index ) -> C1 . Element {
@@ -383,29 +345,33 @@ public struct ${Self}<C1 : ${Collection}, C2: ${Collection}>: ${Collection}
383
345
_sanityCheck ( i != _base1. endIndex)
384
346
let next = _base1. index ( after: i)
385
347
return next == _base1. endIndex
386
- ? ConcatenatedCollectionIndex ( second: _base2. startIndex)
387
- : ConcatenatedCollectionIndex ( first: next)
348
+ ? Index ( second: _base2. startIndex)
349
+ : Index ( first: next)
388
350
case let . second( i) :
389
- return ConcatenatedCollectionIndex ( second: _base2. index ( after: i) )
351
+ return Index ( second: _base2. index ( after: i) )
390
352
}
391
353
}
354
+ }
392
355
393
- % if Traversal in [ 'Bidirectional', 'RandomAccess'] :
356
+ extension Concatenation : BidirectionalCollection
357
+ where C1: BidirectionalCollection , C2: BidirectionalCollection
358
+ {
394
359
public func index( before i: Index ) -> Index {
395
360
assert ( i != startIndex, " Can't advance before startIndex " )
396
361
switch i. _position {
397
362
case let . first( i) :
398
- return ConcatenatedCollectionIndex ( first: _base1. index ( before: i) )
363
+ return Index ( first: _base1. index ( before: i) )
399
364
case let . second( i) :
400
365
return i == _base2. startIndex
401
- ? ConcatenatedCollectionIndex (
402
- first: _base1. index ( before: _base1. endIndex) )
403
- : ConcatenatedCollectionIndex ( second: _base2. index ( before: i) )
366
+ ? Index ( first: _base1. index ( before: _base1. endIndex) )
367
+ : Index ( second: _base2. index ( before: i) )
404
368
}
405
369
}
406
- % end
370
+ }
407
371
408
- % if Traversal is 'RandomAccess':
372
+ extension Concatenation : RandomAccessCollection
373
+ where C1: RandomAccessCollection , C2: RandomAccessCollection
374
+ {
409
375
public func index( _ i: Index , offsetBy n: Int ) -> Index {
410
376
if n == 0 { return i }
411
377
return n > 0 ? _offsetForward ( i, by: n) : _offsetBackward ( i, by: - n)
@@ -418,15 +384,13 @@ public struct ${Self}<C1 : ${Collection}, C2: ${Collection}>: ${Collection}
418
384
case let . first( i) :
419
385
let d : Int = _base1. distance ( from: i, to: _base1. endIndex)
420
386
if n < d {
421
- return ConcatenatedCollectionIndex (
422
- first: _base1. index ( i, offsetBy: numericCast ( n) ) )
387
+ return Index ( first: _base1. index ( i, offsetBy: numericCast ( n) ) )
423
388
} else {
424
- return ConcatenatedCollectionIndex (
389
+ return Index (
425
390
second: _base2. index ( _base2. startIndex, offsetBy: numericCast ( n - d) ) )
426
391
}
427
392
case let . second( i) :
428
- return ConcatenatedCollectionIndex (
429
- second: _base2. index ( i, offsetBy: numericCast ( n) ) )
393
+ return Index ( second: _base2. index ( i, offsetBy: numericCast ( n) ) )
430
394
}
431
395
}
432
396
@@ -435,112 +399,100 @@ public struct ${Self}<C1 : ${Collection}, C2: ${Collection}>: ${Collection}
435
399
) -> Index {
436
400
switch i. _position {
437
401
case let . first( i) :
438
- return ConcatenatedCollectionIndex (
439
- first: _base1. index ( i, offsetBy: - numericCast( n) ) )
402
+ return Index ( first: _base1. index ( i, offsetBy: - numericCast( n) ) )
440
403
case let . second( i) :
441
404
let d : Int = _base2. distance ( from: _base2. startIndex, to: i)
442
405
if n <= d {
443
- return ConcatenatedCollectionIndex (
444
- second: _base2. index ( i, offsetBy: - numericCast( n) ) )
406
+ return Index ( second: _base2. index ( i, offsetBy: - numericCast( n) ) )
445
407
} else {
446
- return ConcatenatedCollectionIndex (
408
+ return Index (
447
409
first: _base1. index ( _base1. endIndex, offsetBy: - numericCast( n - d) ) )
448
410
}
449
411
}
450
412
}
451
- % end
452
-
453
- let _base1 : C1
454
- let _base2 : C2
455
413
}
456
414
457
415
/// Returns a new collection that presents a view onto the elements of the
458
416
/// first collection and then the elements of the second collection.
459
- func concatenate<
460
- C1 : ${ Collection} , C2 : ${ Collection}
461
- > ( _ first: C1 , _ second: C2 ) -> ${ Self} < C1 , C2>
462
- where C1 . Element == C2 . Element {
463
- return ${ Self} ( _base1: first, base2: second)
417
+ func concatenate< C1 : Collection , C2 : Collection > (
418
+ _ first: C1 ,
419
+ _ second: C2 )
420
+ -> Concatenation < C1 , C2 > where C1. Element == C2 . Element
421
+ {
422
+ return Concatenation ( _base1: first, base2: second)
464
423
}
465
424
466
- % end
467
-
468
425
//===--- RotatedCollection ------------------------------------------------===//
469
426
//===----------------------------------------------------------------------===//
470
427
471
- /// A position in a rotated collection.
472
- public struct RotatedCollectionIndex < Base : Collection > : Comparable {
473
- internal let _index :
474
- ConcatenatedCollectionIndex < Base . SubSequence , Base . SubSequence >
428
+ /// A rotated view onto a collection.
429
+ public struct RotatedCollection < Base : Collection > : Collection {
430
+ let _base : Base
431
+ let _indices : Concatenation < Base . Indices , Base . Indices >
475
432
476
- public static func < (
477
- lhs: RotatedCollectionIndex , rhs: RotatedCollectionIndex
478
- ) -> Bool {
479
- return lhs. _index < rhs. _index
480
- }
481
-
482
- public static func == (
483
- lhs: RotatedCollectionIndex , rhs: RotatedCollectionIndex
484
- ) -> Bool {
485
- return lhs. _index == rhs. _index
433
+ init ( _base: Base , shiftingToStart i: Base . Index ) {
434
+ self . _base = _base
435
+ self . _indices = concatenate ( _base. indices [ i... ] , _base. indices [ ..< i] )
486
436
}
487
- }
488
437
489
- % for Traversal in TRAVERSALS:
490
- % Collection = collectionForTraversal ( Traversal)
491
- % Self = " Rotated " + Collection
438
+ /// A position in a rotated collection.
439
+ public struct Index : Comparable {
440
+ internal let _index :
441
+ Concatenation < Base . Indices , Base . Indices > . Index
492
442
493
- /// A rotated view onto a `${Collection}`.
494
- public struct ${ Self} <
495
- Base : ${ Collection}
496
- > : ${ Collection} {
497
- let _concatenation : Concatenated ${ Collection} <
498
- Base . SubSequence, Base. SubSequence>
499
-
500
- init ( _base: Base, shiftingToStart i: Base . Index) {
501
- _concatenation = concatenate ( _base [ i... ] , _base [ ..< i] )
443
+ public static func < ( lhs: Index , rhs: Index ) -> Bool {
444
+ return lhs. _index < rhs. _index
445
+ }
502
446
}
503
447
504
- public typealias Index = RotatedCollectionIndex < Base >
505
-
506
448
public var startIndex : Index {
507
- return RotatedCollectionIndex ( _index: _concatenation . startIndex)
449
+ return Index ( _index: _indices . startIndex)
508
450
}
509
451
510
452
public var endIndex : Index {
511
- return RotatedCollectionIndex ( _index: _concatenation . endIndex)
453
+ return Index ( _index: _indices . endIndex)
512
454
}
513
455
514
456
public subscript( i: Index ) -> Base . SubSequence . Element {
515
- return _concatenation [ i. _index]
457
+ return _base [ _indices [ i. _index] ]
516
458
}
517
459
518
460
public func index( after i: Index ) -> Index {
519
- return RotatedCollectionIndex ( _index: _concatenation . index ( after: i. _index) )
461
+ return Index ( _index: _indices . index ( after: i. _index) )
520
462
}
521
463
522
- % if Traversal in [ 'Bidirectional', 'RandomAccess'] :
523
- public func index( before i: Index ) -> Index {
524
- return RotatedCollectionIndex (
525
- _index: _concatenation. index ( before: i. _index) )
464
+ public func index( _ i: Index , offsetBy n: Int ) -> Index {
465
+ return Index ( _index: _indices. index ( i. _index, offsetBy: n) )
526
466
}
527
- % end
528
467
529
- public func index( _ i: Index , offsetBy n: Int ) -> Index {
530
- return RotatedCollectionIndex (
531
- _index: _concatenation. index ( i. _index, offsetBy: n) )
468
+ public func distance( from start: Index , to end: Index ) -> Int {
469
+ return _indices. distance ( from: start. _index, to: end. _index)
532
470
}
533
471
534
472
/// The shifted position of the base collection's `startIndex`.
535
473
public var shiftedStartIndex : Index {
536
- return RotatedCollectionIndex (
537
- _index: ConcatenatedCollectionIndex (
538
- second: _concatenation . _base2. startIndex)
474
+ return Index (
475
+ _index: Concatenation < Base . Indices , Base . Indices > . Index (
476
+ second: _indices . _base2. startIndex)
539
477
)
540
478
}
479
+
480
+ public func rotated( shiftingToStart i: Index ) -> RotatedCollection < Base > {
481
+ return RotatedCollection ( _base: _base, shiftingToStart: _indices [ i. _index] )
482
+ }
541
483
}
542
484
543
- extension ${ Collection} {
485
+ extension RotatedCollection : BidirectionalCollection
486
+ where Base : BidirectionalCollection {
487
+ public func index( before i: Index ) -> Index {
488
+ return Index ( _index: _indices. index ( before: i. _index) )
489
+ }
490
+ }
491
+
492
+ extension RotatedCollection : RandomAccessCollection
493
+ where Base : RandomAccessCollection { }
494
+
495
+ extension Collection {
544
496
/// Returns a view of this collection with the elements reordered such the
545
497
/// element at the given position ends up first.
546
498
///
@@ -556,13 +508,11 @@ extension ${Collection} {
556
508
/// result. `i` must be a valid index of the collection.
557
509
/// - Returns: A rotated view on the elements of this collection, such that
558
510
/// the element at `i` is first.
559
- func rotated( shiftingToStart i: Index ) -> $ { Self } < Self> {
560
- return $ { Self } ( _base: self , shiftingToStart: i)
511
+ func rotated( shiftingToStart i: Index ) -> RotatedCollection < Self > {
512
+ return RotatedCollection ( _base: self , shiftingToStart: i)
561
513
}
562
514
}
563
515
564
- % end
565
-
566
516
//===--- Stable Partition -------------------------------------------------===//
567
517
//===----------------------------------------------------------------------===//
568
518
0 commit comments