Follow-up...
After some more digging, and reading, and trial and error, I managed to get the implementation below, which I think is correct. However, now Xcode gives me a vDSP error that I don't understand, since CGPoint is now conforming to the types that vDSP expects its arguments and return values to have. What am I doing incorrectly?
(The code below is in a Playground)
import Foundation
import CoreGraphics
import Accelerate
extension CGPoint: AccelerateMutableBuffer {
public var count: Int { 2 }
public func withUnsafeBufferPointer<R>(
_ body: (UnsafeBufferPointer<CGFloat>) throws -> R
) rethrows -> R {
var varself = self
let ubp = withUnsafeBytes(of: &varself) { urbp in
urbp.bindMemory(to: CGFloat.self)
}
return try body(ubp)
}
public mutating func withUnsafeMutableBufferPointer<R>(
_ body: (inout UnsafeMutableBufferPointer<CGFloat>) throws -> R
) rethrows -> R {
var varself = self
var ubp = withUnsafeMutableBytes(of: &varself) { urbp in
urbp.bindMemory(to: CGFloat.self)
}
return try body(&ubp)
}
}
let p1 = CGPoint(x: 1.5, y: -3.5)
let p2 = CGPoint(x: -0.5, y: 2.5)
var p: CGPoint = .zero
vDSP.add(p1, p2, result: &p) // Error: "No exact matches in call to static method 'add(_:_:result:)'"
p
Post
Replies
Boosts
Views
Activity
Doh! 🤦🏻♂️ I accidentally clicked on that checkmark button and now I can't uncheck it. This question is not yet resolved!
I understand the error message now. The Element type of the type conforming to Accelerate[Mutable]Buffer must be a Double. I can live with that since CGFloat is a Double on a 64-bit platform. Still, vDSP is not returning the correct result. Again, what am I doing incorrectly?
Many thanks.
import Foundation
import CoreGraphics
import Accelerate
extension CGPoint: AccelerateMutableBuffer {
public typealias Element = Double
public var count: Int { 2 }
public func withUnsafeBufferPointer <R> (
_ body: (UnsafeBufferPointer<Element>) throws -> R
) rethrows -> R {
var varself = self
let ubp = withUnsafeBytes(of: &varself) { urbp in
urbp.bindMemory(to: Element.self)
}
return try body(ubp)
}
public mutating func withUnsafeMutableBufferPointer <R> (
_ body: (inout UnsafeMutableBufferPointer<Element>) throws -> R
) rethrows -> R {
var varself = self
var umbp = withUnsafeMutableBytes(of: &varself) { umrbp in
umrbp.bindMemory(to: Element.self)
}
return try body(&umbp)
}
}
let p1 = CGPoint(x: 1.5, y: 3.5)
let p2 = CGPoint(x: 0.5, y: 2.5)
var p: CGPoint = .zero
vDSP.add(p1, p2, result: &p)
p	 //	result is (0.0, 0.0), not the expected (2.0, 6.0)
Edit: I've since figured it out. Here's the correct solution, as far as I know. It compiles without errors, runs without problems, and gives the correct result. So, unless someone sees a problem I'm not seeing, I'm now happy to consider this question resolved.
The problem with the previous implementation is on line 23: by creating a local mutable copy of self and operating on *that*, self itself doesn't get changed.
import Foundation
import CoreGraphics
import Accelerate
extension CGPoint: AccelerateMutableBuffer {
		public typealias Element = Double
		public var count: Int { 2 }
		public func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Double>) throws -> R) rethrows -> R {
				try Swift.withUnsafeBytes(of: self) { urbp in
						try body(urbp.bindMemory(to: Double.self))
				}
		}
		public mutating func withUnsafeMutableBufferPointer <R> (
				_ body: (inout UnsafeMutableBufferPointer<Double>) throws -> R
		) rethrows -> R {
				try Swift.withUnsafeMutableBytes(of: &self) { umrbp in
						var umbp = umrbp.bindMemory(to: Double.self)
						return try body(&umbp)
				}
		}
}
let p1 = CGPoint(x: 1.5, y: 3.5)
let p2 = CGPoint(x: 0.5, y: 2.5)
var p: CGPoint = .zero
vDSP.add(p1, p2, result: &p)
p // (x: 2, y: 6)	✅
Hi. Thank you for your prompt reply.
Unfortunately, it's not possible for Metal shading language to call into Swift functions.
Ah, that's unfortunate.