> On Aug 19, 2017, at 6:16 PM, Taylor Swift <kelvin1...@gmail.com> wrote: > > What you’re describing is basically an earlier version of the proposal which > had a slightly weaker precondition (source >= destination) than yours (source > == destination). That one basically ignored the Sequence methods at the > expense of greater API surface area.
The Sequence methods don’t provide the simpler, more convenient form of initialization/deinitialization that I thought you wanted. I see two reasonable options. 1. Don’t provide any new buffer initialization/deinitialization convenience. i.e. drop UsafeMutableBufferPointer moveInitialize, moveAssign, and deinitialize from your proposal. 2. Provide the full set of convenience methods: initialize, assign, moveInitialize, and moveAssign assuming self.count==source.count. And provide deinitialize() to be used only in conjunction with those new initializers. The question is really whether those new methods are going to significantly simplify your code. If not, #1 is the conservative choice. Don't provide convenience which could be misused. Put off solving that problem until we can design a new move-only buffer type that tracks partially initialized state. -Andy > On Sat, Aug 19, 2017 at 9:08 PM, Andrew Trick <atr...@apple.com > <mailto:atr...@apple.com>> wrote: > >> On Aug 19, 2017, at 6:03 PM, Taylor Swift <kelvin1...@gmail.com >> <mailto:kelvin1...@gmail.com>> wrote: >> >> >> >> On Sat, Aug 19, 2017 at 8:52 PM, Andrew Trick <atr...@apple.com >> <mailto:atr...@apple.com>> wrote: >>>> >>>> The problem is I would expect to be able to safely call deinitialize() and >>>> friends after calling initialize(from:). If Element is a class type and >>>> initialize doesn’t fill the entire buffer range, calling deinitialize() >>>> will crash. That being said, since copy(from:bytes:) and copyBytes(from:) >>>> don’t do any initialization and have no direct counterparts in >>>> UnsafeMutableBufferPointer, it’s okay if they have different behavior than >>>> the other methods. >>> >>> You astutely pointed out that the UnsafeMutableBufferPointer.deinitialize() >>> method is dangerous, and I asked you to add a warning to its comments. >>> However, given the danger, I think we need to justify adding the method to >>> begin with. Are there real use cases that greatly benefit from it? >>> >>> I agree that’s a problem, which is why i was iffy on supporting partial >>> initialization to begin with. The use case is for things like growing >>> collections where you have to periodically move to larger storage. However, >>> deinitialize is no more dangerous than moveInitialize, >>> assign(repeating:count:), or moveAssign; they all deinitialize at least one >>> entire buffer. If deinitialize is to be omitted, so must a majority of the >>> unsafe pointer API. >> >> Here's an alternative. Impose the precondition(source.count == self.count) >> to the following UnsafeMutableBufferPointer convenience methods that you >> propose adding: >> >> +++ func assign(from:UnsafeBufferPointer<Element>) >> +++ func assign(from:UnsafeMutableBufferPointer<Element>) >> +++ func moveAssign(from:UnsafeMutableBufferPointer<Element>) >> +++ func moveInitialize(from:UnsafeMutableBufferPointer<Element>) >> +++ func initialize(from:UnsafeBufferPointer<Element>) >> +++ func initialize(from:UnsafeMutableBufferPointer<Element>) >> >> I don't that introduces any behavior that is inconsistent with other >> methods. `copyBytes` is a totally different thing that only works on trivial >> types. The currently dominant use case for UnsafeBufferPointer, partially >> initialized backing store, does not need to use your new convenience >> methods. It can continue dropping down to pointer+count style >> initialization/deinitialization. >> >> -Andy >> >> the latest draft does not have >> assign(from:UnsafeMutableBufferPointer<Element>) or >> initialize(from:UnsafeMutableBufferPointer<Element>), it uses the generic >> Sequence methods that are already there that do not require that >> precondition. > > Sorry, I was pasting from your original proposal. Here are the relevant > methods from the latest draft: > > https://github.com/kelvin13/swift-evolution/blob/1b7738513c00388b8de3b09769eab773539be386/proposals/0184-improved-pointers.md > > <https://github.com/kelvin13/swift-evolution/blob/1b7738513c00388b8de3b09769eab773539be386/proposals/0184-improved-pointers.md> > > +++ func moveInitialize(from:UnsafeMutableBufferPointer<Element>) > +++ func moveAssign(from:UnsafeMutableBufferPointer<Element>) > > But with the precondition, the `assign` method could be reasonably added > back, right? > +++ func assign(from:UnsafeMutableBufferPointer<Element>) > > Likewise, I don’t have a problem with initialize(from: UnsafeBufferPointer) > where self.count==source.count. The Sequence initializer is different. It’s > designed for the Array use case and forces the caller to deal with partial > initialization. > > UnsafeMutableRawBufferPointer.moveInitializeMemory on the other hand probably > doesn't need that precondition since there's no way to deinitialize. It just > needs clear comments. > > -Andy >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution