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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
//===--- CollectionOfOne.swift - A Collection with one element ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
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
}
}
@_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 { }
|