mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
186 lines
5.1 KiB
Swift
186 lines
5.1 KiB
Swift
//===--- FixedArray.swift.gyb ---------------------------------*- swift -*-===//
|
|
//
|
|
// 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 helper struct to provide fixed-sized array like functionality
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
%{
|
|
# The sizes to generate code for.
|
|
sizes = [2, 8, 16]
|
|
}%
|
|
|
|
% for N in sizes:
|
|
|
|
@usableFromInline // FIXME(sil-serialize-all)
|
|
@_fixed_layout // FIXME(sil-serialize-all)
|
|
internal struct _FixedArray${N}<T> {
|
|
// ABI TODO: The has assumptions about tuple layout in the ABI, namely that
|
|
// they are laid out contiguously and individually addressable (i.e. strided).
|
|
//
|
|
@usableFromInline // FIXME(sil-serialize-all)
|
|
internal var storage: (
|
|
// A ${N}-wide tuple of type T
|
|
% for i in range(0, N-1):
|
|
T,
|
|
% end
|
|
T
|
|
)
|
|
|
|
@usableFromInline // FIXME(sil-serialize-all)
|
|
var _count: Int8
|
|
}
|
|
|
|
|
|
extension _FixedArray${N} {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal static var capacity: Int {
|
|
@inline(__always) get { return ${N} }
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal var capacity: Int {
|
|
@inline(__always) get { return ${N} }
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal var count: Int {
|
|
@inline(__always) get { return Int(truncatingIfNeeded: _count) }
|
|
@inline(__always) set { _count = Int8(newValue) }
|
|
}
|
|
}
|
|
|
|
extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
|
|
internal typealias Index = Int
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal var startIndex : Index {
|
|
return 0
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal var endIndex : Index {
|
|
return count
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal subscript(i: Index) -> T {
|
|
@inline(__always)
|
|
get {
|
|
let count = self.count // for exclusive access
|
|
_sanityCheck(i >= 0 && i < count)
|
|
var copy = storage
|
|
let res: T = withUnsafeBytes(of: ©) {
|
|
(rawPtr : UnsafeRawBufferPointer) -> T in
|
|
let stride = MemoryLayout<T>.stride
|
|
_sanityCheck(rawPtr.count == ${N}*stride, "layout mismatch?")
|
|
let bufPtr = UnsafeBufferPointer(
|
|
start: rawPtr.baseAddress!.assumingMemoryBound(to: T.self),
|
|
count: count)
|
|
return bufPtr[i]
|
|
}
|
|
return res
|
|
}
|
|
@inline(__always)
|
|
set {
|
|
_sanityCheck(i >= 0 && i < count)
|
|
self.withUnsafeMutableBufferPointer { buffer in
|
|
buffer[i] = newValue
|
|
}
|
|
}
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@inline(__always)
|
|
internal func index(after i: Index) -> Index {
|
|
return i+1
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@inline(__always)
|
|
internal func index(before i: Index) -> Index {
|
|
return i-1
|
|
}
|
|
}
|
|
|
|
extension _FixedArray${N} {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal mutating func append(_ newElement: T) {
|
|
_sanityCheck(count < capacity)
|
|
_count += 1
|
|
self[count-1] = newElement
|
|
}
|
|
}
|
|
|
|
extension _FixedArray${N} where T : ExpressibleByIntegerLiteral {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@inline(__always)
|
|
internal init(count: Int) {
|
|
_sanityCheck(count >= 0 && count <= _FixedArray${N}.capacity)
|
|
self.storage = (
|
|
% for i in range(0, N-1):
|
|
0,
|
|
% end
|
|
0
|
|
)
|
|
self._count = Int8(truncatingIfNeeded: count)
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@inline(__always)
|
|
internal init() {
|
|
self.init(count: 0)
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@inline(__always)
|
|
internal init(allZeros: ()) {
|
|
self.init(count: ${N})
|
|
}
|
|
}
|
|
|
|
extension _FixedArray${N} {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal mutating func withUnsafeMutableBufferPointer<R>(
|
|
_ body: (UnsafeMutableBufferPointer<Element>) throws -> R
|
|
) rethrows -> R {
|
|
let count = self.count // for exclusive access
|
|
return try withUnsafeMutableBytes(of: &storage) { rawBuffer in
|
|
_sanityCheck(rawBuffer.count == ${N}*MemoryLayout<T>.stride,
|
|
"layout mismatch?")
|
|
let buffer = UnsafeMutableBufferPointer<Element>(
|
|
start: rawBuffer.baseAddress._unsafelyUnwrappedUnchecked
|
|
.assumingMemoryBound(to: Element.self),
|
|
count: count)
|
|
return try body(buffer)
|
|
}
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal mutating func withUnsafeBufferPointer<R>(
|
|
_ body: (UnsafeBufferPointer<Element>) throws -> R
|
|
) rethrows -> R {
|
|
let count = self.count // for exclusive access
|
|
return try withUnsafeBytes(of: &storage) { rawBuffer in
|
|
_sanityCheck(rawBuffer.count == ${N}*MemoryLayout<T>.stride,
|
|
"layout mismatch?")
|
|
let buffer = UnsafeBufferPointer<Element>(
|
|
start: rawBuffer.baseAddress._unsafelyUnwrappedUnchecked
|
|
.assumingMemoryBound(to: Element.self),
|
|
count: count)
|
|
return try body(buffer)
|
|
}
|
|
}
|
|
}
|
|
|
|
% end
|