1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2022 - 2024 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
//
//===----------------------------------------------------------------------===//
/// A fixed-size array of just enough size to hold an ancestor path in a
/// `TreeDictionary`.
@usableFromInline
@frozen
internal struct _HashStack<Element> {
#if arch(x86_64) || arch(arm64)
@inlinable
@inline(__always)
internal static var capacity: Int { 13 }
// xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxx
@usableFromInline
internal var _contents: (
Element, Element, Element, Element,
Element, Element, Element, Element,
Element, Element, Element, Element,
Element
)
#else
@inlinable
@inline(__always)
internal static var capacity: Int { 7 }
// xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xx
@usableFromInline
internal var _contents: (
Element, Element, Element, Element,
Element, Element, Element
)
#endif
@usableFromInline
internal var _count: UInt8
@inlinable
internal init(filledWith value: Element) {
assert(Self.capacity == _HashLevel.limit)
#if arch(x86_64) || arch(arm64)
_contents = (
value, value, value, value,
value, value, value, value,
value, value, value, value,
value
)
#else
_contents = (
value, value, value, value,
value, value, value
)
#endif
self._count = 0
}
@inlinable
@inline(__always)
internal var capacity: Int { Self.capacity }
@inlinable
@inline(__always)
internal var count: Int { Int(truncatingIfNeeded: _count) }
@inlinable
@inline(__always)
internal var isEmpty: Bool { _count == 0 }
@inlinable
subscript(level: UInt8) -> Element {
mutating get {
assert(level < _count)
return withUnsafeBytes(of: &_contents) { buffer in
// Homogeneous tuples are layout compatible with their element type
let start = buffer.baseAddress!.assumingMemoryBound(to: Element.self)
return start[Int(truncatingIfNeeded: level)]
}
}
set {
assert(level < capacity)
withUnsafeMutableBytes(of: &_contents) { buffer in
// Homogeneous tuples are layout compatible with their element type
let start = buffer.baseAddress!.assumingMemoryBound(to: Element.self)
start[Int(truncatingIfNeeded: level)] = newValue
}
}
}
@inlinable
mutating func push(_ item: Element) {
assert(_count < capacity)
self[_count] = item
_count &+= 1
}
@inlinable
mutating func pop() -> Element {
assert(_count > 0)
defer { _count &-= 1 }
return self[_count &- 1]
}
@inlinable
mutating func peek() -> Element {
assert(count > 0)
return self[_count &- 1]
}
}
|