<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Aug 19, 2017 at 6:05 PM, Andrew Trick <span dir="ltr">&lt;<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><br><div><blockquote type="cite"><div>On Aug 9, 2017, at 8:51 AM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="m_2573699732820783188Apple-interchange-newline"><div><br class="m_2573699732820783188Apple-interchange-newline"><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">On Wed, Aug 9, 2017 at 2:34 AM, Andrew Trick<span class="m_2573699732820783188Apple-converted-space"> </span><span dir="ltr">&lt;<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>&gt;</span><span class="m_2573699732820783188Apple-converted-space"> </span>wrote<wbr>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><blockquote type="cite"><div>On Aug 8, 2017, at 11:10 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="m_2573699732820783188m_-4859785049460883042Apple-interchange-newline"><div><div dir="ltr"><br><div class="gmail_extra">On Wed, Aug 9, 2017 at 1:51 AM, Andrew Trick<span class="m_2573699732820783188Apple-converted-space"> </span><span dir="ltr">&lt;<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>&gt;</span><span class="m_2573699732820783188Apple-converted-space"> </span>wrote<wbr>:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><br><div><span class="m_2573699732820783188m_-4859785049460883042gmail-"><blockquote type="cite"><div>On Aug 8, 2017, at 8:44 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="m_2573699732820783188m_-4859785049460883042gmail-m_2532167022362721963Apple-interchange-newline"><div><div dir="ltr">cool,, as for<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">UnsafeMutableRawBufferPoin<wbr>ter.copy(from:bytes:)</span>, I cannot find such a function anywhere in the API. There is<span class="m_2573699732820783188Apple-converted-space"> </span><a href="https://developer.apple.com/documentation/swift/unsafemutablerawbufferpointer/2635415-copybytes" target="_blank"><span style="font-family:monospace,monospace">copyBytes(from:)</span></a>, but the documentation is messed up and mentions a nonexistent<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">count:</span><span class="m_2573699732820783188Apple-converted-space"> </span>argument over and over again. The documentation also doesn’t mention what happens if there is a length mismatch, so users are effectively relying on an implementation detail. I don’t know how to best resolve this.<br></div></div></blockquote><div><br></div></span><div>We currently have `UnsafeMutableRawBufferPointer<wbr>.copyBytes(from:)`. I don’t think your proposal changes that. The current docs refer to the `source` parameter, which is correct. Docs refer to the parameter name, not the label name. So `source.count` is the size of the input. I was pointing out that it has the semantics: `debugAssert(source.count &lt;= self.count)`.</div><div><br></div><div>Your proposal changes `UnsafeRawPointer.copyBytes(fr<wbr>om:count:)` to `UnsafeRawPointer.copy(from:by<wbr>tes:)`. Originally we wanted to those API names to match, but I’m fine with your change. What is more important is that the semantics are the same as `copyBytes(from:)`. Furthermore, any new methods that you add that copy into a raw buffer (e.g. initializeMemory(as:from:count<wbr>:)) should have similar behavior.</div><div><br></div></div></div></blockquote><div> </div><div>I’m fine with switching to taking the<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">count</span><span class="m_2573699732820783188Apple-converted-space"> </span>from the source, though I think taking the<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">count</span><span class="m_2573699732820783188Apple-converted-space"> </span>from the destination is slightly better because 1) the use cases I mentioned in the other email, and 2) all the other memorystate functions use<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">self.count</span><span class="m_2573699732820783188Apple-converted-space"> </span>instead of<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">source.count</span>, if they take a<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">source</span><span class="m_2573699732820783188Apple-converted-space"> </span>argument. But being consistent with the raw pointer version is more important.</div></div></div></div></div></blockquote><div><br></div></span>If it’s copying from a buffer it should not take a count, if it’s copying from a pointer it obviously needs to take a count. What I mean by the two versions being named consistently is simply that they’re both named `copyBytes`. That really isn’t important though. The overflow/underflow semantics being consistent are important.</div><div><br></div><div>(Incidentally, the reason “bytes” needs to be in the somewhere name is because this method isn’t capable of copying nontrivial values)</div><div><span><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Should the methods that don’t deal with raw buffers also be modified to use the source argument (i.e. UnsafeMutableBufferPointer.ini<wbr>tialize(from:))?<br></div></div></div></div></div></blockquote><div><br></div></span><div>I’m not sure what you mean by this. It also allows the destination to be larger than the source. Initializing from a sequence does not trap on overflow because we can’t guarantee the size of the sequence ahead of time. When I talk about consistent overflow/underflow semantics, I’m only talking about initializing one unsafe buffer/pointer from another unsafe buffer/pointer.</div><span><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Also, was there a reason why<span class="m_2573699732820783188Apple-converted-space"> </span><span style="font-family:monospace,monospace">UnsafeMutableRawBufferPoin<wbr>ter.copyBytes(from:)</span><span class="m_2573699732820783188Apple-converted-space"> </span>uses the source’s count instead of its own? Right now this behavior is “technically” undocumented behavior (as the public docs haven’t been updated) so if there was ever a time to change it, now would be it.<br></div></div></div></div></div></blockquote><div><br></div></span><div>Mainly because partial initialization is more expected than dropping data on the floor. Ultimately, this should be whatever typical developers would expect the behavior to be. I would be very hesitant to change the behavior now though.</div><div><br></div><div>-Andy</div></div></div></blockquote><div><br></div><div>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.</div></div></div></blockquote><br></div></span><div><div>You astutely pointed out that the UnsafeMutableBufferPointer.<wbr>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?</div></div></div></blockquote></div></div><div class="gmail_extra"><br></div><div class="gmail_extra">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.<br></div></div>