Skip to content

Commit 267011c

Browse files
committed
Merge pull request #895 from moiseev/anysequence
[stdlib] Constraining `AnySequence.init`
2 parents 695a78c + 1600c52 commit 267011c

File tree

2 files changed

+71
-60
lines changed

2 files changed

+71
-60
lines changed

stdlib/public/core/ExistentialCollection.swift.gyb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,14 @@ public struct AnySequence<Element> : SequenceType {
224224
public typealias T = Element
225225

226226
/// Wrap and forward operations to `base`.
227-
public init<S: SequenceType where S.Generator.Element == Element>(_ base: S) {
227+
public init<
228+
S: SequenceType
229+
where
230+
S.Generator.Element == Element,
231+
S.SubSequence : SequenceType,
232+
S.SubSequence.Generator.Element == Element,
233+
S.SubSequence.SubSequence == S.SubSequence
234+
>(_ base: S) {
228235
_box = _SequenceBox(base)
229236
}
230237

stdlib/public/core/Sequence.swift

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -331,63 +331,6 @@ extension SequenceType {
331331
return Array(result)
332332
}
333333

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-
391334
@warn_unused_result
392335
public func prefix(maxLength: Int) -> AnySequence<Generator.Element> {
393336
_precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
@@ -526,9 +469,7 @@ extension SequenceType {
526469
) -> Bool? {
527470
return nil
528471
}
529-
}
530472

531-
extension SequenceType {
532473
/// Call `body` on each element in `self` in the same order as a
533474
/// *for-in loop.*
534475
///
@@ -585,6 +526,69 @@ extension SequenceType where Generator.Element : Equatable {
585526
}
586527
}
587528

529+
extension SequenceType where
530+
SubSequence : SequenceType,
531+
SubSequence.Generator.Element == Generator.Element,
532+
SubSequence.SubSequence == SubSequence {
533+
534+
/// Returns a subsequence containing all but the first `n` elements.
535+
///
536+
/// - Requires: `n >= 0`
537+
/// - Complexity: O(`n`)
538+
@warn_unused_result
539+
public func dropFirst(n: Int) -> AnySequence<Generator.Element> {
540+
_precondition(n >= 0, "Can't drop a negative number of elements from a sequence")
541+
if n == 0 { return AnySequence(self) }
542+
// If this is already a _DropFirstSequence, we need to fold in
543+
// the current drop count and drop limit so no data is lost.
544+
//
545+
// i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to
546+
// [1,2,3,4].dropFirst(2).
547+
// FIXME: <rdar://problem/21885675> Use method dispatch to fold
548+
// _PrefixSequence and _DropFirstSequence counts
549+
if let any = self as? AnySequence<Generator.Element>,
550+
let box = any._box as? _SequenceBox<_DropFirstSequence<Generator>> {
551+
let base = box._base
552+
let folded = _DropFirstSequence(base.generator, limit: base.limit + n,
553+
dropped: base.dropped)
554+
return AnySequence(folded)
555+
}
556+
557+
return AnySequence(_DropFirstSequence(generate(), limit: n))
558+
}
559+
560+
/// Returns a subsequence containing all but the last `n` elements.
561+
///
562+
/// - Requires: `self` is a finite collection.
563+
/// - Requires: `n >= 0`
564+
/// - Complexity: O(`self.count`)
565+
@warn_unused_result
566+
public func dropLast(n: Int) -> AnySequence<Generator.Element> {
567+
_precondition(n >= 0, "Can't drop a negative number of elements from a sequence")
568+
if n == 0 { return AnySequence(self) }
569+
// FIXME: <rdar://problem/21885650> Create reusable RingBuffer<T>
570+
// Put incoming elements from this sequence in a holding tank, a ring buffer
571+
// of size <= n. If more elements keep coming in, pull them out of the
572+
// holding tank into the result, an `Array`. This saves
573+
// `n` * sizeof(Generator.Element) of memory, because slices keep the entire
574+
// memory of an `Array` alive.
575+
var result: [Generator.Element] = []
576+
var ringBuffer: [Generator.Element] = []
577+
var i = ringBuffer.startIndex
578+
579+
for element in self {
580+
if ringBuffer.count < n {
581+
ringBuffer.append(element)
582+
} else {
583+
result.append(ringBuffer[i])
584+
ringBuffer[i] = element
585+
i = i.successor() % n
586+
}
587+
}
588+
return AnySequence(result)
589+
}
590+
}
591+
588592
extension SequenceType {
589593
/// Returns a subsequence containing all but the first element.
590594
///

0 commit comments

Comments
 (0)