mirror of
https://github.com/apple/swift-foundation.git
synced 2025-05-19 03:38:49 +08:00
783 lines
24 KiB
Swift
783 lines
24 KiB
Swift
//===----------------------------------------------------------------------===//
|
||
//
|
||
// This source file is part of the Swift.org open source project
|
||
//
|
||
// Copyright (c) 2020-2023 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
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
|
||
extension AttributedString.Runs {
|
||
@preconcurrency
|
||
public struct AttributesSlice1<T : AttributedStringKey> : BidirectionalCollection, Sendable where T.Value : Sendable {
|
||
public typealias Index = AttributedString.Index
|
||
|
||
// FIXME: Why no labels?
|
||
public typealias Element = (T.Value?, Range<AttributedString.Index>)
|
||
|
||
internal typealias Runs = AttributedString.Runs
|
||
|
||
let runs : Runs
|
||
let _names: [String]
|
||
let _constraints: [AttributeRunBoundaries]
|
||
|
||
init(runs: Runs) {
|
||
self.runs = runs
|
||
// FIXME: ☠️ Get these from a proper cache in runs._guts.
|
||
_names = [T.name]
|
||
_constraints = T._constraintsInvolved
|
||
}
|
||
|
||
public struct Iterator: IteratorProtocol, Sendable {
|
||
// Note: This is basically equivalent to `IndexingIterator`.
|
||
|
||
public typealias Element = AttributesSlice1.Element
|
||
|
||
let _slice: AttributesSlice1
|
||
var _index: AttributesSlice1.Index
|
||
|
||
internal init(_ slice: AttributesSlice1) {
|
||
self._slice = slice
|
||
self._index = slice.startIndex
|
||
}
|
||
|
||
public mutating func next() -> Element? {
|
||
if _index == _slice.endIndex {
|
||
return nil
|
||
}
|
||
let run = _slice.runs[_index]
|
||
let next = _slice.index(after: _index)
|
||
let range = _index ..< next
|
||
_index = next
|
||
return (run._attributes[T.self], range)
|
||
}
|
||
}
|
||
|
||
public func makeIterator() -> Iterator {
|
||
Iterator(self)
|
||
}
|
||
|
||
public var startIndex: Index {
|
||
runs._range.lowerBound
|
||
}
|
||
public var endIndex: Index {
|
||
runs._range.upperBound
|
||
}
|
||
|
||
public func index(before i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
before: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public func index(after i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
after: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public subscript(position: AttributedString.Index) -> Element {
|
||
let (start, runIndex) = runs._slicedRunBoundary(
|
||
roundingDown: position,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
let end = self.index(after: position)
|
||
let attributes = runs._guts.runs[runIndex.rangeIndex].attributes
|
||
return (attributes[T.self], start ..< end)
|
||
}
|
||
}
|
||
|
||
public subscript<T : AttributedStringKey>(_ keyPath: KeyPath<AttributeDynamicLookup, T>) -> AttributesSlice1<T> {
|
||
return AttributesSlice1<T>(runs: self)
|
||
}
|
||
|
||
public subscript<T : AttributedStringKey>(_ t: T.Type) -> AttributesSlice1<T> {
|
||
return AttributesSlice1<T>(runs: self)
|
||
}
|
||
}
|
||
|
||
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
|
||
extension AttributedString.Runs {
|
||
@preconcurrency
|
||
public struct AttributesSlice2<
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey
|
||
> : BidirectionalCollection, Sendable
|
||
where
|
||
T.Value : Sendable,
|
||
U.Value : Sendable
|
||
{
|
||
public typealias Index = AttributedString.Index
|
||
|
||
// FIXME: Why no labels?
|
||
public typealias Element = (T.Value?, U.Value?, Range<AttributedString.Index>)
|
||
|
||
internal typealias Runs = AttributedString.Runs
|
||
|
||
let runs : Runs
|
||
let _names: [String]
|
||
let _constraints: [AttributeRunBoundaries]
|
||
|
||
init(runs: Runs) {
|
||
self.runs = runs
|
||
// FIXME: ☠️ Get these from a proper cache in runs._guts.
|
||
_names = [T.name, U.name]
|
||
_constraints = Array(_contents: T.runBoundaries, U.runBoundaries)
|
||
}
|
||
|
||
public struct Iterator: IteratorProtocol, Sendable {
|
||
// Note: This is basically equivalent to `IndexingIterator`.
|
||
|
||
public typealias Element = AttributesSlice2.Element
|
||
|
||
let _slice: AttributesSlice2
|
||
var _index: AttributedString.Index
|
||
|
||
internal init(_ slice: AttributesSlice2) {
|
||
self._slice = slice
|
||
self._index = slice.startIndex
|
||
}
|
||
|
||
public mutating func next() -> Element? {
|
||
if _index == _slice.endIndex {
|
||
return nil
|
||
}
|
||
let run = _slice.runs[_index]
|
||
let next = _slice.index(after: _index)
|
||
let range = _index ..< next
|
||
_index = next
|
||
return (run._attributes[T.self], run._attributes[U.self], range)
|
||
}
|
||
}
|
||
|
||
public func makeIterator() -> Iterator {
|
||
Iterator(self)
|
||
}
|
||
|
||
public var startIndex: Index {
|
||
runs._range.lowerBound
|
||
}
|
||
public var endIndex: Index {
|
||
runs._range.upperBound
|
||
}
|
||
|
||
public func index(before i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
before: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public func index(after i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
after: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public subscript(position: AttributedString.Index) -> Element {
|
||
let (start, runIndex) = runs._slicedRunBoundary(
|
||
roundingDown: position,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
let end = self.index(after: position)
|
||
let attributes = runs._guts.runs[runIndex.rangeIndex].attributes
|
||
return (attributes[T.self], attributes[U.self], start ..< end)
|
||
}
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey
|
||
> (
|
||
_ t: KeyPath<AttributeDynamicLookup, T>,
|
||
_ u: KeyPath<AttributeDynamicLookup, U>
|
||
) -> AttributesSlice2<T, U> {
|
||
return AttributesSlice2<T, U>(runs: self)
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey
|
||
> (
|
||
_ t: T.Type,
|
||
_ u: U.Type
|
||
) -> AttributesSlice2<T, U> {
|
||
return AttributesSlice2<T, U>(runs: self)
|
||
}
|
||
}
|
||
|
||
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
|
||
extension AttributedString.Runs {
|
||
@preconcurrency
|
||
public struct AttributesSlice3<
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey
|
||
> : BidirectionalCollection, Sendable
|
||
where
|
||
T.Value : Sendable,
|
||
U.Value : Sendable,
|
||
V.Value : Sendable
|
||
{
|
||
public typealias Index = AttributedString.Index
|
||
|
||
// FIXME: Why no labels?
|
||
public typealias Element = (T.Value?, U.Value?, V.Value?, Range<AttributedString.Index>)
|
||
|
||
internal typealias Runs = AttributedString.Runs
|
||
|
||
let runs : Runs
|
||
let _names: [String]
|
||
let _constraints: [AttributeRunBoundaries]
|
||
|
||
init(runs: Runs) {
|
||
self.runs = runs
|
||
// FIXME: ☠️ Get these from a proper cache in runs._guts.
|
||
_names = [T.name, U.name, V.name]
|
||
_constraints = Array(_contents: T.runBoundaries, U.runBoundaries, V.runBoundaries)
|
||
}
|
||
|
||
public struct Iterator: IteratorProtocol, Sendable {
|
||
// Note: This is basically equivalent to `IndexingIterator`.
|
||
|
||
public typealias Element = AttributesSlice3.Element
|
||
|
||
let _slice: AttributesSlice3
|
||
var _index: AttributedString.Index
|
||
|
||
internal init(_ slice: AttributesSlice3) {
|
||
self._slice = slice
|
||
self._index = slice.startIndex
|
||
}
|
||
|
||
public mutating func next() -> Element? {
|
||
if _index == _slice.endIndex {
|
||
return nil
|
||
}
|
||
let run = _slice.runs[_index]
|
||
let next = _slice.index(after: _index)
|
||
let range = _index ..< next
|
||
_index = next
|
||
return (
|
||
run._attributes[T.self],
|
||
run._attributes[U.self],
|
||
run._attributes[V.self],
|
||
range)
|
||
}
|
||
}
|
||
|
||
public func makeIterator() -> Iterator {
|
||
Iterator(self)
|
||
}
|
||
|
||
public var startIndex: Index {
|
||
runs._range.lowerBound
|
||
}
|
||
public var endIndex: Index {
|
||
runs._range.upperBound
|
||
}
|
||
|
||
public func index(before i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
before: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public func index(after i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
after: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public subscript(position: AttributedString.Index) -> Element {
|
||
let (start, runIndex) = runs._slicedRunBoundary(
|
||
roundingDown: position,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
let end = self.index(after: position)
|
||
let attributes = runs._guts.runs[runIndex.rangeIndex].attributes
|
||
return (attributes[T.self], attributes[U.self], attributes[V.self], start ..< end)
|
||
}
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey
|
||
> (
|
||
_ t: KeyPath<AttributeDynamicLookup, T>,
|
||
_ u: KeyPath<AttributeDynamicLookup, U>,
|
||
_ v: KeyPath<AttributeDynamicLookup, V>
|
||
) -> AttributesSlice3<T, U, V> {
|
||
return AttributesSlice3<T, U, V>(runs: self)
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey
|
||
> (
|
||
_ t: T.Type,
|
||
_ u: U.Type,
|
||
_ v: V.Type
|
||
) -> AttributesSlice3<T, U, V> {
|
||
return AttributesSlice3<T, U, V>(runs: self)
|
||
}
|
||
}
|
||
|
||
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
|
||
extension AttributedString.Runs {
|
||
@preconcurrency
|
||
public struct AttributesSlice4<
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey,
|
||
W : AttributedStringKey
|
||
> : BidirectionalCollection, Sendable
|
||
where
|
||
T.Value : Sendable,
|
||
U.Value : Sendable,
|
||
V.Value : Sendable,
|
||
W.Value : Sendable
|
||
{
|
||
public typealias Index = AttributedString.Index
|
||
|
||
// FIXME: Why no labels?
|
||
public typealias Element = (T.Value?, U.Value?, V.Value?, W.Value?, Range<AttributedString.Index>)
|
||
|
||
internal typealias Runs = AttributedString.Runs
|
||
|
||
let runs : Runs
|
||
let _names: [String]
|
||
let _constraints: [AttributeRunBoundaries]
|
||
|
||
init(runs: Runs) {
|
||
self.runs = runs
|
||
// FIXME: ☠️ Get these from a proper cache in runs._guts.
|
||
_names = [T.name, U.name, V.name, W.name]
|
||
_constraints = Array(
|
||
_contents: T.runBoundaries, U.runBoundaries, V.runBoundaries, W.runBoundaries)
|
||
}
|
||
|
||
public struct Iterator: IteratorProtocol, Sendable {
|
||
// Note: This is basically equivalent to `IndexingIterator`.
|
||
|
||
public typealias Element = AttributesSlice4.Element
|
||
|
||
let _slice: AttributesSlice4
|
||
var _index: AttributedString.Index
|
||
|
||
internal init(_ slice: AttributesSlice4) {
|
||
self._slice = slice
|
||
self._index = slice.startIndex
|
||
}
|
||
|
||
public mutating func next() -> Element? {
|
||
if _index == _slice.endIndex {
|
||
return nil
|
||
}
|
||
let run = _slice.runs[_index]
|
||
let next = _slice.index(after: _index)
|
||
let range = _index ..< next
|
||
_index = next
|
||
return (
|
||
run._attributes[T.self],
|
||
run._attributes[U.self],
|
||
run._attributes[V.self],
|
||
run._attributes[W.self],
|
||
range)
|
||
}
|
||
}
|
||
|
||
public func makeIterator() -> Iterator {
|
||
Iterator(self)
|
||
}
|
||
|
||
public var startIndex: Index {
|
||
runs._range.lowerBound
|
||
}
|
||
public var endIndex: Index {
|
||
runs._range.upperBound
|
||
}
|
||
|
||
public func index(before i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
before: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public func index(after i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
after: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public subscript(position: AttributedString.Index) -> Element {
|
||
let (start, runIndex) = runs._slicedRunBoundary(
|
||
roundingDown: position,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
let end = self.index(after: position)
|
||
let attributes = runs._guts.runs[runIndex.rangeIndex].attributes
|
||
return (
|
||
attributes[T.self],
|
||
attributes[U.self],
|
||
attributes[V.self],
|
||
attributes[W.self],
|
||
start ..< end)
|
||
}
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey,
|
||
W : AttributedStringKey
|
||
> (
|
||
_ t: KeyPath<AttributeDynamicLookup, T>,
|
||
_ u: KeyPath<AttributeDynamicLookup, U>,
|
||
_ v: KeyPath<AttributeDynamicLookup, V>,
|
||
_ w: KeyPath<AttributeDynamicLookup, W>
|
||
) -> AttributesSlice4<T, U, V, W> {
|
||
return AttributesSlice4<T, U, V, W>(runs: self)
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey,
|
||
W : AttributedStringKey
|
||
> (
|
||
_ t: T.Type,
|
||
_ u: U.Type,
|
||
_ v: V.Type,
|
||
_ w: W.Type
|
||
) -> AttributesSlice4<T, U, V, W> {
|
||
return AttributesSlice4<T, U, V, W>(runs: self)
|
||
}
|
||
}
|
||
|
||
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
|
||
extension AttributedString.Runs {
|
||
@preconcurrency
|
||
public struct AttributesSlice5<
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey,
|
||
W : AttributedStringKey,
|
||
X : AttributedStringKey
|
||
> : BidirectionalCollection, Sendable
|
||
where
|
||
T.Value : Sendable,
|
||
U.Value : Sendable,
|
||
V.Value : Sendable,
|
||
W.Value : Sendable,
|
||
X.Value : Sendable
|
||
{
|
||
public typealias Index = AttributedString.Index
|
||
|
||
// FIXME: Why no labels?
|
||
public typealias Element = (T.Value?, U.Value?, V.Value?, W.Value?, X.Value?, Range<AttributedString.Index>)
|
||
|
||
internal typealias Runs = AttributedString.Runs
|
||
|
||
let runs : Runs
|
||
let _names: [String]
|
||
let _constraints: [AttributeRunBoundaries]
|
||
|
||
init(runs: Runs) {
|
||
self.runs = runs
|
||
// FIXME: ☠️ Get these from a proper cache in runs._guts.
|
||
_names = [T.name, U.name, V.name, W.name]
|
||
_constraints = Array(
|
||
_contents: T.runBoundaries,
|
||
U.runBoundaries,
|
||
V.runBoundaries,
|
||
W.runBoundaries,
|
||
X.runBoundaries)
|
||
}
|
||
|
||
public struct Iterator: IteratorProtocol, Sendable {
|
||
public typealias Element = AttributesSlice5.Element
|
||
|
||
let _slice: AttributesSlice5
|
||
var _index: AttributedString.Index
|
||
|
||
internal init(_ slice: AttributesSlice5) {
|
||
self._slice = slice
|
||
self._index = slice.startIndex
|
||
}
|
||
|
||
public mutating func next() -> Element? {
|
||
if _index == _slice.endIndex {
|
||
return nil
|
||
}
|
||
let run = _slice.runs[_index]
|
||
let next = _slice.index(after: _index)
|
||
let range = _index ..< next
|
||
_index = next
|
||
return (
|
||
run._attributes[T.self],
|
||
run._attributes[U.self],
|
||
run._attributes[V.self],
|
||
run._attributes[W.self],
|
||
run._attributes[X.self],
|
||
range)
|
||
}
|
||
}
|
||
|
||
public func makeIterator() -> Iterator {
|
||
Iterator(self)
|
||
}
|
||
|
||
public var startIndex: Index {
|
||
runs._range.lowerBound
|
||
}
|
||
public var endIndex: Index {
|
||
runs._range.upperBound
|
||
}
|
||
|
||
public func index(before i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
before: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public func index(after i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
after: i,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
}
|
||
|
||
public subscript(position: AttributedString.Index) -> Element {
|
||
let (start, runIndex) = runs._slicedRunBoundary(
|
||
roundingDown: position,
|
||
attributeNames: _names,
|
||
constraints: _constraints)
|
||
let end = self.index(after: position)
|
||
let attributes = runs._guts.runs[runIndex.rangeIndex].attributes
|
||
return (
|
||
attributes[T.self],
|
||
attributes[U.self],
|
||
attributes[V.self],
|
||
attributes[W.self],
|
||
attributes[X.self],
|
||
start ..< end)
|
||
}
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey,
|
||
W : AttributedStringKey,
|
||
X : AttributedStringKey
|
||
> (
|
||
_ t: KeyPath<AttributeDynamicLookup, T>,
|
||
_ u: KeyPath<AttributeDynamicLookup, U>,
|
||
_ v: KeyPath<AttributeDynamicLookup, V>,
|
||
_ w: KeyPath<AttributeDynamicLookup, W>,
|
||
_ x: KeyPath<AttributeDynamicLookup, X>
|
||
) -> AttributesSlice5<T, U, V, W, X> {
|
||
return AttributesSlice5<T, U, V, W, X>(runs: self)
|
||
}
|
||
|
||
public subscript <
|
||
T : AttributedStringKey,
|
||
U : AttributedStringKey,
|
||
V : AttributedStringKey,
|
||
W : AttributedStringKey,
|
||
X : AttributedStringKey
|
||
> (
|
||
_ t: T.Type,
|
||
_ u: U.Type,
|
||
_ v: V.Type,
|
||
_ w: W.Type,
|
||
_ x: X.Type
|
||
) -> AttributesSlice5<T, U, V, W, X> {
|
||
return AttributesSlice5<T, U, V, W, X>(runs: self)
|
||
}
|
||
}
|
||
|
||
#if FOUNDATION_FRAMEWORK
|
||
|
||
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
|
||
extension AttributedString.Runs {
|
||
@_spi(AttributedString)
|
||
public struct NSAttributesSlice : BidirectionalCollection, Sendable {
|
||
public typealias Index = AttributedString.Index
|
||
|
||
// FIXME: Why no labels?
|
||
public typealias Element = (AttributeContainer, Range<AttributedString.Index>)
|
||
|
||
internal typealias Runs = AttributedString.Runs
|
||
|
||
let runs : Runs
|
||
let keys : [NSAttributedString.Key]
|
||
|
||
private let _names: [String]
|
||
|
||
internal init(runs: Runs, keys: [NSAttributedString.Key]) {
|
||
self.runs = runs
|
||
self.keys = keys
|
||
self._names = keys.map { $0.rawValue }
|
||
}
|
||
|
||
public struct Iterator: IteratorProtocol, Sendable {
|
||
// Note: This is basically equivalent to `IndexingIterator`.
|
||
|
||
public typealias Element = NSAttributesSlice.Element
|
||
|
||
let _slice: NSAttributesSlice
|
||
var _index: AttributedString.Index
|
||
|
||
internal init(_ slice: NSAttributesSlice) {
|
||
self._slice = slice
|
||
self._index = slice.startIndex
|
||
}
|
||
|
||
public mutating func next() -> Element? {
|
||
if _index == _slice.endIndex {
|
||
return nil
|
||
}
|
||
let run = _slice.runs[_index]
|
||
let next = _slice.index(after: _index)
|
||
let range = _index ..< next
|
||
_index = next
|
||
return (_slice.buildContainer(from: run._attributes), range)
|
||
}
|
||
}
|
||
|
||
public func makeIterator() -> Iterator {
|
||
Iterator(self)
|
||
}
|
||
|
||
public var startIndex: Index {
|
||
runs._range.lowerBound
|
||
}
|
||
public var endIndex: Index {
|
||
runs._range.upperBound
|
||
}
|
||
|
||
public func index(before i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
before: i,
|
||
attributeNames: _names,
|
||
constraints: [])
|
||
}
|
||
|
||
public func index(after i: Index) -> Index {
|
||
runs._slicedRunBoundary(
|
||
after: i,
|
||
attributeNames: _names,
|
||
constraints: [])
|
||
}
|
||
|
||
public subscript(position: AttributedString.Index) -> Element {
|
||
let (start, runIndex) = runs._slicedRunBoundary(
|
||
roundingDown: position,
|
||
attributeNames: _names,
|
||
constraints: [])
|
||
let end = self.index(after: position)
|
||
let attributes = runs._guts.runs[runIndex.rangeIndex].attributes
|
||
return (buildContainer(from: attributes), start ..< end)
|
||
}
|
||
|
||
private func buildContainer(from storage: AttributedString._AttributeStorage) -> AttributeContainer {
|
||
AttributeContainer(storage.filter { _names.contains($0.key) })
|
||
}
|
||
}
|
||
|
||
@_spi(AttributedString)
|
||
public subscript(nsAttributedStringKeys keys: NSAttributedString.Key...) -> NSAttributesSlice {
|
||
return NSAttributesSlice(runs: self, keys: keys)
|
||
}
|
||
}
|
||
|
||
#endif // FOUNDATION_FRAMEWORK
|
||
|
||
extension RangeReplaceableCollection {
|
||
internal init(_contents item1: Element?) {
|
||
self.init()
|
||
if let item1 { self.append(item1) }
|
||
}
|
||
|
||
internal init(_contents item1: Element?, _ item2: Element?) {
|
||
self.init()
|
||
var c = 0
|
||
if item1 != nil { c &+= 1 }
|
||
if item2 != nil { c &+= 1 }
|
||
guard c > 0 else { return }
|
||
self.reserveCapacity(c)
|
||
if let item1 { self.append(item1) }
|
||
if let item2 { self.append(item2) }
|
||
}
|
||
|
||
internal init(_contents item1: Element?, _ item2: Element?, _ item3: Element?) {
|
||
self.init()
|
||
var c = 0
|
||
if item1 != nil { c &+= 1 }
|
||
if item2 != nil { c &+= 1 }
|
||
if item3 != nil { c &+= 1 }
|
||
guard c > 0 else { return }
|
||
self.reserveCapacity(c)
|
||
if let item1 { self.append(item1) }
|
||
if let item2 { self.append(item2) }
|
||
if let item3 { self.append(item3) }
|
||
}
|
||
|
||
internal init(
|
||
_contents item1: Element?, _ item2: Element?, _ item3: Element?, _ item4: Element?
|
||
) {
|
||
self.init()
|
||
var c = 0
|
||
if item1 != nil { c &+= 1 }
|
||
if item2 != nil { c &+= 1 }
|
||
if item3 != nil { c &+= 1 }
|
||
if item4 != nil { c &+= 1 }
|
||
guard c > 0 else { return }
|
||
self.reserveCapacity(c)
|
||
if let item1 { self.append(item1) }
|
||
if let item2 { self.append(item2) }
|
||
if let item3 { self.append(item3) }
|
||
if let item4 { self.append(item4) }
|
||
}
|
||
|
||
internal init(
|
||
_contents item1: Element?,
|
||
_ item2: Element?,
|
||
_ item3: Element?,
|
||
_ item4: Element?,
|
||
_ item5: Element?
|
||
) {
|
||
self.init()
|
||
var c = 0
|
||
if item1 != nil { c &+= 1 }
|
||
if item2 != nil { c &+= 1 }
|
||
if item3 != nil { c &+= 1 }
|
||
if item4 != nil { c &+= 1 }
|
||
if item5 != nil { c &+= 1 }
|
||
guard c > 0 else { return }
|
||
self.reserveCapacity(c)
|
||
if let item1 { self.append(item1) }
|
||
if let item2 { self.append(item2) }
|
||
if let item3 { self.append(item3) }
|
||
if let item4 { self.append(item4) }
|
||
if let item5 { self.append(item5) }
|
||
}
|
||
}
|
||
|