@@ -21,21 +21,49 @@ extension Collection {
21
21
}
22
22
23
23
// MARK: Fixed pattern algorithms
24
+ extension Substring {
25
+ @usableFromInline
26
+ func _firstRangeSubstring(
27
+ of other: Substring
28
+ ) -> Range < String . Index > ? {
29
+ var searcher = SubstringSearcher ( text: self , pattern: other)
30
+ return searcher. next ( )
31
+ }
32
+ }
24
33
25
34
extension Collection where Element: Equatable {
35
+ @usableFromInline
36
+ func _firstRangeGeneric< C: Collection > (
37
+ of other: C
38
+ ) -> Range < Index > ? where C. Element == Element {
39
+ let searcher = ZSearcher < SubSequence > ( pattern: Array ( other) , by: == )
40
+ return searcher. search ( self [ ... ] , in: startIndex..< endIndex)
41
+ }
42
+
26
43
/// Finds and returns the range of the first occurrence of a given collection
27
44
/// within this collection.
28
45
///
29
46
/// - Parameter other: The collection to search for.
30
47
/// - Returns: A range in the collection of the first occurrence of `sequence`.
31
48
/// Returns nil if `sequence` is not found.
32
49
@available ( SwiftStdlib 5 . 7 , * )
50
+ @inline ( __always)
33
51
public func firstRange< C: Collection > (
34
52
of other: C
35
53
) -> Range < Index > ? where C. Element == Element {
36
- // TODO: Use a more efficient search algorithm
37
- let searcher = ZSearcher < SubSequence > ( pattern: Array ( other) , by: == )
38
- return searcher. search ( self [ ... ] , in: startIndex..< endIndex)
54
+ switch ( self , other) {
55
+ case ( let str as String , let other as String ) :
56
+ return str [ ... ] . _firstRangeSubstring ( of: other [ ... ] ) as! Range < Index > ?
57
+ case ( let str as Substring , let other as String ) :
58
+ return str. _firstRangeSubstring ( of: other [ ... ] ) as! Range < Index > ?
59
+ case ( let str as String , let other as Substring ) :
60
+ return str [ ... ] . _firstRangeSubstring ( of: other) as! Range < Index > ?
61
+ case ( let str as Substring , let other as Substring ) :
62
+ return str. _firstRangeSubstring ( of: other) as! Range < Index > ?
63
+
64
+ default :
65
+ return _firstRangeGeneric ( of: other)
66
+ }
39
67
}
40
68
}
41
69
@@ -47,11 +75,23 @@ extension BidirectionalCollection where Element: Comparable {
47
75
/// - Returns: A range in the collection of the first occurrence of `sequence`.
48
76
/// Returns `nil` if `sequence` is not found.
49
77
@available ( SwiftStdlib 5 . 7 , * )
78
+ @inline ( __always)
50
79
public func firstRange< C: Collection > (
51
80
of other: C
52
81
) -> Range < Index > ? where C. Element == Element {
53
- let searcher = ZSearcher < SubSequence > ( pattern: Array ( other) , by: == )
54
- return searcher. search ( self [ ... ] , in: startIndex..< endIndex)
82
+ switch ( self , other) {
83
+ case ( let str as String , let other as String ) :
84
+ return str [ ... ] . _firstRangeSubstring ( of: other [ ... ] ) as! Range < Index > ?
85
+ case ( let str as Substring , let other as String ) :
86
+ return str. _firstRangeSubstring ( of: other [ ... ] ) as! Range < Index > ?
87
+ case ( let str as String , let other as Substring ) :
88
+ return str [ ... ] . _firstRangeSubstring ( of: other) as! Range < Index > ?
89
+ case ( let str as Substring , let other as Substring ) :
90
+ return str. _firstRangeSubstring ( of: other) as! Range < Index > ?
91
+
92
+ default :
93
+ return _firstRangeGeneric ( of: other)
94
+ }
55
95
}
56
96
}
57
97
0 commit comments