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
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021-2022 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
//
//===----------------------------------------------------------------------===//
// MARK: `CollectionConsumer` algorithms
extension Collection {
func _trimmingPrefix<Consumer: CollectionConsumer>(
_ consumer: Consumer
) -> SubSequence where Consumer.Consumed == Self {
let start = consumer.consuming(self) ?? startIndex
return self[start...]
}
}
extension Collection where SubSequence == Self {
mutating func _trimPrefix<Consumer: CollectionConsumer>(
_ consumer: Consumer
) where Consumer.Consumed == Self {
_ = consumer.consume(&self)
}
}
extension RangeReplaceableCollection {
// NOTE: Disfavored because the `Collection with SubSequence == Self` overload
// should be preferred whenever both are available
@_disfavoredOverload
mutating func _trimPrefix<Consumer: CollectionConsumer>(
_ consumer: Consumer
) where Consumer.Consumed == Self {
if let start = consumer.consuming(self) {
removeSubrange(..<start)
}
}
}
// MARK: Predicate algorithms
extension Collection {
fileprivate func _endOfPrefix(while predicate: (Element) throws -> Bool) rethrows -> Index {
try firstIndex(where: { try !predicate($0) }) ?? endIndex
}
@available(SwiftStdlib 5.7, *)
public func trimmingPrefix(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence {
let end = try _endOfPrefix(while: predicate)
return self[end...]
}
}
extension Collection where SubSequence == Self {
@available(SwiftStdlib 5.7, *)
public mutating func trimPrefix(
while predicate: (Element) throws -> Bool
) throws {
let end = try _endOfPrefix(while: predicate)
self = self[end...]
}
}
extension RangeReplaceableCollection {
@_disfavoredOverload
@available(SwiftStdlib 5.7, *)
public mutating func trimPrefix(
while predicate: (Element) throws -> Bool
) rethrows {
let end = try _endOfPrefix(while: predicate)
removeSubrange(startIndex..<end)
}
}
// MARK: Fixed pattern algorithms
extension Collection where Element: Equatable {
/// Returns a new collection of the same type by removing `prefix` from the start
/// of the collection.
/// - Parameter prefix: The collection to remove from this collection.
/// - Returns: A collection containing the elements of the collection that are
/// not removed by `prefix`.
@available(SwiftStdlib 5.7, *)
public func trimmingPrefix<Prefix: Sequence>(
_ prefix: Prefix
) -> SubSequence where Prefix.Element == Element {
_trimmingPrefix(FixedPatternConsumer(pattern: prefix))
}
}
extension Collection where SubSequence == Self, Element: Equatable {
/// Removes `prefix` from the start of the collection.
/// - Parameter prefix: The collection to remove from this collection.
@available(SwiftStdlib 5.7, *)
public mutating func trimPrefix<Prefix: Sequence>(
_ prefix: Prefix
) where Prefix.Element == Element {
_trimPrefix(FixedPatternConsumer<SubSequence, Prefix>(pattern: prefix))
}
}
extension RangeReplaceableCollection where Element: Equatable {
/// Removes `prefix` from the start of the collection.
/// - Parameter prefix: The collection to remove from this collection.
@available(SwiftStdlib 5.7, *)
public mutating func trimPrefix<Prefix: Sequence>(
_ prefix: Prefix
) where Prefix.Element == Element {
_trimPrefix(FixedPatternConsumer(pattern: prefix))
}
}
// MARK: Regex algorithms
extension BidirectionalCollection where SubSequence == Substring {
/// Returns a new collection of the same type by removing the initial elements
/// that matches the given regex.
/// - Parameter regex: The regex to remove from this collection.
/// - Returns: A collection containing the elements that does not match
/// `regex` from the start.
@_disfavoredOverload
@available(SwiftStdlib 5.7, *)
public func trimmingPrefix(_ regex: some RegexComponent) -> SubSequence {
let s = self[...]
guard let prefix = try? regex.regex.prefixMatch(in: s) else {
return s
}
return s[prefix.range.upperBound...]
}
}
extension RangeReplaceableCollection
where Self: BidirectionalCollection, SubSequence == Substring
{
/// Removes the initial elements that matches the given regex.
/// - Parameter regex: The regex to remove from this collection.
@_disfavoredOverload
@available(SwiftStdlib 5.7, *)
public mutating func trimPrefix(_ regex: some RegexComponent) {
let s = self[...]
guard let prefix = try? regex.regex.prefixMatch(in: s) else {
return
}
self.removeSubrange(prefix.range)
}
}
|