mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
192 lines
5.8 KiB
Swift
192 lines
5.8 KiB
Swift
//===--- CollectionOfOne.swift - A Collection with one element ------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2025 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// A collection containing a single element.
|
|
///
|
|
/// You can use a `CollectionOfOne` instance when you need to efficiently
|
|
/// represent a single value as a collection. For example, you can add a
|
|
/// single element to an array by using a `CollectionOfOne` instance with the
|
|
/// concatenation operator (`+`):
|
|
///
|
|
/// let a = [1, 2, 3, 4]
|
|
/// let toAdd = 100
|
|
/// let b = a + CollectionOfOne(toAdd)
|
|
/// // b == [1, 2, 3, 4, 100]
|
|
@frozen // trivial-implementation
|
|
@_addressableForDependencies
|
|
public struct CollectionOfOne<Element> {
|
|
@usableFromInline // trivial-implementation
|
|
internal var _element: Element
|
|
|
|
/// Creates an instance containing just the given element.
|
|
///
|
|
/// - Parameter element: The element to store in the collection.
|
|
@inlinable // trivial-implementation
|
|
public init(_ element: Element) {
|
|
self._element = element
|
|
}
|
|
}
|
|
|
|
extension CollectionOfOne {
|
|
/// An iterator that produces one or zero instances of an element.
|
|
///
|
|
/// `IteratorOverOne` is the iterator for the `CollectionOfOne` type.
|
|
@frozen // trivial-implementation
|
|
public struct Iterator {
|
|
@usableFromInline // trivial-implementation
|
|
internal var _elements: Element?
|
|
|
|
/// Construct an instance that generates `_element!`, or an empty
|
|
/// sequence if `_element == nil`.
|
|
@inlinable // trivial-implementation
|
|
public // @testable
|
|
init(_elements: Element?) {
|
|
self._elements = _elements
|
|
}
|
|
}
|
|
}
|
|
|
|
extension CollectionOfOne.Iterator: IteratorProtocol {
|
|
/// Advances to the next element and returns it, or `nil` if no next element
|
|
/// exists.
|
|
///
|
|
/// Once `nil` has been returned, all subsequent calls return `nil`.
|
|
///
|
|
/// - Returns: The next element in the underlying sequence, if a next element
|
|
/// exists; otherwise, `nil`.
|
|
@inlinable // trivial-implementation
|
|
public mutating func next() -> Element? {
|
|
let result = _elements
|
|
_elements = nil
|
|
return result
|
|
}
|
|
}
|
|
|
|
extension CollectionOfOne: RandomAccessCollection, MutableCollection {
|
|
|
|
public typealias Index = Int
|
|
public typealias Indices = Range<Int>
|
|
public typealias SubSequence = Slice<CollectionOfOne<Element>>
|
|
|
|
/// The position of the first element.
|
|
///
|
|
/// In a `CollectionOfOne` instance, `startIndex` is always `0`.
|
|
@inlinable // trivial-implementation
|
|
public var startIndex: Index {
|
|
return 0
|
|
}
|
|
|
|
/// The "past the end" position---that is, the position one greater than the
|
|
/// last valid subscript argument.
|
|
///
|
|
/// In a `CollectionOfOne` instance, `endIndex` is always `1`.
|
|
@inlinable // trivial-implementation
|
|
public var endIndex: Index {
|
|
return 1
|
|
}
|
|
|
|
/// Returns the position immediately after the given index.
|
|
///
|
|
/// - Parameter i: A valid index of the collection. `i` must be `0`.
|
|
/// - Returns: The index value immediately after `i`.
|
|
@inlinable // trivial-implementation
|
|
public func index(after i: Index) -> Index {
|
|
_precondition(i == startIndex)
|
|
return 1
|
|
}
|
|
|
|
/// Returns the position immediately before the given index.
|
|
///
|
|
/// - Parameter i: A valid index of the collection. `i` must be `1`.
|
|
/// - Returns: The index value immediately before `i`.
|
|
@inlinable // trivial-implementation
|
|
public func index(before i: Index) -> Index {
|
|
_precondition(i == endIndex)
|
|
return 0
|
|
}
|
|
|
|
/// Returns an iterator over the elements of this collection.
|
|
///
|
|
/// - Complexity: O(1)
|
|
@inlinable // trivial-implementation
|
|
public __consuming func makeIterator() -> Iterator {
|
|
return Iterator(_elements: _element)
|
|
}
|
|
|
|
/// Accesses the element at the specified position.
|
|
///
|
|
/// - Parameter position: The position of the element to access. The only
|
|
/// valid position in a `CollectionOfOne` instance is `0`.
|
|
@inlinable // trivial-implementation
|
|
public subscript(position: Int) -> Element {
|
|
_read {
|
|
_precondition(position == 0, "Index out of range")
|
|
yield _element
|
|
}
|
|
_modify {
|
|
_precondition(position == 0, "Index out of range")
|
|
yield &_element
|
|
}
|
|
}
|
|
|
|
@inlinable // trivial-implementation
|
|
public subscript(bounds: Range<Int>) -> SubSequence {
|
|
get {
|
|
_failEarlyRangeCheck(bounds, bounds: 0..<1)
|
|
return Slice(base: self, bounds: bounds)
|
|
}
|
|
set {
|
|
_failEarlyRangeCheck(bounds, bounds: 0..<1)
|
|
let n = newValue.count
|
|
_precondition(bounds.count == n, "CollectionOfOne can't be resized")
|
|
if n == 1 { self = newValue.base }
|
|
}
|
|
}
|
|
|
|
/// The number of elements in the collection, which is always one.
|
|
@inlinable // trivial-implementation
|
|
public var count: Int {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
extension CollectionOfOne {
|
|
|
|
@available(SwiftStdlib 6.2, *)
|
|
public var span: Span<Element> {
|
|
@lifetime(borrow self)
|
|
@_alwaysEmitIntoClient
|
|
get {
|
|
fatalError("Span over CollectionOfOne is not supported yet.")
|
|
}
|
|
}
|
|
}
|
|
|
|
@_unavailableInEmbedded
|
|
extension CollectionOfOne: CustomDebugStringConvertible {
|
|
/// A textual representation of the collection, suitable for debugging.
|
|
public var debugDescription: String {
|
|
return "CollectionOfOne(\(String(reflecting: _element)))"
|
|
}
|
|
}
|
|
|
|
#if SWIFT_ENABLE_REFLECTION
|
|
extension CollectionOfOne: CustomReflectable {
|
|
public var customMirror: Mirror {
|
|
return Mirror(self, children: ["element": _element])
|
|
}
|
|
}
|
|
#endif
|
|
|
|
extension CollectionOfOne: Sendable where Element: Sendable { }
|
|
extension CollectionOfOne.Iterator: Sendable where Element: Sendable { }
|