<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 2, 2016, at 8:27 PM, Nate Cook <<a href="mailto:natecook@gmail.com" class="">natecook@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 2, 2016, at 2:12 PM, Ben Cohen via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 1, 2016, at 11:33 PM, Nate Cook via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">3) Make all buffer pointers their own slices but use a different index type. If the indices were just wrapped pointers, that would handle the index sharing without needing an additional property on the buffer. We could also maintain integer-based stridable conformance (which greatly simplifies index arithmetic), since the indices would just offset by a byte for raw buffers or a stride for typed buffers.</div><br class="Apple-interchange-newline"></div></blockquote></div><br class=""><div class="">Unfortunately, switching to non-integer indices would change this from being mildly source-breaking to being extremely source-breaking, as there’s lots of code out there using buffers today indexing them with integers (including integer literals).</div><div class=""><br class=""></div><div class="">The big win with UnsafeBufferPointer having an integer index is it’s a drop-in replacement for arrays, so when you hit a performance problem using an array you can quickly switch to using a buffer under most circumstances instead without having to change much of your code – including code that uses <font face="Menlo" class="">for i in 0..<myArray.count</font>, of which there is a lot out there in the wild. Switching to an opaque index would break anyone doing that.</div></div></div></blockquote><br class=""></div><div class="">It is definitely very source-breaking, though with relatively simple fixits:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>buf[0] ---> buf[buf.startIndex]</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>buf[3] ---> buf[buf.startIndex + 3]</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>buf[i] ---> buf[buf.startIndex + i]</div><div class=""><br class=""></div><div class="">Any integer arithmetic happening outside the subscript could be left unchanged. If that cost isn't worth the benefit, then making UnsafeRawBufferPointer use Slice as its slice type is probably the best way to resolve that issue.</div><div class=""><br class=""></div></div></div></div>Nate</div></div></blockquote></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The fixits aren’t quite that simple for slices, though:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let slice = buf[3..<6]</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>slice[3] —> slice[slice.startIndex + 0] // fixit would somehow need to know this is 0 not 3</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>slice[i] —> slice[slice.startIndex + ??] // or even need to know this is, erm, I haven’t had enough coffee this morning</div><br class=""><div class="">The other downside is it would thwart speculatively switching an Array to an UnsafeBuffer to see if that was a bottleneck, then switching back.</div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Dec 1, 2016, at 11:33 PM, Nate Cook via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">1) Switch to using Slice as a wrapper for UnsafeRawBufferPointer.</div><br class="Apple-interchange-newline"></div></blockquote></div><br class=""><div class="">Based on the above, it seems like this is the least bad option, and we need to do this ASAP as currently UnsafeRawBufferPointer is non-compliant with the requirements of slicing and needs changing before it’s more widely adopted.</div></div><div class=""><br class=""></div></body></html>