Skip to content

Add TupleType and UnsafeTuple #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 34 additions & 13 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ let openGraphCompatibilityTestTarget = Target.testTarget(
cSettings: sharedCSettings,
swiftSettings: sharedSwiftSettings
)
let openGraphSPICompatibilityTestTarget = Target.testTarget(
name: "OpenGraph_SPICompatibilityTests",
dependencies: [
.product(name: "Numerics", package: "swift-numerics"),
],
exclude: ["README.md"],
cSettings: sharedCSettings,
swiftSettings: sharedSwiftSettings
)

// MARK: - Package

Expand Down Expand Up @@ -178,6 +187,7 @@ let package = Package(
openGraphTestTarget,
openGraphShimsTestTarget,
openGraphCompatibilityTestTarget,
openGraphSPICompatibilityTestTarget,
],
cxxLanguageStandard: .cxx17
)
Expand All @@ -192,6 +202,26 @@ let attributeGraphCondition = envEnable("OPENGRAPH_ATTRIBUTEGRAPH")
#endif
let useLocalDeps = envEnable("OPENGRAPH_USE_LOCAL_DEPS")

extension Target {
func addAGSettings() {
dependencies.append(
.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks")
)
var swiftSettings = swiftSettings ?? []
swiftSettings.append(.define("OPENGRAPH_ATTRIBUTEGRAPH"))
self.swiftSettings = swiftSettings
}

func addCompatibilitySettings() {
dependencies.append(
.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks")
)
var swiftSettings = swiftSettings ?? []
swiftSettings.append(.define("OPENGRAPH_COMPATIBILITY_TEST"))
self.swiftSettings = swiftSettings
}
}

if attributeGraphCondition {
let privateFrameworkRepo: Package.Dependency
if useLocalDeps {
Expand All @@ -200,12 +230,7 @@ if attributeGraphCondition {
privateFrameworkRepo = Package.Dependency.package(url: "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git", branch: "main")
}
package.dependencies.append(privateFrameworkRepo)
var swiftSettings: [SwiftSetting] = (openGraphShimsTarget.swiftSettings ?? [])
swiftSettings.append(.define("OPENGRAPH_ATTRIBUTEGRAPH"))
openGraphShimsTarget.swiftSettings = swiftSettings
openGraphShimsTarget.dependencies.append(
.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks")
)
openGraphShimsTarget.addAGSettings()

let agVersion = Context.environment["DARWIN_PRIVATE_FRAMEWORKS_TARGET_RELEASE"].flatMap { Int($0) } ?? 2024
package.platforms = switch agVersion {
Expand All @@ -219,15 +244,11 @@ if attributeGraphCondition {

let compatibilityTestCondition = envEnable("OPENGRAPH_COMPATIBILITY_TEST")
if compatibilityTestCondition && attributeGraphCondition {
openGraphCompatibilityTestTarget.dependencies.append(
.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks")
)

var swiftSettings: [SwiftSetting] = (openGraphCompatibilityTestTarget.swiftSettings ?? [])
swiftSettings.append(.define("OPENGRAPH_COMPATIBILITY_TEST"))
openGraphCompatibilityTestTarget.swiftSettings = swiftSettings
openGraphCompatibilityTestTarget.addCompatibilitySettings()
openGraphSPICompatibilityTestTarget.addCompatibilitySettings()
} else {
openGraphCompatibilityTestTarget.dependencies.append("OpenGraph")
openGraphSPICompatibilityTestTarget.dependencies.append("OpenGraph")
}

extension [Platform] {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenGraph/Runtime/Metadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension Metadata: Swift.Hashable, Swift.CustomStringConvertible {
@inlinable
@inline(__always)
public init(_ type: Any.Type) {
self.init(rawValue: unsafeBitCast(type, to: UnsafePointer<OGSwiftMetadata>.self))
self.init(rawValue: unsafeBitCast(type, to: UnsafePointer<_Metadata>.self))
}

@inlinable
Expand Down
38 changes: 0 additions & 38 deletions Sources/OpenGraph/Runtime/OGTupleType.swift

This file was deleted.

135 changes: 135 additions & 0 deletions Sources/OpenGraph/Runtime/TupleType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,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) }
}
}
2 changes: 0 additions & 2 deletions Sources/OpenGraphShims/GraphShims.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ public typealias OGGraphContext = AGGraphContext
public typealias OGInputOptions = AGInputOptions
public typealias OGSearchOptions = AGSearchOptions
public typealias OGSubgraph = AGSubgraph
public typealias OGSwiftMetadata = AGSwiftMetadata
public typealias OGTupleType = AGTupleType
public typealias OGTypeApplyOptions = AGTypeApplyOptions
public typealias OGUniqueID = AGUniqueID
public typealias OGValue = AGValue
Expand Down
1 change: 1 addition & 0 deletions Sources/OpenGraph_SPI/OGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <stdint.h>

#define OG_ENUM CF_ENUM
#define OG_CLOSED_ENUM CF_CLOSED_ENUM
#define OG_OPTIONS CF_OPTIONS
#define OG_EXTERN_C_BEGIN CF_EXTERN_C_BEGIN
#define OG_EXTERN_C_END CF_EXTERN_C_END
Expand Down
Loading