[swift-evolution] Draft: Add @noescape and rethrows to ManagedBuffer API
Janosch Hildebrand
jnosh at jnosh.com
Sun Feb 7 08:53:19 CST 2016
+1
Is there a reason for not marking 'ManagedBuffer.create' and 'ManagedBufferPointer.init' as rethrows and taking throwing closures?
Now that we can have throwing initializers I don't really see a reason for not allowing throwing closures here...
> On 06 Feb 2016, at 21:03, Károly Lőrentey via swift-evolution <swift-evolution at swift.org> wrote:
>
> I’d like to request feedback on the draft proposal below, about a (hopefully) trivial change to the standard library.
>
> I considered adding it to SE-0012 <https://github.com/apple/swift-evolution/blob/master/proposals/0012-add-noescape-to-public-library-api.md>, which is also about @noescape, but that proposal is about modifying C/Obj-C API, so it’s not a good fit <https://github.com/apple/swift-evolution/pull/122>.
>
> Introduction
>
> stdlib’s ManagedBuffer family of APIs has some public initializers and methods taking closures that are missing the @noescape attribute. The same family has a set of withUnsafeMutablePointer* functions that do not have a rethrows declaration, while all similar methods elsewhere in the standard library allow closures to throw.
>
> I propose to add the missing @noescape attributes and rethrows.
>
> Motivation
>
> - ManagedBuffer seems designed for raw performance. Not having @noescape on the only API that allows access to the buffer’s contents defeats some compiler optimizations, such as omitting unneccessary retain/release calls. This can negate the performance advantage of ManagedBuffer over simpler solutions, like using an Array.
> - Accepting throwing closures makes these APIs more versatile, and also improves their consistency with other parts of stdlib.
>
> Detailed Design
>
> The following set of APIs would be affected by this proposal:
>
> public class ManagedProtoBuffer<Value, Element> : NonObjectiveCBase {
> public final func withUnsafeMutablePointerToValue<R>(body: (UnsafeMutablePointer<Value>) -> R) -> R
> public final func withUnsafeMutablePointerToElements<R>(body: (UnsafeMutablePointer<Element>) -> R) -> R
> public final func withUnsafeMutablePointers<R>(body: (_: UnsafeMutablePointer<Value>, _: UnsafeMutablePointer<Element>) -> R) -> R
> }
>
> public class ManagedBuffer<Value, Element> : ManagedProtoBuffer<Value, Element> {
> public final class func create(minimumCapacity: Int, initialValue: (ManagedProtoBuffer<Value,Element>) -> Value) -> ManagedBuffer<Value,Element>
> }
>
> public struct ManagedBufferPointer<Value, Element> : Equatable {
> public init(bufferClass: AnyClass, minimumCapacity: Int, initialValue: (buffer: AnyObject, allocatedCount: (AnyObject) -> Int) -> Value)
> public func withUnsafeMutablePointerToValue<R>(body: (UnsafeMutablePointer<Value>) -> R) -> R
> public func withUnsafeMutablePointerToElements<R>(body: (UnsafeMutablePointer<Element>) -> R) -> R
> public func withUnsafeMutablePointers<R>(body: (_: UnsafeMutablePointer<Value>, _: UnsafeMutablePointer<Element>) -> R) -> R
> }
>
> Here is how they would look after the proposed changes:
>
> public class ManagedProtoBuffer<Value, Element> : NonObjectiveCBase {
> public final func withUnsafeMutablePointerToValue<R>(@noescape body: (UnsafeMutablePointer<Value>) throws -> R) rethrows -> R
> public final func withUnsafeMutablePointerToElements<R>(@noescape body: (UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
> public final func withUnsafeMutablePointers<R>(@noescape body: (_: UnsafeMutablePointer<Value>, _: UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
>
> public class ManagedBuffer<Value, Element> : ManagedProtoBuffer<Value, Element> {
> public final class func create(minimumCapacity: Int, @noescape initialValue: (ManagedProtoBuffer<Value,Element>) -> Value) -> ManagedBuffer<Value,Element>
> }
>
> public struct ManagedBufferPointer<Value, Element> : Equatable {
> public init(bufferClass: AnyClass, minimumCapacity: Int, @noescape initialValue: (buffer: AnyObject, allocatedCount: (AnyObject) -> Int) -> Value)
> public func withUnsafeMutablePointerToValue<R>(@noescape body: (UnsafeMutablePointer<Value>) throws -> R) rethrows -> R
> public func withUnsafeMutablePointerToElements<R>(@noescape body: (UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
> public func withUnsafeMutablePointers<R>(@noescape body: (_: UnsafeMutablePointer<Value>,_: UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
> }
>
> A draft implementation is available at https://github.com/apple/swift/compare/master...lorentey:noescape <https://github.com/apple/swift/compare/master...lorentey:noescape>
>
> Impact on Existing Code
>
> Luckily, all modified API is either marked final, or defined in a struct, so I expect no existing code is going to break due to these changes.
>
> --
> Károly
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
- Janosch
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160207/e4b82309/attachment-0001.html>
More information about the swift-evolution
mailing list