Suffix.swift 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. // suffix(while:)
  13. //===----------------------------------------------------------------------===//
  14. extension BidirectionalCollection {
  15. /// Returns a subsequence containing the elements from the end until
  16. /// `predicate` returns `false` and skipping the remaining elements.
  17. ///
  18. /// - Parameter predicate: A closure that takes an element of the sequence as
  19. /// its argument and returns `true` if the element should be included or
  20. /// `false` if it should be excluded. Once the predicate returns `false` it
  21. /// will not be called again.
  22. ///
  23. /// - Complexity: O(*n*), where *n* is the length of the collection.
  24. @inlinable
  25. public func suffix(
  26. while predicate: (Element) throws -> Bool
  27. ) rethrows -> SubSequence {
  28. try self[startOfSuffix(while: predicate)...]
  29. }
  30. }
  31. //===----------------------------------------------------------------------===//
  32. // endOfPrefix(while:)
  33. //===----------------------------------------------------------------------===//
  34. extension Collection {
  35. /// Returns the exclusive upper bound of the prefix of elements that satisfy
  36. /// the predicate.
  37. ///
  38. /// - Parameter predicate: A closure that takes an element of the collection
  39. /// as its argument and returns `true` if the element is part of the prefix
  40. /// or `false` if it is not. Once the predicate returns `false` it will not
  41. /// be called again.
  42. ///
  43. /// - Complexity: O(*n*), where *n* is the length of the collection.
  44. @inlinable
  45. internal func endOfPrefix(
  46. while predicate: (Element) throws -> Bool
  47. ) rethrows -> Index {
  48. var index = startIndex
  49. while try index != endIndex && predicate(self[index]) {
  50. formIndex(after: &index)
  51. }
  52. return index
  53. }
  54. }
  55. //===----------------------------------------------------------------------===//
  56. // startOfSuffix(while:)
  57. //===----------------------------------------------------------------------===//
  58. extension BidirectionalCollection {
  59. /// Returns the inclusive lower bound of the suffix of elements that satisfy
  60. /// the predicate.
  61. ///
  62. /// - Parameter predicate: A closure that takes an element of the collection
  63. /// as its argument and returns `true` if the element is part of the suffix
  64. /// or `false` if it is not. Once the predicate returns `false` it will not
  65. /// be called again.
  66. ///
  67. /// - Complexity: O(*n*), where *n* is the length of the collection.
  68. @inlinable
  69. internal func startOfSuffix(
  70. while predicate: (Element) throws -> Bool
  71. ) rethrows -> Index {
  72. var index = endIndex
  73. while index != startIndex {
  74. let after = index
  75. formIndex(before: &index)
  76. if try !predicate(self[index]) {
  77. return after
  78. }
  79. }
  80. return index
  81. }
  82. }