@@ -42,12 +42,6 @@ func _toNSArray<T, U : AnyObject>(_ a: [T], f: (T) -> U) -> NSArray {
42
42
return result
43
43
}
44
44
45
- func _toNSRange( _ r: Range < String . Index > ) -> NSRange {
46
- return NSRange (
47
- location: r. lowerBound. encodedOffset,
48
- length: r. upperBound. encodedOffset - r. lowerBound. encodedOffset)
49
- }
50
-
51
45
#if !DEPLOYMENT_RUNTIME_SWIFT
52
46
// We only need this for UnsafeMutablePointer, but there's not currently a way
53
47
// to write that constraint.
@@ -439,10 +433,26 @@ extension StringProtocol where Index == String.Index {
439
433
return self . _ephemeralString. _bridgeToObjectiveC ( )
440
434
}
441
435
436
+ // self can be a Substring so we need to subtract/add this offset when
437
+ // passing _ns to the Foundation APIs. Will be 0 if self is String.
438
+ @_inlineable
439
+ @_versioned
440
+ internal var _substringOffset : Int {
441
+ return self . startIndex. encodedOffset
442
+ }
443
+
442
444
/// Return an `Index` corresponding to the given offset in our UTF-16
443
445
/// representation.
444
446
func _index( _ utf16Index: Int ) -> Index {
445
- return Index ( encodedOffset: utf16Index)
447
+ return Index ( encodedOffset: utf16Index + _substringOffset)
448
+ }
449
+
450
+ @_inlineable
451
+ @_versioned
452
+ internal func _toRelativeNSRange( _ r: Range < String . Index > ) -> NSRange {
453
+ return NSRange (
454
+ location: r. lowerBound. encodedOffset - _substringOffset,
455
+ length: r. upperBound. encodedOffset - r. lowerBound. encodedOffset)
446
456
}
447
457
448
458
/// Return a `Range<Index>` corresponding to the given `NSRange` of
@@ -603,7 +613,7 @@ extension StringProtocol where Index == String.Index {
603
613
return locale != nil ? _ns. compare (
604
614
aString,
605
615
options: mask,
606
- range: _toNSRange (
616
+ range: _toRelativeNSRange (
607
617
range ?? startIndex..< endIndex
608
618
) ,
609
619
locale: locale? . _bridgeToObjectiveC ( )
@@ -612,7 +622,7 @@ extension StringProtocol where Index == String.Index {
612
622
: range != nil ? _ns. compare (
613
623
aString,
614
624
options: mask,
615
- range: _toNSRange ( range!)
625
+ range: _toRelativeNSRange ( range!)
616
626
)
617
627
618
628
: !mask. isEmpty ? _ns. compare ( aString, options: mask)
@@ -1050,7 +1060,7 @@ extension StringProtocol where Index == String.Index {
1050
1060
T : StringProtocol , R : RangeExpression
1051
1061
> ( in range: R , with replacement: T ) -> String where R. Bound == Index {
1052
1062
return _ns. replacingCharacters (
1053
- in: _toNSRange ( range. relative ( to: self ) ) ,
1063
+ in: _toRelativeNSRange ( range. relative ( to: self ) ) ,
1054
1064
with: replacement. _ephemeralString)
1055
1065
}
1056
1066
@@ -1083,7 +1093,7 @@ extension StringProtocol where Index == String.Index {
1083
1093
of: target,
1084
1094
with: replacement,
1085
1095
options: options,
1086
- range: _toNSRange (
1096
+ range: _toRelativeNSRange (
1087
1097
searchRange ?? startIndex..< endIndex
1088
1098
)
1089
1099
)
@@ -1208,7 +1218,7 @@ extension StringProtocol where Index == String.Index {
1208
1218
) where R. Bound == Index {
1209
1219
let range = range. relative ( to: self )
1210
1220
_ns. enumerateLinguisticTags (
1211
- in: _toNSRange ( range) ,
1221
+ in: _toRelativeNSRange ( range) ,
1212
1222
scheme: tagScheme. _ephemeralString,
1213
1223
options: opts,
1214
1224
orthography: orthography != nil ? orthography! : nil
@@ -1273,7 +1283,7 @@ extension StringProtocol where Index == String.Index {
1273
1283
) -> Void
1274
1284
) where R. Bound == Index {
1275
1285
_ns. enumerateSubstrings (
1276
- in: _toNSRange ( range. relative ( to: self ) ) , options: opts) {
1286
+ in: _toRelativeNSRange ( range. relative ( to: self ) ) , options: opts) {
1277
1287
var stop_ = false
1278
1288
1279
1289
body ( $0,
@@ -1346,7 +1356,7 @@ extension StringProtocol where Index == String.Index {
1346
1356
usedLength: usedBufferCount,
1347
1357
encoding: encoding. rawValue,
1348
1358
options: options,
1349
- range: _toNSRange ( range. relative ( to: self ) ) ,
1359
+ range: _toRelativeNSRange ( range. relative ( to: self ) ) ,
1350
1360
remaining: $0)
1351
1361
}
1352
1362
}
@@ -1373,7 +1383,7 @@ extension StringProtocol where Index == String.Index {
1373
1383
contentsEnd in self . _ns. getLineStart (
1374
1384
start, end: end,
1375
1385
contentsEnd: contentsEnd,
1376
- for: _toNSRange ( range. relative ( to: self ) ) )
1386
+ for: _toRelativeNSRange ( range. relative ( to: self ) ) )
1377
1387
}
1378
1388
}
1379
1389
}
@@ -1401,7 +1411,7 @@ extension StringProtocol where Index == String.Index {
1401
1411
contentsEnd in self . _ns. getParagraphStart (
1402
1412
start, end: end,
1403
1413
contentsEnd: contentsEnd,
1404
- for: _toNSRange ( range. relative ( to: self ) ) )
1414
+ for: _toRelativeNSRange ( range. relative ( to: self ) ) )
1405
1415
}
1406
1416
}
1407
1417
}
@@ -1428,7 +1438,8 @@ extension StringProtocol where Index == String.Index {
1428
1438
public func lineRange<
1429
1439
R : RangeExpression
1430
1440
> ( for aRange: R ) -> Range < Index > where R. Bound == Index {
1431
- return _range ( _ns. lineRange ( for: _toNSRange ( aRange. relative ( to: self ) ) ) )
1441
+ return _range ( _ns. lineRange (
1442
+ for: _toRelativeNSRange ( aRange. relative ( to: self ) ) ) )
1432
1443
}
1433
1444
1434
1445
#if !DEPLOYMENT_RUNTIME_SWIFT
@@ -1453,7 +1464,7 @@ extension StringProtocol where Index == String.Index {
1453
1464
var nsTokenRanges : NSArray ?
1454
1465
let result = tokenRanges. _withNilOrAddress ( of: & nsTokenRanges) {
1455
1466
self . _ns. linguisticTags (
1456
- in: _toNSRange ( range. relative ( to: self ) ) ,
1467
+ in: _toRelativeNSRange ( range. relative ( to: self ) ) ,
1457
1468
scheme: tagScheme. _ephemeralString,
1458
1469
options: opts,
1459
1470
orthography: orthography,
@@ -1477,7 +1488,7 @@ extension StringProtocol where Index == String.Index {
1477
1488
R : RangeExpression
1478
1489
> ( for aRange: R ) -> Range < Index > where R. Bound == Index {
1479
1490
return _range (
1480
- _ns. paragraphRange ( for: _toNSRange ( aRange. relative ( to: self ) ) ) )
1491
+ _ns. paragraphRange ( for: _toRelativeNSRange ( aRange. relative ( to: self ) ) ) )
1481
1492
}
1482
1493
#endif
1483
1494
@@ -1504,7 +1515,7 @@ extension StringProtocol where Index == String.Index {
1504
1515
_ns. rangeOfCharacter (
1505
1516
from: aSet,
1506
1517
options: mask,
1507
- range: _toNSRange (
1518
+ range: _toRelativeNSRange (
1508
1519
aRange ?? startIndex..< endIndex
1509
1520
)
1510
1521
)
@@ -1535,7 +1546,7 @@ extension StringProtocol where Index == String.Index {
1535
1546
// and output ranges due (if nothing else) to locale changes
1536
1547
return _range (
1537
1548
_ns. rangeOfComposedCharacterSequences (
1538
- for: _toNSRange ( range. relative ( to: self ) ) ) )
1549
+ for: _toRelativeNSRange ( range. relative ( to: self ) ) ) )
1539
1550
}
1540
1551
1541
1552
// - (NSRange)rangeOfString:(NSString *)aString
@@ -1570,13 +1581,13 @@ extension StringProtocol where Index == String.Index {
1570
1581
locale != nil ? _ns. range (
1571
1582
of: aString,
1572
1583
options: mask,
1573
- range: _toNSRange (
1584
+ range: _toRelativeNSRange (
1574
1585
searchRange ?? startIndex..< endIndex
1575
1586
) ,
1576
1587
locale: locale
1577
1588
)
1578
1589
: searchRange != nil ? _ns. range (
1579
- of: aString, options: mask, range: _toNSRange ( searchRange!)
1590
+ of: aString, options: mask, range: _toRelativeNSRange ( searchRange!)
1580
1591
)
1581
1592
: !mask. isEmpty ? _ns. range ( of: aString, options: mask)
1582
1593
: _ns. range ( of: aString)
@@ -1687,7 +1698,7 @@ extension StringProtocol where Index == String.Index {
1687
1698
@available ( swift, deprecated: 4.0 ,
1688
1699
message: " Please use String slicing subscript. " )
1689
1700
public func substring( with aRange: Range < Index > ) -> String {
1690
- return _ns. substring ( with: _toNSRange ( aRange) )
1701
+ return _ns. substring ( with: _toRelativeNSRange ( aRange) )
1691
1702
}
1692
1703
}
1693
1704
0 commit comments