| //===----------------------------------------------------------------------===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| %{ |
| def get_slice_doc_comment(Self): |
| return """\ |
| /// A view into a sub-sequence of elements of another collection. |
| /// |
| /// A `%s` instance stores the base collection, the start and end indices of |
| /// the view. It does not copy the elements from the collection into separate |
| /// storage. Thus, creating a slice has `O(1)` complexity. |
| /// |
| /// A `%s` instance inherits the value or reference semantics of the base |
| /// collection. That is, if a `%s` instance is wrapped around a mutable |
| /// collection that has value semantics (for example, `Array`), mutating the |
| /// original collection would not affect the copy stored inside of the slice. |
| /// |
| /// An element of a slice is located under the same index in the slice and in |
| /// the base collection, as long as neither the collection or the slice were |
| /// mutated. Thus, indices of a slice can be used interchangeably with indices |
| /// of the base collection. |
| /// |
| /// - Warning: Long-term storage of `%s` instances is discouraged. |
| /// |
| /// Because a `%s` presents a *view* onto the storage of some larger |
| /// collection even after the original collection goes out of scope, storing |
| /// the slice may prolong the lifetime of elements that are no longer |
| /// accessible, which can manifest as apparent memory and object leakage. To |
| /// prevent this effect, use slices only for transient computation.\ |
| """ % (Self, Self, Self, Self, Self) |
| }% |
| |
| ${get_slice_doc_comment('Slice')} |
| public struct Slice<Base : Indexable> : CollectionType { |
| |
| public typealias Index = Base.Index |
| |
| public let startIndex: Index |
| public let endIndex: Index |
| |
| public subscript(index: Index) -> Base._Element { |
| Index._failEarlyRangeCheck(index, bounds: startIndex..<endIndex) |
| return _base[index] |
| } |
| |
| public subscript(bounds: Range<Index>) -> Slice { |
| Index._failEarlyRangeCheck2( |
| bounds.startIndex, rangeEnd: bounds.endIndex, |
| boundsStart: startIndex, boundsEnd: endIndex) |
| return Slice(base: _base, bounds: bounds) |
| } |
| |
| /// Create a view into collection `base` that allows access within `bounds`. |
| /// |
| /// - Complexity: O(1). |
| public init(base: Base, bounds: Range<Index>) { |
| self._base = base |
| self.startIndex = bounds.startIndex |
| self.endIndex = bounds.endIndex |
| } |
| |
| internal let _base: Base |
| } |
| |
| ${get_slice_doc_comment('MutableSlice')} |
| /// |
| /// - Warning: `MutableSlice` requires the setter of `Base.subscript(_: Index)` |
| /// to not invalidate indices. If you are writing a collection and mutations |
| /// need to invalidate indices, don't use `MutableSlice`, use `Slice` or |
| /// define your own `Base.SubSequence` type that takes that into account. |
| public struct MutableSlice<Base : MutableIndexable> : MutableCollectionType { |
| |
| public typealias Index = Base.Index |
| |
| public var startIndex: Index { |
| return _startIndex |
| } |
| |
| public var endIndex: Index { |
| return _endIndex |
| } |
| |
| public subscript(index: Index) -> Base._Element { |
| get { |
| Index._failEarlyRangeCheck(index, bounds: startIndex..<endIndex) |
| return _base[index] |
| } |
| set { |
| Index._failEarlyRangeCheck(index, bounds: startIndex..<endIndex) |
| _base[index] = newValue |
| // MutableSlice requires that the underlying collection's subscript |
| // setter does not invalidate indices, so our `startIndex` and `endIndex` |
| // continue to be valid. |
| } |
| } |
| |
| public subscript(bounds: Range<Index>) -> MutableSlice { |
| get { |
| Index._failEarlyRangeCheck2( |
| bounds.startIndex, rangeEnd: bounds.endIndex, |
| boundsStart: startIndex, boundsEnd: endIndex) |
| return MutableSlice(base: _base, bounds: bounds) |
| } |
| set { |
| _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) |
| } |
| } |
| |
| public init(base: Base, bounds: Range<Index>) { |
| self._base = base |
| self._startIndex = bounds.startIndex |
| self._endIndex = bounds.endIndex |
| } |
| |
| internal var _base: Base |
| internal var _startIndex: Index |
| internal var _endIndex: Index |
| } |
| |