[swift-evolution] Draft: Add @noescape and rethrows to ManagedBuffer API
Dave Abrahams
dabrahams at apple.com
Sun Feb 7 09:18:46 CST 2016
on Sat Feb 06 2016, Károly Lőrentey <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.
On first look this seems to be a great idea. Have you checked for
performance impact?
> 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.
--
-Dave
More information about the swift-evolution
mailing list