-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathTupleType.swift
More file actions
135 lines (105 loc) · 4.15 KB
/
TupleType.swift
File metadata and controls
135 lines (105 loc) · 4.15 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// TupleType.swift
// OpenGraph
//
// Audited for iOS 18.0
// Status: WIP
public import OpenGraph_SPI
// MARK: TupleType
extension TupleType {
public init(_ types: [Any.Type]) {
self.init(count: types.count, elements: types.map(Metadata.init))
}
public init(_ type: Any.Type) {
self.init(rawValue: unsafeBitCast(type, to: UnsafePointer<_Metadata>.self))
}
public var isEmpty: Bool { count == 0 }
public var indices: Range<Int> { 0 ..< count }
public var type: Any.Type {
unsafeBitCast(rawValue, to: Any.Type.self)
}
public func type(at index: Int) -> Any.Type {
elementType(at: index).type
}
public func offset<T>(at index: Int, as type: T.Type) -> Int {
elementOffset(at: index, type: Metadata(type))
}
public func setElement<T>(in tupleValue: UnsafeMutableRawPointer, at index: Int, from srcValue: UnsafePointer<T>, options: CopyOptions) {
__OGTupleSetElement(self, tupleValue, index, srcValue, Metadata(T.self), options)
}
public func getElement<T>(in tupleValue: UnsafeMutableRawPointer, at index: Int, to dstValue: UnsafeMutablePointer<T>, options: CopyOptions) {
__OGTupleGetElement(self, tupleValue, index, dstValue, Metadata(T.self), options)
}
}
@_silgen_name("OGTupleWithBuffer")
public func withUnsafeTuple(of type: TupleType, count: Int, _ body: (UnsafeMutableTuple) -> ())
// MARK: - UnsafeTuple
extension UnsafeTuple {
public var count: Int { type.count }
public var isEmpty: Bool { type.isEmpty }
public var indices: Range<Int> { type.indices }
public func address<T>(as _: T.Type = T.self) -> UnsafePointer<T> {
guard type.type == T.self else {
preconditionFailure()
}
return value.assumingMemoryBound(to: T.self)
}
public func address<T>(of index: Int, as _: T.Type = T.self) -> UnsafePointer<T> {
value.advanced(by: type.elementOffset(at: index, type: Metadata(T.self)))
.assumingMemoryBound(to: T.self)
}
public subscript<T>() -> T {
unsafeAddress { address(as: T.self) }
}
public subscript<T>(_ index: Int) -> T {
unsafeAddress { address(of: index, as: T.self) }
}
}
// MARK: - UnsafeMutableTuple
@_silgen_name("swift_slowAlloc")
private func slowAlloc(_ size: Int, _ alignMask: Int) -> UnsafeMutableRawPointer
@_silgen_name("swift_slowDealloc")
private func slowDealloc(_ ptr: UnsafeMutableRawPointer, _ size: Int, _ alignMask: Int)
extension UnsafeMutableTuple {
public init(with tupleType: TupleType) {
self.init(type: tupleType, value: slowAlloc(tupleType.size, -1))
}
public func initialize<T>(at index: Int, to element: T) {
withUnsafePointer(to: element) { elementPointer in
type.setElement(in: value, at: index, from: elementPointer, options: .initCopy)
}
}
public func deinitialize() {
type.destroy(value)
}
public func deinitialize(at index: Int) {
type.destroy(value, at: index)
}
public func deallocate(initialized: Bool) {
if initialized {
deinitialize()
}
slowDealloc(value, -1, -1)
}
public var count: Int { type.count }
public var isEmpty: Bool { type.isEmpty }
public var indices: Range<Int> { type.indices }
public func address<T>(as _: T.Type = T.self) -> UnsafeMutablePointer<T> {
guard type.type == T.self else {
preconditionFailure()
}
return value.assumingMemoryBound(to: T.self)
}
public func address<T>(of index: Int, as _: T.Type = T.self) -> UnsafeMutablePointer<T> {
value.advanced(by: type.elementOffset(at: index, type: Metadata(T.self)))
.assumingMemoryBound(to: T.self)
}
public subscript<T>() -> T {
unsafeAddress { UnsafePointer(address(as: T.self)) }
nonmutating unsafeMutableAddress { address(as: T.self) }
}
public subscript<T>(_ index: Int) -> T {
unsafeAddress { UnsafePointer(address(of: index, as: T.self)) }
nonmutating unsafeMutableAddress { address(of: index, as: T.self) }
}
}