@@ -244,6 +244,16 @@ internal class _DropFirstSequence<Base : GeneratorType>
244
244
}
245
245
return generator. next ( )
246
246
}
247
+
248
+ internal func dropFirst( n: Int ) -> AnySequence < Base . Element > {
249
+ // If this is already a _DropFirstSequence, we need to fold in
250
+ // the current drop count and drop limit so no data is lost.
251
+ //
252
+ // i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to
253
+ // [1,2,3,4].dropFirst(2).
254
+ return AnySequence (
255
+ _DropFirstSequence ( generator, limit: limit + n, dropped: dropped) )
256
+ }
247
257
}
248
258
249
259
/// A sequence that only consumes up to `n` elements from an underlying
@@ -253,7 +263,8 @@ internal class _DropFirstSequence<Base : GeneratorType>
253
263
///
254
264
/// This is a class - we require reference semantics to keep track
255
265
/// of how many elements we've already taken from the underlying sequence.
256
- internal class _PrefixSequence < Base : GeneratorType > : SequenceType , GeneratorType {
266
+ internal class _PrefixSequence < Base : GeneratorType >
267
+ : SequenceType , GeneratorType {
257
268
internal let maxLength : Int
258
269
internal var generator : Base
259
270
internal var taken : Int
@@ -279,6 +290,12 @@ internal class _PrefixSequence<Base : GeneratorType> : SequenceType, GeneratorTy
279
290
taken = maxLength
280
291
return nil
281
292
}
293
+
294
+ internal func prefix( maxLength: Int ) -> AnySequence < Base . Element > {
295
+ return AnySequence (
296
+ _PrefixSequence ( generator,
297
+ maxLength: min ( maxLength, self . maxLength) , taken: taken) )
298
+ }
282
299
}
283
300
284
301
//===----------------------------------------------------------------------===//
@@ -331,83 +348,6 @@ extension SequenceType {
331
348
return Array ( result)
332
349
}
333
350
334
- /// Returns a subsequence containing all but the first `n` elements.
335
- ///
336
- /// - Requires: `n >= 0`
337
- /// - Complexity: O(`n`)
338
- @warn_unused_result
339
- public func dropFirst( n: Int ) -> AnySequence < Generator . Element > {
340
- _precondition ( n >= 0 , " Can't drop a negative number of elements from a sequence " )
341
- if n == 0 { return AnySequence ( self ) }
342
- // If this is already a _DropFirstSequence, we need to fold in
343
- // the current drop count and drop limit so no data is lost.
344
- //
345
- // i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to
346
- // [1,2,3,4].dropFirst(2).
347
- // FIXME: <rdar://problem/21885675> Use method dispatch to fold
348
- // _PrefixSequence and _DropFirstSequence counts
349
- if let any = self as? AnySequence < Generator . Element > ,
350
- let box = any. _box as? _SequenceBox < _DropFirstSequence < Generator > > {
351
- let base = box. _base
352
- let folded = _DropFirstSequence ( base. generator, limit: base. limit + n,
353
- dropped: base. dropped)
354
- return AnySequence ( folded)
355
- }
356
-
357
- return AnySequence ( _DropFirstSequence ( generate ( ) , limit: n) )
358
- }
359
-
360
- /// Returns a subsequence containing all but the last `n` elements.
361
- ///
362
- /// - Requires: `self` is a finite collection.
363
- /// - Requires: `n >= 0`
364
- /// - Complexity: O(`self.count`)
365
- @warn_unused_result
366
- public func dropLast( n: Int ) -> AnySequence < Generator . Element > {
367
- _precondition ( n >= 0 , " Can't drop a negative number of elements from a sequence " )
368
- if n == 0 { return AnySequence ( self ) }
369
- // FIXME: <rdar://problem/21885650> Create reusable RingBuffer<T>
370
- // Put incoming elements from this sequence in a holding tank, a ring buffer
371
- // of size <= n. If more elements keep coming in, pull them out of the
372
- // holding tank into the result, an `Array`. This saves
373
- // `n` * sizeof(Generator.Element) of memory, because slices keep the entire
374
- // memory of an `Array` alive.
375
- var result : [ Generator . Element ] = [ ]
376
- var ringBuffer : [ Generator . Element ] = [ ]
377
- var i = ringBuffer. startIndex
378
-
379
- for element in self {
380
- if ringBuffer. count < n {
381
- ringBuffer. append ( element)
382
- } else {
383
- result. append ( ringBuffer [ i] )
384
- ringBuffer [ i] = element
385
- i = i. successor ( ) % n
386
- }
387
- }
388
- return AnySequence ( result)
389
- }
390
-
391
- @warn_unused_result
392
- public func prefix( maxLength: Int ) -> AnySequence < Generator . Element > {
393
- _precondition ( maxLength >= 0 , " Can't take a prefix of negative length from a sequence " )
394
- if maxLength == 0 {
395
- return AnySequence ( EmptyCollection < Generator . Element > ( ) )
396
- }
397
- // FIXME: <rdar://problem/21885675> Use method dispatch to fold
398
- // _PrefixSequence and _DropFirstSequence counts
399
- if let any = self as? AnySequence < Generator . Element > ,
400
- let box = any. _box as? _SequenceBox < _PrefixSequence < Generator > > {
401
- let base = box. _base
402
- let folded = _PrefixSequence (
403
- base. generator,
404
- maxLength: min ( base. maxLength, maxLength) ,
405
- taken: base. taken)
406
- return AnySequence ( folded)
407
- }
408
- return AnySequence ( _PrefixSequence ( generate ( ) , maxLength: maxLength) )
409
- }
410
-
411
351
@warn_unused_result
412
352
public func suffix( maxLength: Int ) -> AnySequence < Generator . Element > {
413
353
_precondition ( maxLength >= 0 , " Can't take a suffix of negative length from a sequence " )
@@ -526,9 +466,7 @@ extension SequenceType {
526
466
) -> Bool ? {
527
467
return nil
528
468
}
529
- }
530
469
531
- extension SequenceType {
532
470
/// Call `body` on each element in `self` in the same order as a
533
471
/// *for-in loop.*
534
472
///
@@ -585,6 +523,64 @@ extension SequenceType where Generator.Element : Equatable {
585
523
}
586
524
}
587
525
526
+ extension SequenceType where
527
+ SubSequence : SequenceType ,
528
+ SubSequence. Generator. Element == Generator . Element ,
529
+ SubSequence. SubSequence == SubSequence {
530
+
531
+ /// Returns a subsequence containing all but the first `n` elements.
532
+ ///
533
+ /// - Requires: `n >= 0`
534
+ /// - Complexity: O(`n`)
535
+ @warn_unused_result
536
+ public func dropFirst( n: Int ) -> AnySequence < Generator . Element > {
537
+ _precondition ( n >= 0 , " Can't drop a negative number of elements from a sequence " )
538
+ if n == 0 { return AnySequence ( self ) }
539
+ return AnySequence ( _DropFirstSequence ( generate ( ) , limit: n) )
540
+ }
541
+
542
+ /// Returns a subsequence containing all but the last `n` elements.
543
+ ///
544
+ /// - Requires: `self` is a finite collection.
545
+ /// - Requires: `n >= 0`
546
+ /// - Complexity: O(`self.count`)
547
+ @warn_unused_result
548
+ public func dropLast( n: Int ) -> AnySequence < Generator . Element > {
549
+ _precondition ( n >= 0 , " Can't drop a negative number of elements from a sequence " )
550
+ if n == 0 { return AnySequence ( self ) }
551
+
552
+ // FIXME: <rdar://problem/21885650> Create reusable RingBuffer<T>
553
+ // Put incoming elements from this sequence in a holding tank, a ring buffer
554
+ // of size <= n. If more elements keep coming in, pull them out of the
555
+ // holding tank into the result, an `Array`. This saves
556
+ // `n` * sizeof(Generator.Element) of memory, because slices keep the entire
557
+ // memory of an `Array` alive.
558
+ var result : [ Generator . Element ] = [ ]
559
+ var ringBuffer : [ Generator . Element ] = [ ]
560
+ var i = ringBuffer. startIndex
561
+
562
+ for element in self {
563
+ if ringBuffer. count < n {
564
+ ringBuffer. append ( element)
565
+ } else {
566
+ result. append ( ringBuffer [ i] )
567
+ ringBuffer [ i] = element
568
+ i = i. successor ( ) % n
569
+ }
570
+ }
571
+ return AnySequence ( result)
572
+ }
573
+
574
+ @warn_unused_result
575
+ public func prefix( maxLength: Int ) -> AnySequence < Generator . Element > {
576
+ _precondition ( maxLength >= 0 , " Can't take a prefix of negative length from a sequence " )
577
+ if maxLength == 0 {
578
+ return AnySequence ( EmptyCollection < Generator . Element > ( ) )
579
+ }
580
+ return AnySequence ( _PrefixSequence ( generate ( ) , maxLength: maxLength) )
581
+ }
582
+ }
583
+
588
584
extension SequenceType {
589
585
/// Returns a subsequence containing all but the first element.
590
586
///
0 commit comments