11
11
12
12
// MARK: `CollectionSearcher` algorithms
13
13
14
+ extension Substring {
15
+ func _replacingSubstring(
16
+ _ other: Substring ,
17
+ with replacement: Substring ,
18
+ maxReplacements: Int = . max
19
+ ) -> String {
20
+ precondition ( maxReplacements >= 0 )
21
+
22
+ var result = String ( )
23
+ var index = startIndex
24
+
25
+ // `maxRanges` is a workaround for https://github.com/apple/swift/issues/59522
26
+ var rangeIterator = SubstringSearcher ( text: self , pattern: other)
27
+ var replacementCount = 0
28
+ while let range = rangeIterator. next ( ) {
29
+ result. append ( contentsOf: self [ index..< range. lowerBound] )
30
+ result. append ( contentsOf: replacement)
31
+ index = range. upperBound
32
+
33
+ replacementCount += 1
34
+ if replacementCount == maxReplacements { break }
35
+ }
36
+
37
+ result. append ( contentsOf: self [ index... ] )
38
+ return result
39
+ }
40
+ }
41
+
14
42
extension RangeReplaceableCollection {
15
43
func _replacing< Ranges: Collection , Replacement: Collection > (
16
44
_ ranges: Ranges ,
@@ -35,19 +63,6 @@ extension RangeReplaceableCollection {
35
63
result. append ( contentsOf: self [ index... ] )
36
64
return result
37
65
}
38
-
39
- mutating func _replace<
40
- Ranges: Collection , Replacement: Collection
41
- > (
42
- _ ranges: Ranges ,
43
- with replacement: Replacement ,
44
- maxReplacements: Int = . max
45
- ) where Ranges. Element == Range < Index > , Replacement. Element == Element {
46
- self = _replacing (
47
- ranges,
48
- with: replacement,
49
- maxReplacements: maxReplacements)
50
- }
51
66
}
52
67
53
68
// MARK: Fixed pattern algorithms
@@ -70,10 +85,40 @@ extension RangeReplaceableCollection where Element: Equatable {
70
85
subrange: Range < Index > ,
71
86
maxReplacements: Int = . max
72
87
) -> Self where C. Element == Element , Replacement. Element == Element {
73
- _replacing (
74
- self [ subrange] . _ranges ( of: other) ,
75
- with: replacement,
76
- maxReplacements: maxReplacements)
88
+ switch ( self , other, replacement) {
89
+ case ( let str as String , let other as String , let repl as String ) :
90
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
91
+ maxReplacements: maxReplacements) as! Self
92
+ case ( let str as Substring , let other as Substring , let repl as Substring ) :
93
+ return str. _replacingSubstring ( other, with: repl,
94
+ maxReplacements: maxReplacements) as! Self
95
+
96
+ case ( let str as Substring , let other as String , let repl as String ) :
97
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
98
+ maxReplacements: maxReplacements) as! Self
99
+ case ( let str as String , let other as Substring , let repl as String ) :
100
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
101
+ maxReplacements: maxReplacements) as! Self
102
+ case ( let str as String , let other as String , let repl as Substring ) :
103
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
104
+ maxReplacements: maxReplacements) as! Self
105
+
106
+ case ( let str as String , let other as Substring , let repl as Substring ) :
107
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
108
+ maxReplacements: maxReplacements) as! Self
109
+ case ( let str as Substring , let other as String , let repl as Substring ) :
110
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
111
+ maxReplacements: maxReplacements) as! Self
112
+ case ( let str as Substring , let other as Substring , let repl as String ) :
113
+ return str [ ... ] . _replacingSubstring ( other [ ... ] , with: repl [ ... ] ,
114
+ maxReplacements: maxReplacements) as! Self
115
+
116
+ default :
117
+ return _replacing (
118
+ self [ subrange] . _ranges ( of: other) ,
119
+ with: replacement,
120
+ maxReplacements: maxReplacements)
121
+ }
77
122
}
78
123
79
124
/// Returns a new collection in which all occurrences of a target sequence
0 commit comments