//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// /// A type that provides subscript access to its elements. /// /// - Important: In most cases, it's best to ignore this protocol and use /// `CollectionType` instead, as it has a more complete interface. public protocol Indexable { // This protocol is almost an implementation detail of the standard // library; it is used to deduce things like the `SubSequence` and // `Iterator` type from a minimal collection, but it is also used in // exposed places like as a constraint on `IndexingIterator`. /// A type that represents a valid position in the collection. /// /// Valid indices consist of the position of every element and a /// "past the end" position that's not valid for use as a subscript. associatedtype Index : ForwardIndex /// The position of the first element in a non-empty collection. /// /// In an empty collection, `startIndex == endIndex`. /// /// - Complexity: O(1) var startIndex: Index { get } /// The collection's "past the end" position. /// /// `endIndex` is not a valid argument to `subscript`, and is always /// reachable from `startIndex` by zero or more applications of /// `successor()`. /// /// - Complexity: O(1) var endIndex: Index { get } // The declaration of _Element and subscript here is a trick used to // break a cyclic conformance/deduction that Swift can't handle. We // need something other than a Collection.Iterator.Element that can // be used as IndexingIterator's Element. Here we arrange for // the Collection itself to have an Element type that's deducible from // its subscript. Ideally we'd like to constrain this Element to be the same // as Collection.Iterator.Element (see below), but we have no way of // expressing it today. associatedtype _Element /// Returns the element at the given `position`. /// /// - Complexity: O(1) subscript(position: Index) -> _Element { get } } /// A type that supports subscript assignment to a mutable collection. public protocol MutableIndexable { associatedtype Index : ForwardIndex var startIndex: Index { get } var endIndex: Index { get } associatedtype _Element subscript(position: Index) -> _Element { get set } } /// The iterator used for collections that don't specify one. public struct IndexingIterator : IteratorProtocol, Sequence { /// Create an *iterator* over the given collection. public /// @testable init(_elements: Elements) { self._elements = _elements self._position = _elements.startIndex } /// Advance to the next element and return it, or `nil` if no next /// element exists. /// /// - Precondition: No preceding call to `self.next()` has returned `nil`. public mutating func next() -> Elements._Element? { if _position == _elements.endIndex { return nil } let element = _elements[_position] _position._successorInPlace() return element } internal let _elements: Elements internal var _position: Elements.Index } /// A multi-pass sequence with addressable positions. /// /// Positions are represented by an associated `Index` type. Whereas /// an arbitrary sequence may be consumed as it is traversed, a /// collection is multi-pass: any element may be revisited merely by /// saving its index. /// /// The sequence view of the elements is identical to the collection /// view. In other words, the following code binds the same series of /// values to `x` as does `for x in self {}`: /// /// for i in startIndex.. // FIXME: Needed here so that the Iterator is properly deduced from // a custom iterator() function. Otherwise we get an // IndexingIterator. func iterator() -> Iterator // FIXME: should be constrained to Collection // ( Implement recursive protocol // constraints) /// A `Sequence` that can represent a contiguous subrange of `self`'s /// elements. /// /// - Note: This associated type appears as a requirement in /// `Sequence`, but is restated here with stricter /// constraints: in a `Collection`, the `SubSequence` should /// also be a `Collection`. associatedtype SubSequence : Indexable, Sequence = Slice /// Returns the element at the given `position`. subscript(position: Index) -> Iterator.Element { get } /// Returns a collection representing a contiguous sub-range of /// `self`'s elements. /// /// - Complexity: O(1) subscript(bounds: Range) -> SubSequence { get } /// Returns `self[startIndex.. SubSequence /// Returns `self[start.. SubSequence /// Returns `prefix(upTo: position.successor())` /// /// - Complexity: O(1) @warn_unused_result func prefix(through position: Index) -> SubSequence /// Returns `true` iff `self` is empty. var isEmpty: Bool { get } /// Returns the number of elements. /// /// - Complexity: O(1) if `Index` conforms to `RandomAccessIndex`; /// O(N) otherwise. var count: Index.Distance { get } // The following requirement enables dispatching for indexOf when // the element type is Equatable. /// Returns `Optional(Optional(index))` if an element was found; /// `nil` otherwise. /// /// - Complexity: O(N). @warn_unused_result func _customIndexOfEquatableElement(element: Iterator.Element) -> Index?? /// Returns the first element of `self`, or `nil` if `self` is empty. var first: Iterator.Element? { get } } /// Supply the default `iterator()` method for `Collection` models /// that accept the default associated `Iterator`, /// `IndexingIterator`. extension Collection where Iterator == IndexingIterator { public func iterator() -> IndexingIterator { return IndexingIterator(_elements: self) } } /// Supply the default "slicing" `subscript` for `Collection` models /// that accept the default associated `SubSequence`, `Slice`. extension Collection where SubSequence == Slice { public subscript(bounds: Range) -> Slice { Index._failEarlyRangeCheck2( rangeStart: bounds.startIndex, rangeEnd: bounds.endIndex, boundsStart: startIndex, boundsEnd: endIndex) return Slice(_base: self, bounds: bounds) } } extension Collection where SubSequence == Self { /// If `!self.isEmpty`, remove the first element and return it, otherwise /// return `nil`. /// /// - Complexity: O(1) @warn_unused_result public mutating func popFirst() -> Iterator.Element? { guard !isEmpty else { return nil } let element = first! self = self[startIndex.successor().. Iterator.Element? { guard !isEmpty else { return nil } let element = last! self = self[startIndex.. Index?? { return nil } } //===----------------------------------------------------------------------===// // Default implementations for Collection //===----------------------------------------------------------------------===// extension Collection { /// Returns an `Array` containing the results of mapping `transform` /// over `self`. /// /// - Complexity: O(N). @warn_unused_result public func map( @noescape transform: (Iterator.Element) throws -> T ) rethrows -> [T] { let count: Int = numericCast(self.count) if count == 0 { return [] } var result = ContiguousArray() result.reserveCapacity(count) var i = self.startIndex for _ in 0..= 0` /// - Complexity: O(`n`) @warn_unused_result public func dropFirst(n: Int) -> SubSequence { _precondition(n >= 0, "Can't drop a negative number of elements from a collection") let start = startIndex.advanced(by: numericCast(n), limit: endIndex) return self[start..= 0` /// - Complexity: O(`self.count`) @warn_unused_result public func dropLast(n: Int) -> SubSequence { _precondition( n >= 0, "Can't drop a negative number of elements from a collection") let amount = Swift.max(0, numericCast(count) - n) let end = startIndex.advanced(by: numericCast(amount), limit: endIndex) return self[startIndex..= 0` /// - Complexity: O(`maxLength`) @warn_unused_result public func prefix(maxLength: Int) -> SubSequence { _precondition( maxLength >= 0, "Can't take a prefix of negative length from a collection") let end = startIndex.advanced(by: numericCast(maxLength), limit: endIndex) return self[startIndex..= 0` /// - Complexity: O(`self.count`) @warn_unused_result public func suffix(maxLength: Int) -> SubSequence { _precondition( maxLength >= 0, "Can't take a suffix of negative length from a collection") let amount = Swift.max(0, numericCast(count) - maxLength) let start = startIndex.advanced(by: numericCast(amount), limit: endIndex) return self[start.. SubSequence { return self[startIndex.. SubSequence { return self[start.. SubSequence { return prefix(upTo: position.successor()) } /// Returns the maximal `SubSequence`s of `self`, in order, that /// don't contain elements satisfying the predicate `isSeparator`. /// /// - Parameter maxSplits: The maximum number of `SubSequence`s to /// return, minus 1. /// If `maxSplits + 1` `SubSequence`s are returned, the last one is /// a suffix of `self` containing *all* the elements of `self` following the /// last split point. /// The default value is `Int.max`. /// /// - Parameter omittingEmptySubsequences: If `false`, an empty `SubSequence` /// is produced in the result for each pair of consecutive elements /// satisfying `isSeparator`. /// The default value is `true`. /// /// - Precondition: `maxSplits >= 0` @warn_unused_result public func split( maxSplits maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true, @noescape isSeparator: (Iterator.Element) throws -> Bool ) rethrows -> [SubSequence] { _precondition(maxSplits >= 0, "Must take zero or more splits") var result: [SubSequence] = [] var subSequenceStart: Index = startIndex func appendSubsequence(end end: Index) -> Bool { if subSequenceStart == end && omittingEmptySubsequences { return false } result.append(self[subSequenceStart..= 0` @warn_unused_result public func split( separator separator: Iterator.Element, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true ) -> [SubSequence] { return split( maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, isSeparator: { $0 == separator }) } } extension Collection where Index : BidirectionalIndex { /// Returns a subsequence containing all but the last `n` elements. /// /// - Precondition: `n >= 0` /// - Complexity: O(`n`) @warn_unused_result public func dropLast(n: Int) -> SubSequence { _precondition( n >= 0, "Can't drop a negative number of elements from a collection") let end = endIndex.advanced(by: numericCast(-n), limit: startIndex) return self[startIndex..= 0` /// - Complexity: O(`maxLength`) @warn_unused_result public func suffix(maxLength: Int) -> SubSequence { _precondition( maxLength >= 0, "Can't take a suffix of negative length from a collection") let start = endIndex.advanced(by: numericCast(-maxLength), limit: startIndex) return self[start.. Iterator.Element { _precondition(!isEmpty, "can't remove items from an empty collection") let element = first! self = self[startIndex.successor()..= 0 && self.count >= n`. public mutating func removeFirst(n: Int) { if n == 0 { return } _precondition(n >= 0, "number of elements to remove should be non-negative") _precondition(count >= numericCast(n), "can't remove more items from a collection than it contains") self = self[startIndex.advanced(by: numericCast(n)).. Iterator.Element { let element = last! self = self[startIndex..= 0 && self.count >= n`. public mutating func removeLast(n: Int) { if n == 0 { return } _precondition(n >= 0, "number of elements to remove should be non-negative") _precondition(count >= numericCast(n), "can't remove more items from a collection than it contains") self = self[startIndex..) -> UnsafeMutablePointer { let s = self._baseAddressIfContiguous if s != nil { let count = self.count ptr.initializeFrom(s, count: count) _fixLifetime(self._owner) return ptr + count } else { var p = ptr for x in self { p.initializePointee(x) p += 1 } return p } } } extension Collection { public func _preprocessingPass(@noescape preprocess: () -> R) -> R? { return preprocess() } } /// A *collection* that supports subscript assignment. /// /// For any instance `a` of a type conforming to /// `MutableCollection`, : /// /// a[i] = x /// let y = a[i] /// /// is equivalent to: /// /// a[i] = x /// let y = x /// public protocol MutableCollection : MutableIndexable, Collection { // FIXME: should be constrained to MutableCollection // ( Implement recursive protocol // constraints) associatedtype SubSequence : Collection /*: MutableCollection*/ = MutableSlice /// Access the element at `position`. /// /// - Precondition: `position` indicates a valid position in `self` and /// `position != endIndex`. /// /// - Complexity: O(1) subscript(position: Index) -> Iterator.Element {get set} /// Returns a collection representing a contiguous sub-range of /// `self`'s elements. /// /// - Complexity: O(1) for the getter, O(`bounds.count`) for the setter. subscript(bounds: Range) -> SubSequence {get set} /// Call `body(p)`, where `p` is a pointer to the collection's /// mutable contiguous storage. If no such storage exists, it is /// first created. If the collection does not support an internal /// representation in a form of mutable contiguous storage, `body` is not /// called and `nil` is returned. /// /// Often, the optimizer can eliminate bounds- and uniqueness-checks /// within an algorithm, but when that fails, invoking the /// same algorithm on `body`\ 's argument lets you trade safety for /// speed. mutating func _withUnsafeMutableBufferPointerIfSupported( @noescape body: (UnsafeMutablePointer, Int) throws -> R ) rethrows -> R? // FIXME: the signature should use UnsafeMutableBufferPointer, but the // compiler can't handle that. // // Restore the signature of // _withUnsafeMutableBufferPointerIfSupported() that mentions // UnsafeMutableBufferPointer } extension MutableCollection { public mutating func _withUnsafeMutableBufferPointerIfSupported( @noescape body: (UnsafeMutablePointer, Int) throws -> R ) rethrows -> R? { return nil } public subscript(bounds: Range) -> MutableSlice { get { Index._failEarlyRangeCheck2( rangeStart: bounds.startIndex, rangeEnd: bounds.endIndex, boundsStart: startIndex, boundsEnd: endIndex) return MutableSlice(_base: self, bounds: bounds) } set { _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) } } } internal func _writeBackMutableSlice< C : MutableCollection, Slice_ : Collection where C._Element == Slice_.Iterator.Element, C.Index == Slice_.Index >(inout self_: C, bounds: Range, slice: Slice_) { C.Index._failEarlyRangeCheck2( rangeStart: bounds.startIndex, rangeEnd: bounds.endIndex, boundsStart: self_.startIndex, boundsEnd: self_.endIndex) // FIXME(performance): can we use // _withUnsafeMutableBufferPointerIfSupported? Would that create inout // aliasing violations if the newValue points to the same buffer? var selfElementIndex = bounds.startIndex let selfElementsEndIndex = bounds.endIndex var newElementIndex = slice.startIndex let newElementsEndIndex = slice.endIndex while selfElementIndex != selfElementsEndIndex && newElementIndex != newElementsEndIndex { self_[selfElementIndex] = slice[newElementIndex] selfElementIndex._successorInPlace() newElementIndex._successorInPlace() } _precondition( selfElementIndex == selfElementsEndIndex, "Cannot replace a slice of a MutableCollection with a slice of a larger size") _precondition( newElementIndex == newElementsEndIndex, "Cannot replace a slice of a MutableCollection with a slice of a smaller size") } @available(*, unavailable, message="Bit enum has been deprecated. Please use Int instead.") public enum Bit {} @available(*, unavailable, renamed="IndexingIterator") public struct IndexingGenerator {} @available(*, unavailable, renamed="Collection") public typealias CollectionType = Collection extension Collection { @available(*, unavailable, renamed="Iterator") public typealias Generator = Iterator @available(*, unavailable, renamed="iterator") public func generate() -> Iterator { fatalError("unavailable function can't be called") } @available(*, unavailable, message="Removed in Swift 3. Please use underestimatedCount peoperty.") public func underestimateCount() -> Int { fatalError("unavailable function can't be called") } @available(*, unavailable, message="Please use split(_:omittingEmptySubsequences:isSeparator:) instead") public func split( maxSplit: Int = Int.max, allowEmptySlices: Bool = false, @noescape isSeparator: (Iterator.Element) throws -> Bool ) rethrows -> [SubSequence] { fatalError("unavailable function can't be called") } } extension Collection where Iterator.Element : Equatable { @available(*, unavailable, message="Please use split(separator:maxSplits:omittingEmptySubsequences:) instead") public func split( separator: Iterator.Element, maxSplit: Int = Int.max, allowEmptySlices: Bool = false ) -> [SubSequence] { fatalError("unavailable function can't be called") } } @available(*, unavailable, renamed="MutableCollection") public typealias MutableCollectionType = MutableCollection @available(*, unavailable, message="PermutationGenerator has been removed in Swift 3") public struct PermutationGenerator {} @available(*, unavailable, message="Please use 'Collection where SubSequence : MutableCollection'") public typealias MutableSliceable = Collection