//===----------------------------------------------------------------------===// // // 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 type that provides subscript access to its elements. /// /// In most cases, it's best to ignore this protocol and use the /// `MutableCollection` protocol instead, because it has a more complete /// interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'MutableCollection' instead") public typealias MutableIndexable = MutableCollection /// A collection that supports subscript assignment. /// /// Collections that conform to `MutableCollection` gain the ability to /// change the value of their elements. This example shows how you can /// modify one of the names in an array of students. /// /// var students = ["Ben", "Ivy", "Jordell", "Maxime"] /// if let i = students.firstIndex(of: "Maxime") { /// students[i] = "Max" /// } /// print(students) /// // Prints "["Ben", "Ivy", "Jordell", "Max"]" /// /// In addition to changing the value of an individual element, you can also /// change the values of a slice of elements in a mutable collection. For /// example, you can sort *part* of a mutable collection by calling the /// mutable `sort()` method on a subscripted subsequence. Here's an /// example that sorts the first half of an array of integers: /// /// var numbers = [15, 40, 10, 30, 60, 25, 5, 100] /// numbers[0..<4].sort() /// print(numbers) /// // Prints "[10, 15, 30, 40, 60, 25, 5, 100]" /// /// The `MutableCollection` protocol allows changing the values of a /// collection's elements but not the length of the collection itself. For /// operations that require adding or removing elements, see the /// `RangeReplaceableCollection` protocol instead. /// /// Conforming to the MutableCollection Protocol /// ============================================ /// /// To add conformance to the `MutableCollection` protocol to your own /// custom collection, upgrade your type's subscript to support both read /// and write access. /// /// A value stored into a subscript of a `MutableCollection` instance must /// subsequently be accessible at that same position. That is, for a mutable /// collection instance `a`, index `i`, and value `x`, the two sets of /// assignments in the following code sample must be equivalent: /// /// a[i] = x /// let y = a[i] /// /// // Must be equivalent to: /// a[i] = x /// let y = x public protocol MutableCollection: Collection where SubSequence: MutableCollection { // FIXME(ABI): Associated type inference requires this. associatedtype Element // FIXME(ABI): Associated type inference requires this. associatedtype Index // FIXME(ABI): Associated type inference requires this. associatedtype SubSequence /// Accesses the element at the specified position. /// /// For example, you can replace an element of an array by using its /// subscript. /// /// var streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] /// streets[1] = "Butler" /// print(streets[1]) /// // Prints "Butler" /// /// You can subscript a collection with any valid index other than the /// collection's end index. The end index refers to the position one /// past the last element of a collection, so it doesn't correspond with an /// element. /// /// - Parameter position: The position of the element to access. `position` /// must be a valid index of the collection that is not equal to the /// `endIndex` property. subscript(position: Index) -> Element { get set } /// Accesses a contiguous subrange of the collection's elements. /// /// The accessed slice uses the same indices for the same elements as the /// original collection. Always use the slice's `startIndex` property /// instead of assuming that its indices start at a particular value. /// /// This example demonstrates getting a slice of an array of strings, finding /// the index of one of the strings in the slice, and then using that index /// in the original array. /// /// let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] /// let streetsSlice = streets[2 ..< streets.endIndex] /// print(streetsSlice) /// // Prints "["Channing", "Douglas", "Evarts"]" /// /// let index = streetsSlice.firstIndex(of: "Evarts") // 4 /// streets[index!] = "Eustace" /// print(streets[index!]) /// // Prints "Eustace" /// /// - Parameter bounds: A range of the collection's indices. The bounds of /// the range must be valid indices of the collection. subscript(bounds: Range) -> SubSequence { get set } /// Reorders the elements of the collection such that all the elements /// that match the given predicate are after all the elements that don't /// match. /// /// After partitioning a collection, there is a pivot index `p` where /// no element before `p` satisfies the `belongsInSecondPartition` /// predicate and every element at or after `p` satisfies /// `belongsInSecondPartition`. /// /// In the following example, an array of numbers is partitioned by a /// predicate that matches elements greater than 30. /// /// var numbers = [30, 40, 20, 30, 30, 60, 10] /// let p = numbers.partition(by: { $0 > 30 }) /// // p == 5 /// // numbers == [30, 10, 20, 30, 30, 60, 40] /// /// The `numbers` array is now arranged in two partitions. The first /// partition, `numbers[.. Bool ) rethrows -> Index /// Exchanges the values at the specified indices of the collection. /// /// Both parameters must be valid indices of the collection and not /// equal to `endIndex`. Passing the same index as both `i` and `j` has no /// effect. /// /// - Parameters: /// - i: The index of the first value to swap. /// - j: The index of the second value to swap. mutating func swapAt(_ i: Index, _ j: Index) /// 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( _ body: (inout UnsafeMutableBufferPointer) throws -> R ) rethrows -> R? } // TODO: swift-3-indexing-model - review the following extension MutableCollection { @inlinable public mutating func _withUnsafeMutableBufferPointerIfSupported( _ body: (inout UnsafeMutableBufferPointer) throws -> R ) rethrows -> R? { return nil } /// Accesses a contiguous subrange of the collection's elements. /// /// The accessed slice uses the same indices for the same elements as the /// original collection. Always use the slice's `startIndex` property /// instead of assuming that its indices start at a particular value. /// /// This example demonstrates getting a slice of an array of strings, finding /// the index of one of the strings in the slice, and then using that index /// in the original array. /// /// let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] /// let streetsSlice = streets[2 ..< streets.endIndex] /// print(streetsSlice) /// // Prints "["Channing", "Douglas", "Evarts"]" /// /// let index = streetsSlice.firstIndex(of: "Evarts") // 4 /// streets[index!] = "Eustace" /// print(streets[index!]) /// // Prints "Eustace" /// /// - Parameter bounds: A range of the collection's indices. The bounds of /// the range must be valid indices of the collection. @inlinable public subscript(bounds: Range) -> Slice { get { _failEarlyRangeCheck(bounds, bounds: startIndex..