mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[stdlib] Document String index conversions
Also rename some parameters to make the documentation read well. Fixes rdar://18018911 Swift SVN r24512
This commit is contained in:
@@ -938,21 +938,31 @@ extension String {
|
|||||||
|
|
||||||
// Index conversions
|
// Index conversions
|
||||||
extension String.Index {
|
extension String.Index {
|
||||||
|
/// Construct the position in `characters` that corresponds exactly to
|
||||||
|
/// `unicodeScalarIndex`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `unicodeScalarIndex` is an element of
|
||||||
|
/// `indices(characters.unicodeScalars)`.
|
||||||
public init?(
|
public init?(
|
||||||
_ sourceIndex: String.UnicodeScalarIndex,
|
_ unicodeScalarIndex: String.UnicodeScalarIndex,
|
||||||
within characters: String
|
within characters: String
|
||||||
) {
|
) {
|
||||||
if !sourceIndex._isOnGraphemeClusterBoundary {
|
if !unicodeScalarIndex._isOnGraphemeClusterBoundary {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self.init(_base: sourceIndex)
|
self.init(_base: unicodeScalarIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the position in `characters` that corresponds exactly to
|
||||||
|
/// `utf16Index`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `utf16Index` is an element of
|
||||||
|
/// `indices(characters.utf16)`.
|
||||||
public init?(
|
public init?(
|
||||||
_ sourceIndex: String.UTF16Index,
|
_ utf16Index: String.UTF16Index,
|
||||||
within characters: String
|
within characters: String
|
||||||
) {
|
) {
|
||||||
if let me = sourceIndex.samePositionIn(
|
if let me = utf16Index.samePositionIn(
|
||||||
characters.unicodeScalars
|
characters.unicodeScalars
|
||||||
)?.samePositionIn(characters) {
|
)?.samePositionIn(characters) {
|
||||||
self = me
|
self = me
|
||||||
@@ -962,11 +972,16 @@ extension String.Index {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the position in `characters` that corresponds exactly to
|
||||||
|
/// `utf8Index`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `utf8Index` is an element of
|
||||||
|
/// `indices(characters.utf8)`.
|
||||||
public init?(
|
public init?(
|
||||||
_ sourceIndex: String.UTF8Index,
|
_ utf8Index: String.UTF8Index,
|
||||||
within characters: String
|
within characters: String
|
||||||
) {
|
) {
|
||||||
if let me = sourceIndex.samePositionIn(
|
if let me = utf8Index.samePositionIn(
|
||||||
characters.unicodeScalars
|
characters.unicodeScalars
|
||||||
)?.samePositionIn(characters) {
|
)?.samePositionIn(characters) {
|
||||||
self = me
|
self = me
|
||||||
@@ -975,20 +990,34 @@ extension String.Index {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `utf8` that corresponds exactly
|
||||||
|
/// to `self`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(String(utf8))`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UTF8View
|
utf8: String.UTF8View
|
||||||
) -> String.UTF8View.Index {
|
) -> String.UTF8View.Index {
|
||||||
return String.UTF8View.Index(self, within: otherView)
|
return String.UTF8View.Index(self, within: utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `utf16` that corresponds exactly
|
||||||
|
/// to `self`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(String(utf16))`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UTF16View
|
utf16: String.UTF16View
|
||||||
) -> String.UTF16View.Index {
|
) -> String.UTF16View.Index {
|
||||||
return String.UTF16View.Index(self, within: otherView)
|
return String.UTF16View.Index(self, within: utf16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `unicodeScalars` that corresponds exactly
|
||||||
|
/// to `self`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(String(unicodeScalars))`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UnicodeScalarView
|
unicodeScalars: String.UnicodeScalarView
|
||||||
) -> String.UnicodeScalarView.Index {
|
) -> String.UnicodeScalarView.Index {
|
||||||
return String.UnicodeScalarView.Index(self, within: otherView)
|
return String.UnicodeScalarView.Index(self, within: unicodeScalars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,43 +232,73 @@ public func ~> (
|
|||||||
|
|
||||||
// Index conversions
|
// Index conversions
|
||||||
extension String.UTF16View.Index {
|
extension String.UTF16View.Index {
|
||||||
|
/// Construct the position in `utf16` that corresponds exactly to
|
||||||
|
/// `utf8Index`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `utf8Index` is an element of
|
||||||
|
/// `indices(String(utf16).utf8)`.
|
||||||
public init?(
|
public init?(
|
||||||
_ sourceIndex: String.UTF8Index, within utf16: String.UTF16View
|
_ utf8Index: String.UTF8Index, within utf16: String.UTF16View
|
||||||
) {
|
) {
|
||||||
let core = utf16._core
|
let core = utf16._core
|
||||||
|
|
||||||
_precondition(
|
_precondition(
|
||||||
sourceIndex._coreIndex >= 0 && sourceIndex._coreIndex <= core.endIndex,
|
utf8Index._coreIndex >= 0 && utf8Index._coreIndex <= core.endIndex,
|
||||||
"Invalid String.UTF8Index for this UTF-16 view")
|
"Invalid String.UTF8Index for this UTF-16 view")
|
||||||
|
|
||||||
// Detect positions that have no corresponding index.
|
// Detect positions that have no corresponding index.
|
||||||
if !sourceIndex._isOnUnicodeScalarBoundary {
|
if !utf8Index._isOnUnicodeScalarBoundary {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self.init(sourceIndex._coreIndex)
|
self.init(utf8Index._coreIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the position in `utf16` that corresponds exactly to
|
||||||
|
/// `unicodeScalarIndex`.
|
||||||
|
///
|
||||||
|
/// Requires: `unicodeScalarIndex` is an element of
|
||||||
|
/// `indices(String(utf16).unicodeScalars)`.
|
||||||
public init(
|
public init(
|
||||||
_ sourceIndex: String.UnicodeScalarIndex, within utf16: String.UTF16View) {
|
_ unicodeScalarIndex: String.UnicodeScalarIndex,
|
||||||
self.init(sourceIndex._position)
|
within utf16: String.UTF16View) {
|
||||||
|
self.init(unicodeScalarIndex._position)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(_ sourceIndex: String.Index, within utf16: String.UTF16View) {
|
/// Construct the position in `utf16` that corresponds exactly to
|
||||||
self.init(sourceIndex._utf16Index)
|
/// `characterIndex`.
|
||||||
|
///
|
||||||
|
/// Requires: `characterIndex` is an element of
|
||||||
|
/// `indices(String(utf16))`.
|
||||||
|
public init(_ characterIndex: String.Index, within utf16: String.UTF16View) {
|
||||||
|
self.init(characterIndex._utf16Index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `utf8` that corresponds exactly
|
||||||
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of
|
||||||
|
/// `indices(String(utf8).utf16)`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UTF8View
|
utf8: String.UTF8View
|
||||||
) -> String.UTF8View.Index? {
|
) -> String.UTF8View.Index? {
|
||||||
return String.UTF8View.Index(self, within: otherView)
|
return String.UTF8View.Index(self, within: utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `unicodeScalars` that corresponds exactly
|
||||||
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of
|
||||||
|
/// `indices(String(unicodeScalars).utf16)`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UnicodeScalarView
|
unicodeScalars: String.UnicodeScalarView
|
||||||
) -> String.UnicodeScalarIndex? {
|
) -> String.UnicodeScalarIndex? {
|
||||||
return String.UnicodeScalarIndex(self, within: otherView)
|
return String.UnicodeScalarIndex(self, within: unicodeScalars)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `characters` that corresponds exactly
|
||||||
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(characters.utf16)`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
characters: String
|
characters: String
|
||||||
) -> String.Index? {
|
) -> String.Index? {
|
||||||
|
|||||||
@@ -309,58 +309,86 @@ func == (lhs: String.UTF8View.Index, rhs: String.UTF8View.Index) -> Bool {
|
|||||||
while true
|
while true
|
||||||
}
|
}
|
||||||
|
|
||||||
extension String.UTF8Index {
|
// Index conversions
|
||||||
|
extension String.UTF8View.Index {
|
||||||
internal init(_ core: _StringCore, _utf16Offset: Int) {
|
internal init(_ core: _StringCore, _utf16Offset: Int) {
|
||||||
let (_, buffer) = core._encodeSomeUTF8(_utf16Offset)
|
let (_, buffer) = core._encodeSomeUTF8(_utf16Offset)
|
||||||
self.init(core, _utf16Offset, buffer)
|
self.init(core, _utf16Offset, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init?(_ sourceIndex: String.UTF16Index, within utf8: String.UTF8View) {
|
/// Construct the position in `utf8` that corresponds exactly to
|
||||||
let sourceView = String.UTF16View(utf8._core)
|
/// `utf16Index`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `utf8Index` is an element of
|
||||||
|
/// `indices(String(utf16).utf8)`.
|
||||||
|
public init?(_ utf16Index: String.UTF16Index, within utf8: String.UTF8View) {
|
||||||
|
let utf16 = String.UTF16View(utf8._core)
|
||||||
|
|
||||||
if sourceIndex != sourceView.startIndex
|
if utf16Index != utf16.startIndex
|
||||||
&& sourceIndex != sourceView.endIndex {
|
&& utf16Index != utf16.endIndex {
|
||||||
_precondition(
|
_precondition(
|
||||||
sourceIndex >= sourceView.startIndex
|
utf16Index >= utf16.startIndex
|
||||||
&& sourceIndex <= sourceView.endIndex,
|
&& utf16Index <= utf16.endIndex,
|
||||||
"Invalid String.UTF16Index for this UTF-8 view")
|
"Invalid String.UTF16Index for this UTF-8 view")
|
||||||
|
|
||||||
// Detect positions that have no corresponding index. Note that
|
// Detect positions that have no corresponding index. Note that
|
||||||
// we have to check before and after, because an unpaired
|
// we have to check before and after, because an unpaired
|
||||||
// surrogate will be decoded as a single replacement character,
|
// surrogate will be decoded as a single replacement character,
|
||||||
// thus making the corresponding position valid in UTF8.
|
// thus making the corresponding position valid in UTF8.
|
||||||
if UTF16.isTrailSurrogate(sourceView[sourceIndex])
|
if UTF16.isTrailSurrogate(utf16[utf16Index])
|
||||||
&& UTF16.isLeadSurrogate(sourceView[sourceIndex.predecessor()]) {
|
&& UTF16.isLeadSurrogate(utf16[utf16Index.predecessor()]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.init(utf8._core, _utf16Offset: sourceIndex._offset)
|
self.init(utf8._core, _utf16Offset: utf16Index._offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the position in `utf8` that corresponds exactly to
|
||||||
|
/// `unicodeScalarIndex`.
|
||||||
|
///
|
||||||
|
/// Requires: `unicodeScalarIndex` is an element of
|
||||||
|
/// `indices(String(utf8).unicodeScalars)`.
|
||||||
public init(
|
public init(
|
||||||
_ sourceIndex: String.UnicodeScalarIndex, within utf8: String.UTF8View) {
|
_ unicodeScalarIndex: String.UnicodeScalarIndex,
|
||||||
self.init(utf8._core, _utf16Offset: sourceIndex._position)
|
within utf8: String.UTF8View
|
||||||
|
) {
|
||||||
|
self.init(utf8._core, _utf16Offset: unicodeScalarIndex._position)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(_ sourceIndex: String.Index, within utf8: String.UTF8View) {
|
/// Construct the position in `utf8` that corresponds exactly to
|
||||||
self.init(utf8._core, _utf16Offset: sourceIndex._base._position)
|
/// `characterIndex`.
|
||||||
|
///
|
||||||
|
/// Requires: `characterIndex` is an element of
|
||||||
|
/// `indices(String(utf8))`.
|
||||||
|
public init(_ characterIndex: String.Index, within utf8: String.UTF8View) {
|
||||||
|
self.init(utf8._core, _utf16Offset: characterIndex._base._position)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Index conversions
|
/// Return the position in `utf16` that corresponds exactly
|
||||||
extension String.UTF8View.Index {
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(String(utf16).utf8)`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UTF16View
|
utf16: String.UTF16View
|
||||||
) -> String.UTF16View.Index? {
|
) -> String.UTF16View.Index? {
|
||||||
return String.UTF16View.Index(self, within: otherView)
|
return String.UTF16View.Index(self, within: utf16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `unicodeScalars` that corresponds exactly
|
||||||
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of
|
||||||
|
/// `indices(String(unicodeScalars).utf8)`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UnicodeScalarView
|
unicodeScalars: String.UnicodeScalarView
|
||||||
) -> String.UnicodeScalarIndex? {
|
) -> String.UnicodeScalarIndex? {
|
||||||
return String.UnicodeScalarIndex(self, within: otherView)
|
return String.UnicodeScalarIndex(self, within: unicodeScalars)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `characters` that corresponds exactly
|
||||||
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(characters.utf8)`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
characters: String
|
characters: String
|
||||||
) -> String.Index? {
|
) -> String.Index? {
|
||||||
|
|||||||
@@ -349,65 +349,92 @@ extension String.UnicodeScalarView : RangeReplaceableCollectionType {
|
|||||||
|
|
||||||
// Index conversions
|
// Index conversions
|
||||||
extension String.UnicodeScalarIndex {
|
extension String.UnicodeScalarIndex {
|
||||||
|
/// Construct the position in `unicodeScalars` that corresponds exactly to
|
||||||
|
/// `utf16Index`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `utf16Index` is an element of
|
||||||
|
/// `indices(String(unicodeScalars).utf16)`.
|
||||||
public init?(
|
public init?(
|
||||||
_ sourceIndex: String.UTF16Index,
|
_ utf16Index: String.UTF16Index,
|
||||||
within unicodeScalars: String.UnicodeScalarView
|
within unicodeScalars: String.UnicodeScalarView
|
||||||
) {
|
) {
|
||||||
let sourceView = String.UTF16View(unicodeScalars._core)
|
let utf16 = String.UTF16View(unicodeScalars._core)
|
||||||
|
|
||||||
if sourceIndex != sourceView.startIndex
|
if utf16Index != utf16.startIndex
|
||||||
&& sourceIndex != sourceView.endIndex {
|
&& utf16Index != utf16.endIndex {
|
||||||
_precondition(
|
_precondition(
|
||||||
sourceIndex >= sourceView.startIndex
|
utf16Index >= utf16.startIndex
|
||||||
&& sourceIndex <= sourceView.endIndex,
|
&& utf16Index <= utf16.endIndex,
|
||||||
"Invalid String.UTF16Index for this UnicodeScalar view")
|
"Invalid String.UTF16Index for this UnicodeScalar view")
|
||||||
|
|
||||||
// Detect positions that have no corresponding index. Note that
|
// Detect positions that have no corresponding index. Note that
|
||||||
// we have to check before and after, because an unpaired
|
// we have to check before and after, because an unpaired
|
||||||
// surrogate will be decoded as a single replacement character,
|
// surrogate will be decoded as a single replacement character,
|
||||||
// thus making the corresponding position valid.
|
// thus making the corresponding position valid.
|
||||||
if UTF16.isTrailSurrogate(sourceView[sourceIndex])
|
if UTF16.isTrailSurrogate(utf16[utf16Index])
|
||||||
&& UTF16.isLeadSurrogate(sourceView[sourceIndex.predecessor()]) {
|
&& UTF16.isLeadSurrogate(utf16[utf16Index.predecessor()]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.init(sourceIndex._offset, unicodeScalars._core)
|
self.init(utf16Index._offset, unicodeScalars._core)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the position in `unicodeScalars` that corresponds exactly to
|
||||||
|
/// `utf8Index`. If no such position exists, the result is `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `utf8Index` is an element of
|
||||||
|
/// `indices(String(unicodeScalars).utf8)`.
|
||||||
public init?(
|
public init?(
|
||||||
_ sourceIndex: String.UTF8Index,
|
_ utf8Index: String.UTF8Index,
|
||||||
within unicodeScalars: String.UnicodeScalarView
|
within unicodeScalars: String.UnicodeScalarView
|
||||||
) {
|
) {
|
||||||
let core = unicodeScalars._core
|
let core = unicodeScalars._core
|
||||||
|
|
||||||
_precondition(
|
_precondition(
|
||||||
sourceIndex._coreIndex >= 0 && sourceIndex._coreIndex <= core.endIndex,
|
utf8Index._coreIndex >= 0 && utf8Index._coreIndex <= core.endIndex,
|
||||||
"Invalid String.UTF8Index for this UnicodeScalar view")
|
"Invalid String.UTF8Index for this UnicodeScalar view")
|
||||||
|
|
||||||
// Detect positions that have no corresponding index.
|
// Detect positions that have no corresponding index.
|
||||||
if !sourceIndex._isOnUnicodeScalarBoundary {
|
if !utf8Index._isOnUnicodeScalarBoundary {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self.init(sourceIndex._coreIndex, core)
|
self.init(utf8Index._coreIndex, core)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the position in `unicodeScalars` that corresponds
|
||||||
|
/// exactly to `characterIndex`.
|
||||||
|
///
|
||||||
|
/// Requires: `characterIndex` is an element of
|
||||||
|
/// `indices(String(unicodeScalars))`.
|
||||||
public init(
|
public init(
|
||||||
_ sourceIndex: String.Index,
|
_ characterIndex: String.Index,
|
||||||
within unicodeScalars: String.UnicodeScalarView
|
within unicodeScalars: String.UnicodeScalarView
|
||||||
) {
|
) {
|
||||||
self.init(sourceIndex._base._position, unicodeScalars._core)
|
self.init(characterIndex._base._position, unicodeScalars._core)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func samePositionIn(
|
/// Return the position in `utf8` that corresponds exactly
|
||||||
otherView: String.UTF8View
|
/// to `self`.
|
||||||
) -> String.UTF8View.Index {
|
///
|
||||||
return String.UTF8View.Index(self, within: otherView)
|
/// Requires: `self` is an element of `indices(String(utf8))`.
|
||||||
|
public func samePositionIn(utf8: String.UTF8View) -> String.UTF8View.Index {
|
||||||
|
return String.UTF8View.Index(self, within: utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `utf16` that corresponds exactly
|
||||||
|
/// to `self`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(String(utf16))`.
|
||||||
public func samePositionIn(
|
public func samePositionIn(
|
||||||
otherView: String.UTF16View
|
utf16: String.UTF16View
|
||||||
) -> String.UTF16View.Index {
|
) -> String.UTF16View.Index {
|
||||||
return String.UTF16View.Index(self, within: otherView)
|
return String.UTF16View.Index(self, within: utf16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the position in `characters` that corresponds exactly
|
||||||
|
/// to `self`, or if no such position exists, `nil`.
|
||||||
|
///
|
||||||
|
/// Requires: `self` is an element of `indices(characters.unicodeScalars)`.
|
||||||
public func samePositionIn(characters: String) -> String.Index? {
|
public func samePositionIn(characters: String) -> String.Index? {
|
||||||
return String.Index(self, within: characters)
|
return String.Index(self, within: characters)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user