Guest User

Untitled

a guest
Mar 24th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.37 KB | None | 0 0
  1. /// A default index type for a type that only supplies
  2. /// `IteratorProtocol` conformance and value semantics
  3. enum SequenceIndex<Base: Sequence> : Comparable {
  4.  
  5. init() { self = .end }
  6.  
  7. init(_ s: Base) {
  8. self = .normal(0, s.makeIterator())
  9. }
  10.  
  11.  
  12. /// An index of an element in the collection.
  13. ///
  14. /// The associated values are:
  15. /// - The zero-based position in the collection, for `Comparable` purposes.
  16. /// - The element itself, so that it only needs to be computed once.
  17. /// - The state, immediately after generating the element at this index.
  18. case normal(Int, Base.Iterator)
  19.  
  20. /// An index representing the end of the collection.
  21. case end
  22.  
  23. var isEnd: Bool {
  24. if case .normal(_, var i) = self { return i.next() == nil }
  25. return true
  26. }
  27.  
  28. static func ==(lhs: SequenceIndex, rhs: SequenceIndex) -> Bool {
  29. if case .normal(let l, _) = lhs, case .normal(let r, _) = rhs {
  30. return l == r
  31. }
  32. return lhs.isEnd == rhs.isEnd
  33. }
  34.  
  35. static func < (lhs: SequenceIndex, rhs: SequenceIndex) -> Bool {
  36. if case .normal(let l, _) = lhs, case .normal(let r, _) = rhs {
  37. return l < r
  38. }
  39. return !lhs.isEnd && rhs.isEnd
  40. }
  41.  
  42. mutating func stepForward() {
  43. guard case .normal(let pos, var i) = self else {
  44. fatalError("Can't advance past end")
  45. }
  46. _ = i.next()
  47. self = .normal(pos + 1, i)
  48. }
  49.  
  50. func distance(to other: SequenceIndex) -> Int {
  51. switch (self, other) {
  52. case (.end, .end): return 0
  53. case (.normal(let l, _), .normal(let r, _)): return r - l
  54. default: break
  55. }
  56. var i = self
  57. var n = 0
  58. while i != .end { i.stepForward(); n += 1 }
  59. return n
  60. }
  61.  
  62. var element: Base.Element {
  63. guard case .normal(_, var i) = self else {
  64. fatalError("Can't subscript at end")
  65. }
  66. return i.next()!
  67. }
  68. }
  69.  
  70. protocol MultipassSequence : Collection {}
  71.  
  72. extension MultipassSequence {
  73. var startIndex: SequenceIndex<Self> {
  74. return SequenceIndex(self)
  75. }
  76.  
  77. var endIndex: SequenceIndex<Self> {
  78. return SequenceIndex()
  79. }
  80.  
  81. subscript(i: SequenceIndex<Self>) -> Iterator.Element {
  82. return i.element
  83. }
  84.  
  85. func index(after i: SequenceIndex<Self>) -> SequenceIndex<Self> {
  86. var j = i
  87. j.stepForward()
  88. return j
  89. }
  90.  
  91. func formIndex(after i: inout SequenceIndex<Self>) {
  92. i.stepForward()
  93. }
  94.  
  95. typealias SubSequence = MultipassSubSequence<Self>
  96. subscript(r: Range<SequenceIndex<Self>>) -> MultipassSubSequence<Self> {
  97. return MultipassSubSequence(
  98. startIndex: r.lowerBound,
  99. endIndex: r.upperBound
  100. )
  101. }
  102. }
  103.  
  104. struct MultipassSubSequence<Base: MultipassSequence> : Collection {
  105. typealias Element = Base.Element
  106. typealias Index = SequenceIndex<Base>
  107. typealias SubSequence = MultipassSubSequence
  108.  
  109. let startIndex, endIndex: Index
  110.  
  111. subscript(i: Index) -> Iterator.Element {
  112. return i.element
  113. }
  114.  
  115. func index(after i: Index) -> Index {
  116. var j = i
  117. j.stepForward()
  118. return j
  119. }
  120.  
  121. func formIndex(after i: inout Index) {
  122. i.stepForward()
  123. }
  124.  
  125. subscript(r: Range<SequenceIndex<Base>>) -> MultipassSubSequence {
  126. return MultipassSubSequence(
  127. startIndex: r.lowerBound,
  128. endIndex: r.upperBound
  129. )
  130. }
  131. }
  132.  
  133. extension Collection {
  134. /// Returns the index of the first element in the collection
  135. /// that matches the predicate.
  136. ///
  137. /// The collection must already be partitioned according to the
  138. /// predicate, as if `self.partition(by: predicate)` had already
  139. /// been called.
  140. func partitionPoint(
  141. where predicate: (Element) throws -> Bool
  142. ) rethrows -> Index {
  143. var n = count
  144. var l = startIndex
  145.  
  146. while n > 0 {
  147. let half = n / 2
  148. let mid = index(l, offsetBy: half)
  149. if try predicate(self[mid]) {
  150. n = half
  151. } else {
  152. l = index(after: mid)
  153. n -= half + 1
  154. }
  155. }
  156. return l
  157. }
  158. }
  159.  
  160. /// A minimal sequence that gets its `Collection` conformance by declaring its
  161. /// `Index == SequenceIndex`.
  162. struct S: MultipassSequence, IteratorProtocol {
  163. typealias Iterator = S
  164. typealias Index = SequenceIndex<S>
  165.  
  166. var n = 0
  167. var m = 1
  168. mutating func next() -> Int? {
  169. let r = n
  170. (n, m) = (m, n + m)
  171. return r
  172. }
  173. }
  174.  
  175. let s = S()
  176. print(Array(s.prefix(5))) // [0, 1, 1, 2, 3]
  177. let i = s.index(where: { $0 > 6 })!
  178. print(Array(s[i...].prefix(5))) // [8, 13, 21, 34, 55]
  179.  
  180. let s2 = S().prefix(90)
  181. print(
  182. s2.distance(
  183. from: s2.startIndex, to: s2.partitionPoint { $0 >= 1000 }))
Add Comment
Please, Sign In to add comment