EitherSequence.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // This source file is part of the Swift Algorithms open source project
  4. //
  5. // Copyright (c) 2021 Apple Inc. and the Swift project authors
  6. // Licensed under Apache License v2.0 with Runtime Library Exception
  7. //
  8. // See https://swift.org/LICENSE.txt for license information
  9. //
  10. //===----------------------------------------------------------------------===//
  11. //===----------------------------------------------------------------------===//
  12. // Either
  13. //===----------------------------------------------------------------------===//
  14. /// A general-purpose sum type.
  15. @usableFromInline
  16. internal enum Either<Left, Right> {
  17. case left(Left)
  18. case right(Right)
  19. }
  20. extension Either: Equatable where Left: Equatable, Right: Equatable {
  21. @usableFromInline
  22. internal static func == (lhs: Self, rhs: Self) -> Bool {
  23. switch (lhs, rhs) {
  24. case let (.left(lhs), .left(rhs)):
  25. return lhs == rhs
  26. case let (.right(lhs), .right(rhs)):
  27. return lhs == rhs
  28. case (.left, .right), (.right, .left):
  29. return false
  30. }
  31. }
  32. }
  33. extension Either: Comparable where Left: Comparable, Right: Comparable {
  34. @usableFromInline
  35. internal static func < (lhs: Self, rhs: Self) -> Bool {
  36. switch (lhs, rhs) {
  37. case let (.left(lhs), .left(rhs)):
  38. return lhs < rhs
  39. case let (.right(lhs), .right(rhs)):
  40. return lhs < rhs
  41. case (.left, .right):
  42. return true
  43. case (.right, .left):
  44. return false
  45. }
  46. }
  47. }
  48. //===----------------------------------------------------------------------===//
  49. // EitherSequence
  50. //===----------------------------------------------------------------------===//
  51. /// A sequence that has one of the two specified types.
  52. @usableFromInline
  53. internal enum EitherSequence<Left: Sequence, Right: Sequence>
  54. where Left.Element == Right.Element
  55. {
  56. case left(Left)
  57. case right(Right)
  58. }
  59. extension EitherSequence: Sequence {
  60. @usableFromInline
  61. internal struct Iterator: IteratorProtocol {
  62. @usableFromInline
  63. internal var left: Left.Iterator?
  64. @usableFromInline
  65. internal var right: Right.Iterator?
  66. @inlinable
  67. internal mutating func next() -> Left.Element? {
  68. left?.next() ?? right?.next()
  69. }
  70. }
  71. @usableFromInline
  72. internal func makeIterator() -> Iterator {
  73. switch self {
  74. case .left(let left):
  75. return Iterator(left: left.makeIterator(), right: nil)
  76. case .right(let right):
  77. return Iterator(left: nil, right: right.makeIterator())
  78. }
  79. }
  80. }
  81. extension EitherSequence: Collection
  82. where Left: Collection, Right: Collection, Left.Element == Right.Element
  83. {
  84. @usableFromInline
  85. internal typealias Index = Either<Left.Index, Right.Index>
  86. @inlinable
  87. internal var startIndex: Index {
  88. switch self {
  89. case .left(let s):
  90. return .left(s.startIndex)
  91. case .right(let s):
  92. return .right(s.startIndex)
  93. }
  94. }
  95. @inlinable
  96. internal var endIndex: Index {
  97. switch self {
  98. case .left(let s):
  99. return .left(s.endIndex)
  100. case .right(let s):
  101. return .right(s.endIndex)
  102. }
  103. }
  104. @inlinable
  105. internal subscript(position: Index) -> Element {
  106. switch (self, position) {
  107. case let (.left(s), .left(i)):
  108. return s[i]
  109. case let (.right(s), .right(i)):
  110. return s[i]
  111. default:
  112. fatalError()
  113. }
  114. }
  115. @inlinable
  116. internal func index(after i: Index) -> Index {
  117. switch (self,i) {
  118. case let (.left(s), .left(i)):
  119. return .left(s.index(after: i))
  120. case let (.right(s), .right(i)):
  121. return .right(s.index(after: i))
  122. default:
  123. fatalError()
  124. }
  125. }
  126. @inlinable
  127. internal func index(
  128. _ i: Index,
  129. offsetBy distance: Int,
  130. limitedBy limit: Index
  131. ) -> Index? {
  132. switch (self, i, limit) {
  133. case let (.left(s), .left(i), .left(limit)):
  134. return s.index(i, offsetBy: distance, limitedBy: limit).map { .left($0) }
  135. case let (.right(s), .right(i), .right(limit)):
  136. return s.index(i, offsetBy: distance, limitedBy: limit).map { .right($0) }
  137. default:
  138. fatalError()
  139. }
  140. }
  141. @inlinable
  142. internal func index(_ i: Index, offsetBy distance: Int) -> Index {
  143. switch (self, i) {
  144. case let (.left(s), .left(i)):
  145. return .left(s.index(i, offsetBy: distance))
  146. case let (.right(s), .right(i)):
  147. return .right(s.index(i, offsetBy: distance))
  148. default:
  149. fatalError()
  150. }
  151. }
  152. @inlinable
  153. internal func distance(from start: Index, to end: Index) -> Int {
  154. switch (self, start, end) {
  155. case let (.left(s), .left(i), .left(j)):
  156. return s.distance(from: i, to: j)
  157. case let (.right(s), .right(i), .right(j)):
  158. return s.distance(from: i, to: j)
  159. default:
  160. fatalError()
  161. }
  162. }
  163. }
  164. extension EitherSequence: BidirectionalCollection
  165. where Left: BidirectionalCollection, Right: BidirectionalCollection
  166. {
  167. @inlinable
  168. internal func index(before i: Index) -> Index {
  169. switch (self, i) {
  170. case let (.left(s), .left(i)):
  171. return .left(s.index(before: i))
  172. case let (.right(s), .right(i)):
  173. return .right(s.index(before: i))
  174. default:
  175. fatalError()
  176. }
  177. }
  178. }
  179. extension EitherSequence: RandomAccessCollection
  180. where Left: RandomAccessCollection, Right: RandomAccessCollection {}