File: DropWhile.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (167 lines) | stat: -rw-r--r-- 5,685 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//===--- DropWhile.swift - Lazy views for drop(while:) --------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

/// A sequence whose elements consist of the elements that follow the initial
/// consecutive elements of some base sequence that satisfy a given predicate.
@frozen // lazy-performance
public struct LazyDropWhileSequence<Base: Sequence> {
  public typealias Element = Base.Element

  @usableFromInline // lazy-performance
  internal var _base: Base
  @usableFromInline // lazy-performance
  internal let _predicate: (Element) -> Bool

  /// Create an instance with elements `transform(x)` for each element
  /// `x` of base.
  @inlinable // lazy-performance
  internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
    self._base = _base
    self._predicate = predicate
  }
}

@available(*, unavailable)
extension LazyDropWhileSequence: Sendable {}

extension LazyDropWhileSequence {
  /// An iterator over the elements traversed by a base iterator that follow the
  /// initial consecutive elements that satisfy a given predicate.
  ///
  /// This is the associated iterator for the `LazyDropWhileSequence`,
  /// `LazyDropWhileCollection`, and `LazyDropWhileBidirectionalCollection`
  /// types.
  @frozen // lazy-performance
  public struct Iterator {
    public typealias Element = Base.Element

    @usableFromInline // lazy-performance
    internal var _predicateHasFailed = false
    @usableFromInline // lazy-performance
    internal var _base: Base.Iterator
    @usableFromInline // lazy-performance
    internal let _predicate: (Element) -> Bool

    @inlinable // lazy-performance
    internal init(_base: Base.Iterator, predicate: @escaping (Element) -> Bool) {
      self._base = _base
      self._predicate = predicate
    }
  }
}

@available(*, unavailable)
extension LazyDropWhileSequence.Iterator: Sendable {}

extension LazyDropWhileSequence.Iterator: IteratorProtocol {
  @inlinable // lazy-performance
  public mutating func next() -> Element? {
    // Once the predicate has failed for the first time, the base iterator
    // can be used for the rest of the elements.
    if _predicateHasFailed {
      return _base.next()
    }

    // Retrieve and discard elements from the base iterator until one fails
    // the predicate.
    while let nextElement = _base.next() {
      if !_predicate(nextElement) {
        _predicateHasFailed = true
        return nextElement
      }
    }
    return nil
  }  
}

extension LazyDropWhileSequence: Sequence {
  /// Returns an iterator over the elements of this sequence.
  ///
  /// - Complexity: O(1).
  @inlinable // lazy-performance
  public __consuming func makeIterator() -> Iterator {
    return Iterator(_base: _base.makeIterator(), predicate: _predicate)
  }
}

extension LazyDropWhileSequence: LazySequenceProtocol {
  public typealias Elements = LazyDropWhileSequence
}

extension LazySequenceProtocol {
  /// Returns a lazy sequence that skips any initial elements that satisfy
  /// `predicate`.
  ///
  /// - Parameter predicate: A closure that takes an element of the sequence as
  ///   its argument and returns `true` if the element should be skipped or
  ///   `false` otherwise. Once `predicate` returns `false` it will not be
  ///   called again.
  @inlinable // lazy-performance
  public __consuming func drop(
    while predicate: @escaping (Elements.Element) -> Bool
  ) -> LazyDropWhileSequence<Self.Elements> {
    return LazyDropWhileSequence(_base: self.elements, predicate: predicate)
  }
}

/// A lazy wrapper that includes the elements of an underlying
/// collection after any initial consecutive elements that satisfy a
/// predicate.
///
/// - Note: The performance of accessing `startIndex`, `first`, or any methods
///   that depend on `startIndex` depends on how many elements satisfy the
///   predicate at the start of the collection, and may not offer the usual
///   performance given by the `Collection` protocol. Be aware, therefore,
///   that general operations on lazy collections may not have the
///   documented complexity.
public typealias LazyDropWhileCollection<T: Collection> = LazyDropWhileSequence<T>

extension LazyDropWhileCollection: Collection {
  public typealias SubSequence = Slice<LazyDropWhileCollection<Base>>
  public typealias Index = Base.Index

  @inlinable // lazy-performance
  public var startIndex: Index {
    var index = _base.startIndex
    while index != _base.endIndex && _predicate(_base[index]) {
      _base.formIndex(after: &index)
    }
    return index
  }

  @inlinable // lazy-performance
  public var endIndex: Index {
    return _base.endIndex
  }

  @inlinable // lazy-performance
  public func index(after i: Index) -> Index {
    _precondition(i < _base.endIndex, "Can't advance past endIndex")
    return _base.index(after: i)
  }

  @inlinable // lazy-performance
  public subscript(position: Index) -> Element {
    return _base[position]
  }
}

extension LazyDropWhileCollection: BidirectionalCollection 
where Base: BidirectionalCollection {
  @inlinable // lazy-performance
  public func index(before i: Index) -> Index {
    _precondition(i > startIndex, "Can't move before startIndex")
    return _base.index(before: i)
  }
}

extension LazyDropWhileCollection: LazyCollectionProtocol { }