1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#if FOUNDATION_FRAMEWORK
@_spi(Unstable) internal import CollectionsInternal
#elseif canImport(_RopeModule)
internal import _RopeModule
#elseif canImport(_FoundationCollections)
internal import _FoundationCollections
#endif
@available(FoundationPreview 6.2, *)
extension AttributedString {
/// A view of an attributed string’s contents as a collection of UTF-16 code units.
public struct UTF16View: Sendable {
internal var _guts: Guts
internal var _range: Range<BigString.Index>
internal var _identity: Int = 0
internal init(_ guts: AttributedString.Guts) {
self.init(guts, in: guts.stringBounds)
}
internal init(_ guts: Guts, in range: Range<BigString.Index>) {
_guts = guts
_range = range
}
}
/// A view of the attributed string’s contents as a collection of UTF-16 code units.
public var utf16: UTF16View {
UTF16View(_guts)
}
}
@available(FoundationPreview 6.2, *)
extension AttributedSubstring {
/// A view of the attributed substring's contents as a collection of UTF-16 code units.
public var utf16: AttributedString.UTF16View {
AttributedString.UTF16View(_guts, in: _range)
}
}
@available(FoundationPreview 6.2, *)
extension AttributedString.UTF16View {
var _utf16: BigSubstring.UTF16View {
BigSubstring.UTF16View(_unchecked: _guts.string, in: _range)
}
}
@available(FoundationPreview 6.2, *)
extension AttributedString.UTF16View: BidirectionalCollection {
public typealias Element = UTF16.CodeUnit
public typealias Index = AttributedString.Index
public typealias Subsequence = Self
public var startIndex: AttributedString.Index {
.init(_range.lowerBound, version: _guts.version)
}
public var endIndex: AttributedString.Index {
.init(_range.upperBound, version: _guts.version)
}
public var count: Int {
_utf16.count
}
public func index(before i: AttributedString.Index) -> AttributedString.Index {
precondition(i > startIndex && i <= endIndex, "AttributedString index out of bounds")
let j = Index(_guts.string.utf16.index(before: i._value), version: _guts.version)
precondition(j >= startIndex, "Can't advance AttributedString index before start index")
return j
}
public func index(after i: AttributedString.Index) -> AttributedString.Index {
precondition(i >= startIndex && i < endIndex, "AttributedString index out of bounds")
let j = Index(_guts.string.utf16.index(after: i._value), version: _guts.version)
precondition(j <= endIndex, "Can't advance AttributedString index after end index")
return j
}
public func index(_ i: AttributedString.Index, offsetBy distance: Int) -> AttributedString.Index {
precondition(i >= startIndex && i <= endIndex, "AttributedString index out of bounds")
let j = Index(_guts.string.utf16.index(i._value, offsetBy: distance), version: _guts.version)
precondition(j >= startIndex && j <= endIndex, "AttributedString index out of bounds")
return j
}
public func index(
_ i: AttributedString.Index,
offsetBy distance: Int,
limitedBy limit: AttributedString.Index
) -> AttributedString.Index? {
precondition(i >= startIndex && i <= endIndex, "AttributedString index out of bounds")
precondition(limit >= startIndex && limit <= endIndex, "AttributedString index out of bounds")
guard let j = _guts.string.utf16.index(
i._value, offsetBy: distance, limitedBy: limit._value
) else {
return nil
}
precondition(j >= startIndex._value && j <= endIndex._value,
"AttributedString index out of bounds")
return Index(j, version: _guts.version)
}
public func distance(
from start: AttributedString.Index,
to end: AttributedString.Index
) -> Int {
precondition(start >= startIndex && start <= endIndex, "AttributedString index out of bounds")
precondition(end >= startIndex && end <= endIndex, "AttributedString index out of bounds")
return _guts.string.utf16.distance(from: start._value, to: end._value)
}
public subscript(index: AttributedString.Index) -> UTF16.CodeUnit {
precondition(index >= startIndex && index < endIndex, "AttributedString index out of bounds")
return _guts.string.utf16[index._value]
}
public subscript(bounds: Range<AttributedString.Index>) -> Self {
let bounds = bounds._bstringRange
precondition(
bounds.lowerBound >= _range.lowerBound && bounds.lowerBound <= _range.upperBound &&
bounds.upperBound >= _range.lowerBound && bounds.upperBound <= _range.upperBound,
"AttributedString index range out of bounds")
return Self(_guts, in: bounds)
}
}
|