@@ -30,12 +30,6 @@ func _toNSArray<T, U : AnyObject>(_ a: [T], f: (T) -> U) -> NSArray {
30
30
return result
31
31
}
32
32
33
- func _toNSRange( _ r: Range < String . Index > ) -> NSRange {
34
- return NSRange (
35
- location: r. lowerBound. encodedOffset,
36
- length: r. upperBound. encodedOffset - r. lowerBound. encodedOffset)
37
- }
38
-
39
33
// We only need this for UnsafeMutablePointer, but there's not currently a way
40
34
// to write that constraint.
41
35
extension Optional {
@@ -417,10 +411,26 @@ extension StringProtocol where Index == String.Index {
417
411
return self . _ephemeralString as NSString
418
412
}
419
413
414
+ // self can be a Substring so we need to subtract/add this offset when
415
+ // passing _ns to the Foundation APIs. Will be 0 if self is String.
416
+ @_inlineable
417
+ @_versioned
418
+ internal var _substringOffset : Int {
419
+ return self . startIndex. encodedOffset
420
+ }
421
+
420
422
/// Return an `Index` corresponding to the given offset in our UTF-16
421
423
/// representation.
422
424
func _index( _ utf16Index: Int ) -> Index {
423
- return Index ( encodedOffset: utf16Index)
425
+ return Index ( encodedOffset: utf16Index + _substringOffset)
426
+ }
427
+
428
+ @_inlineable
429
+ @_versioned
430
+ internal func _toRelativeNSRange( _ r: Range < String . Index > ) -> NSRange {
431
+ return NSRange (
432
+ location: r. lowerBound. encodedOffset - _substringOffset,
433
+ length: r. upperBound. encodedOffset - r. lowerBound. encodedOffset)
424
434
}
425
435
426
436
/// Return a `Range<Index>` corresponding to the given `NSRange` of
@@ -581,7 +591,7 @@ extension StringProtocol where Index == String.Index {
581
591
return locale != nil ? _ns. compare (
582
592
aString,
583
593
options: mask,
584
- range: _toNSRange (
594
+ range: _toRelativeNSRange (
585
595
range ?? startIndex..< endIndex
586
596
) ,
587
597
locale: locale
@@ -590,7 +600,7 @@ extension StringProtocol where Index == String.Index {
590
600
: range != nil ? _ns. compare (
591
601
aString,
592
602
options: mask,
593
- range: _toNSRange ( range!)
603
+ range: _toRelativeNSRange ( range!)
594
604
)
595
605
596
606
: !mask. isEmpty ? _ns. compare ( aString, options: mask)
@@ -1008,7 +1018,7 @@ extension StringProtocol where Index == String.Index {
1008
1018
T : StringProtocol , R : RangeExpression
1009
1019
> ( in range: R , with replacement: T ) -> String where R. Bound == Index {
1010
1020
return _ns. replacingCharacters (
1011
- in: _toNSRange ( range. relative ( to: self ) ) ,
1021
+ in: _toRelativeNSRange ( range. relative ( to: self ) ) ,
1012
1022
with: replacement. _ephemeralString)
1013
1023
}
1014
1024
@@ -1041,7 +1051,7 @@ extension StringProtocol where Index == String.Index {
1041
1051
of: target,
1042
1052
with: replacement,
1043
1053
options: options,
1044
- range: _toNSRange (
1054
+ range: _toRelativeNSRange (
1045
1055
searchRange ?? startIndex..< endIndex
1046
1056
)
1047
1057
)
@@ -1163,7 +1173,7 @@ extension StringProtocol where Index == String.Index {
1163
1173
) where R. Bound == Index {
1164
1174
let range = range. relative ( to: self )
1165
1175
_ns. enumerateLinguisticTags (
1166
- in: _toNSRange ( range) ,
1176
+ in: _toRelativeNSRange ( range) ,
1167
1177
scheme: tagScheme. _ephemeralString,
1168
1178
options: opts,
1169
1179
orthography: orthography != nil ? orthography! : nil
@@ -1227,7 +1237,7 @@ extension StringProtocol where Index == String.Index {
1227
1237
) -> Void
1228
1238
) where R. Bound == Index {
1229
1239
_ns. enumerateSubstrings (
1230
- in: _toNSRange ( range. relative ( to: self ) ) , options: opts) {
1240
+ in: _toRelativeNSRange ( range. relative ( to: self ) ) , options: opts) {
1231
1241
var stop_ = false
1232
1242
1233
1243
body ( $0,
@@ -1300,7 +1310,7 @@ extension StringProtocol where Index == String.Index {
1300
1310
usedLength: usedBufferCount,
1301
1311
encoding: encoding. rawValue,
1302
1312
options: options,
1303
- range: _toNSRange ( range. relative ( to: self ) ) ,
1313
+ range: _toRelativeNSRange ( range. relative ( to: self ) ) ,
1304
1314
remaining: $0)
1305
1315
}
1306
1316
}
@@ -1327,7 +1337,7 @@ extension StringProtocol where Index == String.Index {
1327
1337
contentsEnd in self . _ns. getLineStart (
1328
1338
start, end: end,
1329
1339
contentsEnd: contentsEnd,
1330
- for: _toNSRange ( range. relative ( to: self ) ) )
1340
+ for: _toRelativeNSRange ( range. relative ( to: self ) ) )
1331
1341
}
1332
1342
}
1333
1343
}
@@ -1355,7 +1365,7 @@ extension StringProtocol where Index == String.Index {
1355
1365
contentsEnd in self . _ns. getParagraphStart (
1356
1366
start, end: end,
1357
1367
contentsEnd: contentsEnd,
1358
- for: _toNSRange ( range. relative ( to: self ) ) )
1368
+ for: _toRelativeNSRange ( range. relative ( to: self ) ) )
1359
1369
}
1360
1370
}
1361
1371
}
@@ -1382,7 +1392,8 @@ extension StringProtocol where Index == String.Index {
1382
1392
public func lineRange<
1383
1393
R : RangeExpression
1384
1394
> ( for aRange: R ) -> Range < Index > where R. Bound == Index {
1385
- return _range ( _ns. lineRange ( for: _toNSRange ( aRange. relative ( to: self ) ) ) )
1395
+ return _range ( _ns. lineRange (
1396
+ for: _toRelativeNSRange ( aRange. relative ( to: self ) ) ) )
1386
1397
}
1387
1398
1388
1399
// - (NSArray *)
@@ -1406,7 +1417,7 @@ extension StringProtocol where Index == String.Index {
1406
1417
var nsTokenRanges : NSArray ?
1407
1418
let result = tokenRanges. _withNilOrAddress ( of: & nsTokenRanges) {
1408
1419
self . _ns. linguisticTags (
1409
- in: _toNSRange ( range. relative ( to: self ) ) ,
1420
+ in: _toRelativeNSRange ( range. relative ( to: self ) ) ,
1410
1421
scheme: tagScheme. _ephemeralString,
1411
1422
options: opts,
1412
1423
orthography: orthography,
@@ -1430,7 +1441,7 @@ extension StringProtocol where Index == String.Index {
1430
1441
R : RangeExpression
1431
1442
> ( for aRange: R ) -> Range < Index > where R. Bound == Index {
1432
1443
return _range (
1433
- _ns. paragraphRange ( for: _toNSRange ( aRange. relative ( to: self ) ) ) )
1444
+ _ns. paragraphRange ( for: _toRelativeNSRange ( aRange. relative ( to: self ) ) ) )
1434
1445
}
1435
1446
1436
1447
// - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)aSet
@@ -1456,7 +1467,7 @@ extension StringProtocol where Index == String.Index {
1456
1467
_ns. rangeOfCharacter (
1457
1468
from: aSet,
1458
1469
options: mask,
1459
- range: _toNSRange (
1470
+ range: _toRelativeNSRange (
1460
1471
aRange ?? startIndex..< endIndex
1461
1472
)
1462
1473
)
@@ -1487,7 +1498,7 @@ extension StringProtocol where Index == String.Index {
1487
1498
// and output ranges due (if nothing else) to locale changes
1488
1499
return _range (
1489
1500
_ns. rangeOfComposedCharacterSequences (
1490
- for: _toNSRange ( range. relative ( to: self ) ) ) )
1501
+ for: _toRelativeNSRange ( range. relative ( to: self ) ) ) )
1491
1502
}
1492
1503
1493
1504
// - (NSRange)rangeOfString:(NSString *)aString
@@ -1522,13 +1533,13 @@ extension StringProtocol where Index == String.Index {
1522
1533
locale != nil ? _ns. range (
1523
1534
of: aString,
1524
1535
options: mask,
1525
- range: _toNSRange (
1536
+ range: _toRelativeNSRange (
1526
1537
searchRange ?? startIndex..< endIndex
1527
1538
) ,
1528
1539
locale: locale
1529
1540
)
1530
1541
: searchRange != nil ? _ns. range (
1531
- of: aString, options: mask, range: _toNSRange ( searchRange!)
1542
+ of: aString, options: mask, range: _toRelativeNSRange ( searchRange!)
1532
1543
)
1533
1544
: !mask. isEmpty ? _ns. range ( of: aString, options: mask)
1534
1545
: _ns. range ( of: aString)
@@ -1637,7 +1648,7 @@ extension StringProtocol where Index == String.Index {
1637
1648
@available ( swift, deprecated: 4.0 ,
1638
1649
message: " Please use String slicing subscript. " )
1639
1650
public func substring( with aRange: Range < Index > ) -> String {
1640
- return _ns. substring ( with: _toNSRange ( aRange) )
1651
+ return _ns. substring ( with: _toRelativeNSRange ( aRange) )
1641
1652
}
1642
1653
}
1643
1654
0 commit comments