Skip to content

Commit af0d947

Browse files
committed
[WIP] add withUnsafeTuple implementation
1 parent ab513e2 commit af0d947

File tree

4 files changed

+50
-19
lines changed

4 files changed

+50
-19
lines changed

Sources/OpenGraph/Runtime/TupleType.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ extension UnsafeTuple {
5353
public var indices: Range<Int> { type.indices }
5454

5555
public func address<T>(as _: T.Type = T.self) -> UnsafePointer<T> {
56-
value.assumingMemoryBound(to: T.self)
56+
guard type.type == T.self else {
57+
preconditionFailure()
58+
}
59+
return value.assumingMemoryBound(to: T.self)
5760
}
5861

5962
public func address<T>(of index: Int, as _: T.Type = T.self) -> UnsafePointer<T> {
@@ -109,7 +112,10 @@ extension UnsafeMutableTuple {
109112
public var indices: Range<Int> { type.indices }
110113

111114
public func address<T>(as _: T.Type = T.self) -> UnsafeMutablePointer<T> {
112-
value.assumingMemoryBound(to: T.self)
115+
guard type.type == T.self else {
116+
preconditionFailure()
117+
}
118+
return value.assumingMemoryBound(to: T.self)
113119
}
114120

115121
public func address<T>(of index: Int, as _: T.Type = T.self) -> UnsafeMutablePointer<T> {
@@ -119,11 +125,11 @@ extension UnsafeMutableTuple {
119125

120126
public subscript<T>() -> T {
121127
unsafeAddress { UnsafePointer(address(as: T.self)) }
122-
unsafeMutableAddress { address(as: T.self) }
128+
nonmutating unsafeMutableAddress { address(as: T.self) }
123129
}
124130

125131
public subscript<T>(_ index: Int) -> T {
126132
unsafeAddress { UnsafePointer(address(of: index, as: T.self)) }
127-
unsafeMutableAddress { address(of: index, as: T.self) }
133+
nonmutating unsafeMutableAddress { address(of: index, as: T.self) }
128134
}
129135
}

Sources/OpenGraph_SPI/Runtime/OGTupleType.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,26 @@ void OGTupleDestoryElement(OGTupleType tuple_type, void *value, size_t index) {
231231
element_type->vw_destroy(reinterpret_cast<swift::OpaqueValue *>((intptr_t)value + index));
232232
#endif
233233
}
234+
235+
void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (* function)(const OGUnsafeMutableTuple *mutableTuple, const void * context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void *context) {
236+
#ifdef OPENGRAPH_SWIFT_TOOLCHAIN_SUPPORTED
237+
auto metadata = reinterpret_cast<OG::swift::metadata const*>(tuple_type);
238+
auto buffer_size = metadata->vw_stride() * count;
239+
void *value;
240+
if (buffer_size <= 0x1000) {
241+
char buffer[buffer_size];
242+
bzero(buffer, buffer_size);
243+
value = buffer;
244+
} else {
245+
value = malloc_type_malloc(buffer_size, 0x100004077774924);
246+
if (value == nullptr) {
247+
OG::precondition_failure("memory allocation failure");
248+
}
249+
}
250+
OGUnsafeMutableTuple tuple = {tuple_type, value};
251+
function(&tuple, context);
252+
if (buffer_size > 0x1000) {
253+
free(value);
254+
}
255+
#endif
256+
}

Sources/OpenGraph_SPI/Runtime/OGTupleType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ void OGTupleDestoryElement(OGTupleType tuple_type, void *buffer, size_t index) O
8080

8181
OG_EXPORT
8282
OG_REFINED_FOR_SWIFT
83-
void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (*_Nullable function)(const void * _Nullable context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void * _Nullable context);
83+
void OGTupleWithBuffer(OGTupleType tuple_type, size_t count, const void (* function)(const OGUnsafeMutableTuple *mutableTuple, const void * context OG_SWIFT_CONTEXT) OG_SWIFT_CC(swift), const void *context);
8484

8585
OG_EXTERN_C_END
8686

Tests/OpenGraphCompatibilityTests/Runtime/TupleTypeTests.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,24 +99,29 @@ struct TupleTypeTests {
9999
}
100100
}
101101

102-
@Suite(.enabled(if: swiftToolchainSupported))
103-
struct UnsafeTupleTests {
104-
}
105-
106102
@Suite(.enabled(if: swiftToolchainSupported))
107103
struct UnsafeMutableTupleTests {
108104
class T1 {
109105
var a = 0
110-
var b: Double = 0
111106
}
112107

113108
struct T2 {
114-
var a: Int = 0
115-
var b: Double = 0
109+
var a = 0
116110
}
117111

118-
enum T3 {
119-
case a, b
112+
@Test
113+
func buffer() {
114+
withUnsafeTuple(of: TupleType([T1.self, T2.self]), count: 1) { mutableTuple in
115+
let t1 = T1()
116+
t1.a = 1
117+
let t2 = T2(a: 2)
118+
mutableTuple.initialize(at: 0, to: t1)
119+
mutableTuple.initialize(at: 1, to: t2)
120+
121+
let tuple = UnsafeTuple(type: mutableTuple.type, value: mutableTuple.value)
122+
#expect((tuple[0] as T1).a == 1)
123+
#expect((tuple[1] as T2).a == 2)
124+
}
120125
}
121126

122127
@Test
@@ -131,12 +136,9 @@ struct UnsafeMutableTupleTests {
131136
let t2 = T2(a: 2)
132137
mutableTuple.initialize(at: 0, to: t1)
133138
mutableTuple.initialize(at: 1, to: t2)
134-
135-
let retrievedT1: T1 = mutableTuple[0]
136-
let retrievedT2: T2 = mutableTuple[1]
137139

138-
#expect(retrievedT1.a == 1)
139-
#expect(retrievedT2.a == 2)
140+
#expect((mutableTuple[0] as T1).a == 1)
141+
#expect((mutableTuple[1] as T2).a == 2)
140142

141143
mutableTuple.deinitialize()
142144
}

0 commit comments

Comments
 (0)