| //===--- UnsafeBufferPointer.swift.gyb ------------------------*- swift -*-===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| /// An iterator for the elements in the buffer referenced by |
| /// `UnsafeBufferPointer` or `UnsafeMutableBufferPointer`. |
| public struct UnsafeBufferPointerIterator<Element> |
| : IteratorProtocol, Sequence { |
| |
| /// 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`. |
| public mutating func next() -> Element? { |
| if _position == _end { return nil } |
| |
| let result = _position!.pointee |
| _position! += 1 |
| return result |
| } |
| |
| internal var _position, _end: UnsafePointer<Element>? |
| } |
| |
| %for Mutable in ('Mutable', ''): |
| /// A non-owning pointer to a buffer of ${Mutable.lower()} elements stored |
| /// contiguously in memory, presenting a collection interface to the |
| /// underlying elements. |
| /// |
| /// The pointer should be aligned to `MemoryLayout<Element>.alignment`. |
| public struct Unsafe${Mutable}BufferPointer<Element> |
| : ${Mutable}Indexable, ${Mutable}Collection, RandomAccessCollection { |
| |
| public typealias Index = Int |
| public typealias IndexDistance = Int |
| public typealias Iterator = |
| IndexingIterator<Unsafe${Mutable}BufferPointer<Element>> |
| |
| /// Always zero, which is the index of the first element in a |
| /// non-empty buffer. |
| public var startIndex: Int { |
| return 0 |
| } |
| |
| /// The "past the end" position---that is, the position one greater than the |
| /// last valid subscript argument. |
| /// |
| /// The `endIndex` property of an `Unsafe${Mutable}BufferPointer` instance is |
| /// always identical to `count`. |
| public var endIndex: Int { |
| return count |
| } |
| |
| public func index(after i: Int) -> Int { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| return i + 1 |
| } |
| |
| public func formIndex(after i: inout Int) { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| i += 1 |
| } |
| |
| public func index(before i: Int) -> Int { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| return i - 1 |
| } |
| |
| public func formIndex(before i: inout Int) { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| i -= 1 |
| } |
| |
| public func index(_ i: Int, offsetBy n: Int) -> Int { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| return i + n |
| } |
| |
| public func index( |
| _ i: Int, offsetBy n: Int, limitedBy limit: Int |
| ) -> Int? { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| let l = limit - i |
| if n > 0 ? l >= 0 && l < n : l <= 0 && n < l { |
| return nil |
| } |
| return i + n |
| } |
| |
| public func distance(from start: Int, to end: Int) -> Int { |
| // NOTE: this is a manual specialization of index movement for a Strideable |
| // index that is required for UnsafeBufferPointer performance. The |
| // optimizer is not capable of creating partial specializations yet. |
| // NOTE: Range checks are not performed here, because it is done later by |
| // the subscript function. |
| return end - start |
| } |
| |
| public func _failEarlyRangeCheck(_ index: Int, bounds: Range<Int>) { |
| // NOTE: This method is a no-op for performance reasons. |
| } |
| |
| public func _failEarlyRangeCheck(_ range: Range<Int>, bounds: Range<Int>) { |
| // NOTE: This method is a no-op for performance reasons. |
| } |
| |
| public typealias Indices = CountableRange<Int> |
| |
| public var indices: Indices { |
| return startIndex..<endIndex |
| } |
| |
| /// Accesses the `i`th element in the buffer. |
| public subscript(i: Int) -> Element { |
| get { |
| _debugPrecondition(i >= 0) |
| _debugPrecondition(i < endIndex) |
| return _position![i] |
| } |
| %if Mutable: |
| nonmutating set { |
| _debugPrecondition(i >= 0) |
| _debugPrecondition(i < endIndex) |
| _position![i] = newValue |
| } |
| %end |
| } |
| |
| public subscript(bounds: Range<Int>) |
| -> ${Mutable}RandomAccessSlice<Unsafe${Mutable}BufferPointer<Element>> |
| { |
| get { |
| _debugPrecondition(bounds.lowerBound >= startIndex) |
| _debugPrecondition(bounds.upperBound <= endIndex) |
| return ${Mutable}RandomAccessSlice( |
| base: self, bounds: bounds) |
| } |
| % if Mutable: |
| set { |
| _debugPrecondition(bounds.lowerBound >= startIndex) |
| _debugPrecondition(bounds.upperBound <= endIndex) |
| // FIXME: swift-3-indexing-model: tests. |
| _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) |
| } |
| % end |
| } |
| |
| /// Creates an Unsafe${Mutable}Pointer over the `count` contiguous |
| /// `Element` instances beginning at `start`. |
| /// |
| /// If `start` is nil, `count` must be 0. However, `count` may be 0 even for |
| /// a nonzero `start`. |
| public init(start: Unsafe${Mutable}Pointer<Element>?, count: Int) { |
| _precondition( |
| count >= 0, "Unsafe${Mutable}BufferPointer with negative count") |
| _precondition( |
| count == 0 || start != nil, |
| "Unsafe${Mutable}BufferPointer has a nil start and nonzero count") |
| _position = start |
| _end = start.map { $0 + count } |
| } |
| |
| /// Returns an iterator over the elements of this sequence. |
| /// |
| /// - Complexity: O(1). |
| public func makeIterator() -> UnsafeBufferPointerIterator<Element> { |
| return UnsafeBufferPointerIterator(_position: _position, _end: _end) |
| } |
| |
| /// A pointer to the first element of the buffer. |
| public var baseAddress: Unsafe${Mutable}Pointer<Element>? { |
| return _position |
| } |
| |
| /// The number of elements in the buffer. |
| public var count: Int { |
| if let pos = _position { |
| return _end! - pos |
| } |
| return 0 |
| } |
| |
| let _position, _end: Unsafe${Mutable}Pointer<Element>? |
| } |
| |
| extension Unsafe${Mutable}BufferPointer : CustomDebugStringConvertible { |
| /// A textual representation of `self`, suitable for debugging. |
| public var debugDescription: String { |
| return "Unsafe${Mutable}BufferPointer" |
| + "(start: \(_position.map(String.init(describing:)) ?? "nil"), count: \(count))" |
| } |
| } |
| %end |
| |
| @available(*, unavailable, renamed: "UnsafeBufferPointerIterator") |
| public struct UnsafeBufferPointerGenerator<Element> {} |
| |
| // ${'Local Variables'}: |
| // eval: (read-only-mode 1) |
| // End: |