mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
We don't have a way yet to say "this is deprecated for users, but let the stdlib use it without complaining" so we need to do refactoring shenanigans.
233 lines
7.9 KiB
Swift
233 lines
7.9 KiB
Swift
//===--- 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:
|