If keyPath referred to a stored property directly inside the value, this would return a pointer to that property. If keyPath is a computed property, or the property is not stored relative to the pointer (e.g. an object or indirect pointer), it returns nil.
My most immediate use case is for working with MIDI structures, which have an inline byte buffer, but I suspect there will be other uses as well.
If keyPath referred to a stored property directly inside the value, this
would return a pointer to that property. If keyPath is a computed property,
or the property is not stored relative to the pointer (e.g. an object or
indirect pointer), it returns nil.
My most immediate use case is for working with MIDI structures, which have
an inline byte buffer, but I suspect there will be other uses as well.
1. I can't come up with a name as good as `advanced(to:)` that would be attached to the key path. I use `advance(_:)` in the other two reasons below, but I don't think it's nearly as clear about what it's doing to the pointer.
2. Passing the pointer as the parameter would encourage use of `&`, which would be invalid.
(\CGRect.origin.y).advance(&myRect) // Pointer might be to a temporary
(&myRect).advanced(to: \.origin.y) // Rejected during compilation because & is not allowed there
3. Passing the key path as a parameter improves the code's appearance when you specify the key path in the expression.
myRectPtr.advanced(to: \.origin.y)
(\CGRect.origin.y).advance(myRectPtr) // Requires explicit type name and extra parentheses
···
On Jun 6, 2017, at 9:06 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
Why would this be an extension on UnsafePointer and not KeyPath?
IIUC this has nothing to do with "advancing", though. Maybe "applying"
or even "map" would be a better name?
···
on Tue Jun 06 2017, Brent Royal-Gordon <swift-evolution@swift.org> wrote:
On Jun 6, 2017, at 9:06 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
Why would this be an extension on UnsafePointer and not KeyPath?
1. I can't come up with a name as good as `advanced(to:)` that would
be attached to the key path. I use `advance(_:)` in the other two
reasons below, but I don't think it's nearly as clear about what it's
doing to the pointer.
2. Passing the pointer as the parameter would encourage use of `&`, which would be invalid.
(\CGRect.origin.y).advance(&myRect) // Pointer might be to a temporary
(&myRect).advanced(to: \.origin.y) // Rejected during compilation because & is not allowed
there
3. Passing the key path as a parameter improves the code's appearance when you specify the key path
in the expression.
myRectPtr.advanced(to: \.origin.y)
(\CGRect.origin.y).advance(myRectPtr) // Requires explicit type name and extra parentheses
Why would this be an extension on UnsafePointer and not KeyPath?
1. I can't come up with a name as good as `advanced(to:)` that would
be attached to the key path. I use `advance(_:)` in the other two
reasons below, but I don't think it's nearly as clear about what it's
doing to the pointer.
2. Passing the pointer as the parameter would encourage use of `&`, which would be invalid.
(\CGRect.origin.y).advance(&myRect) // Pointer might be to a temporary
(&myRect).advanced(to: \.origin.y) // Rejected during compilation because & is not allowed
there
3. Passing the key path as a parameter improves the code's appearance when you specify the key path
in the expression.
myRectPtr.advanced(to: \.origin.y)
(\CGRect.origin.y).advance(myRectPtr) // Requires explicit type name and extra parentheses
IIUC this has nothing to do with "advancing", though. Maybe "applying"
or even "map" would be a better name?
How about `offset`?
···
On Jun 6, 2017, at 12:56 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:
on Tue Jun 06 2017, Brent Royal-Gordon <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On Jun 6, 2017, at 9:06 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
It's not an offset because the result is a different type of thing than the source
···
Sent from my moss-covered three-handled family gradunza
On Jun 6, 2017, at 1:09 PM, Hooman Mehr <hooman@mac.com> wrote:
On Jun 6, 2017, at 12:56 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:
on Tue Jun 06 2017, Brent Royal-Gordon <swift-evolution@swift.org> wrote:
On Jun 6, 2017, at 9:06 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
Why would this be an extension on UnsafePointer and not KeyPath?
1. I can't come up with a name as good as `advanced(to:)` that would
be attached to the key path. I use `advance(_:)` in the other two
reasons below, but I don't think it's nearly as clear about what it's
doing to the pointer.
2. Passing the pointer as the parameter would encourage use of `&`, which would be invalid.
(\CGRect.origin.y).advance(&myRect) // Pointer might be to a temporary
(&myRect).advanced(to: \.origin.y) // Rejected during compilation because & is not allowed
there
3. Passing the key path as a parameter improves the code's appearance when you specify the key path
in the expression.
myRectPtr.advanced(to: \.origin.y)
(\CGRect.origin.y).advance(myRectPtr) // Requires explicit type name and extra parentheses
IIUC this has nothing to do with "advancing", though. Maybe "applying"
or even "map" would be a better name?
I just ran into a use case for this as well, though I agree with others in this thread that "advanced" may not be the best name. A simple subscript works great
extension UnsafePointer {
subscript<T>(_ keyPath: KeyPath<Pointee, T>) -> UnsafePointer<T> {
let raw = UnsafeRawPointer(self)
// If a key path is not directly-addressable I consider it programmer error
let offset = MemoryLayout<Pointee>.offset(of: keyPath)!
return raw.advanced(by: offset).assumingMemoryBound(to: T.self)
}
}