[swift-evolution] Draft: Add @noescape and rethrows to ManagedBuffer API

Jacob Bandes-Storch jtbandes at gmail.com
Sun Feb 7 12:31:03 CST 2016


As the author of SE-0012, +1 :-)
On Sun, Feb 7, 2016 at 7:50 AM Dave Abrahams via swift-evolution <
swift-evolution at swift.org> wrote:

>
> 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
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160207/59df0ce1/attachment.html>


More information about the swift-evolution mailing list