[swift-evolution] [swift-evolution-announce] [Review] SE-0184: Unsafe[Mutable][Raw][Buffer]Pointer: add missing methods, adjust existing labels for clarity, and remove deallocation size

Taylor Swift kelvin13ma at gmail.com
Fri Sep 29 19:22:20 CDT 2017


On Fri, Sep 29, 2017 at 6:17 PM, Andrew Trick <atrick at apple.com> wrote:

>
>
> On Sep 29, 2017, at 4:03 PM, Taylor Swift <kelvin13ma at gmail.com> wrote:
>
>
>
> On Sep 29, 2017, at 5:56 PM, Dave Abrahams <dabrahams at apple.com> wrote:
>
>
>
> On Sep 29, 2017, at 3:48 PM, Taylor Swift <kelvin13ma at gmail.com> wrote:
>
>
>
> On Fri, Sep 29, 2017 at 4:13 PM, Andrew Trick <atrick at apple.com> wrote:
>
>>
>>
>> On Sep 29, 2017, at 1:23 PM, Taylor Swift <kelvin13ma at gmail.com> wrote:
>>
>> Instead of
>>>
>>>   buf.intialize(at: i, from: source)
>>>
>>> We want to force a more obvious idiom:
>>>
>>>   buf[i..<n].intialize(from: source)
>>>
>>>
>> The problem with subscript notation is we currently get the n argument
>> from the source argument. So what would really have to be written is
>>
>> buf[i ..< i + source.count].initialize(from: source)
>>
>> which is a lot more ugly and redundant. One option could be to decouple
>> the count parameter from the length of the source buffer, but that opens up
>> the whole can of worms in which length do we use? What happens if n - i is
>> less than or longer than source.count? If we enforce the precondition
>> that source.count == n - i, then this syntax seems horribly redundant.
>>
>>
>> Sorry, a better analogy would have been:
>>
>>  buf[i...].intialize(from: source)
>>
>> Whether you specify the slice’s end point depends on whether you want to
>> completely initialize that slice or whether you’re just filling up as much
>> of the buffer as you can. It also depends on whether `source` is also a
>> buffer (of known size) or some arbitrary Sequence.
>>
>> Otherwise, point  taken.
>>
>> -Andy
>>
>
> After thinking about this more, one-sided ranges might provide just the
> expressivity we need. What if:
>
> buf[offset...].initialize(from: source) // initializes source.count
> elements from source starting from offset
>
> buf[offset ..< endIndex].initialize(from: source) // initializes up to
> source.count elements from source starting from offset
>
>
> The one sided one does not give a full initialization guarantee. The two
> sided one guarantees the entire segment is initialized.
>
>
> In every other context, x[i...] is equivalent to x[i..<x.endIndex]
>
> I don't think breaking that precedent is a good idea.
>
> For move operations, the one sided one will fully deinitialize the source
> buffer while the two sided one will only deinitialize endIndex - offset
> elements.
>
>
>> -Dave
>
>
> well since people want to use subscript notation so much we need some way
> of expressing case 1. writing both bounds in the subscript seems to imply a
> full initialization (and thus partial movement) guarantee.
>
>
> Presumably, in your use case, you’re working directly with buffers on both
> sides (please point us to the real code). With the slicing approach, that
> would be done as follows:
>
> bufA[i ..< i + bufB.count].initialize(from: bufB)
>
> That will enforce full initialization of the slice:
> precondition(self.count == source.count).
>
> Your point stands that it is redundant. That point will need to be weighed
> against other points, which I think should be discussed in another thread.
>
> -Andy
>

To this and your other method about the real library code; right now the
PNG library doesn’t use buffer methods (since they don’t exist yet) and
pixels are plain-old-data so i’m not using the memory state API there
anyway (the original proposal didn’t even have anything to do with those
APIs actually). However I did take a few minutes to write a quick queue
implementation
<https://gist.github.com/kelvin13/0860334278aeab5c1cbaefbefb050268#file-dequeue-swift>
in Swift which does not make any assumptions about the Element type. I then
rewrote it using the hypothetical buffer API I proposed, and then the
hypothetical buffer API using subscript notation.



*These are the relevant function calls using the current API (the rest of
the code has been stripped out)*

        newBuffer:UnsafeMutablePointer<Element> =
                    UnsafeMutablePointer<Element>.allocate(capacity:
newCapacity)

        newBuffer              .moveInitialize( from:  buffer + self.zero,
                                                        count:
self.capacity - self.zero)
        (newBuffer + self.zero).moveInitialize( from:  buffer,
                                                        count: self.zero)
        buffer.deallocate(capacity: self.capacity)

        (self.buffer! + self.bufferPosition(of: self.count)).initialize(to:
data)

        let dequeued:Element = (self.buffer! + self.zero).move()

*These are the function calls using the SE 184 API *

        newBuffer:UnsafeMutableBufferPointer<Element> =
                    UnsafeMutableBufferPointer<Element>.allocate(capacity:
newCapacity)

        newBuffer.moveInitialize(at: 0,         from:
self.buffer[self.zero...   ])
        newBuffer.moveInitialize(at: self.zero, from: self.buffer[0 ..<
self.zero])
        self.buffer.deallocate()

        (self.buffer.baseAddress! + self.bufferPosition(of:
self.count)).initialize(to: data)

        let dequeued:Element = (self.buffer! + self.zero).move()

*And with the proposed subscript notation*

        newBuffer:UnsafeMutableBufferPointer<Element> =
                    UnsafeMutableBufferPointer<Element>.allocate(capacity:
newCapacity)

        newBuffer[0...                        ].moveInitialize(from:
self.buffer[self.zero...   ])
        newBuffer[self.zero ... self.zero << 1].moveInitialize(from:
self.buffer[0 ..< self.zero])
        self.buffer.deallocate()

        (self.buffer.baseAddress! + self.bufferPosition(of:
self.count)).initialize(to: data)

        let dequeued:Element = (self.buffer! + self.zero).move()


I took out the rebasing calls since apparently we’re bringing slices into
the scope of this proposal.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170929/9d142452/attachment.html>


More information about the swift-evolution mailing list