Scope Containers

bitwise bitwise.pvt at gmail.com
Mon Mar 11 17:00:35 UTC 2019


On Sunday, 10 March 2019 at 18:46:14 UTC, Atila Neves wrote:
> On Sunday, 10 March 2019 at 17:36:09 UTC, bitwise wrote:
>> On Sunday, 10 March 2019 at 16:10:10 UTC, Atila Neves wrote:
>>> On Sunday, 10 March 2019 at 15:12:03 UTC, bitwise wrote:
>>>> [...]
>>>
>>> Like `const`, `scope` on a member function means that the 
>>> `this` reference is `scope`.
>>
>> Interesting. I'll have to look up some examples.
>>
>>>> [...]
>>>
>>> https://github.com/atilaneves/automem/blob/2a97acba94d6fe0bf9ba07fec99e86e46aa0f2a1/source/automem/vector.d#L134
>>> https://github.com/atilaneves/automem/blob/2a97acba94d6fe0bf9ba07fec99e86e46aa0f2a1/source/automem/vector.d#L159
>>> https://github.com/atilaneves/automem/blob/2a97acba94d6fe0bf9ba07fec99e86e46aa0f2a1/source/automem/vector.d#L145
>>>
>>> static assert(isInputRange!(Vector!int));
>>>
>>>> [...]
>>>
>>> I would think so, especially since I wrote Vector to be @safe 
>>> with dip1000. Look at this unit test for not being able to 
>>> escape the payload for example:
>>>
>>> https://github.com/atilaneves/automem/blob/master/tests/ut/vector.d#L229
>>
>> Ok, but this container copies the entire collection in 
>> postblit:
>> https://github.com/atilaneves/automem/blob/2a97acba94d6fe0bf9ba07fec99e86e46aa0f2a1/source/automem/vector.d#L104
>
> Well, yes. As it says in the module ddoc, it's my version of 
> C++'s std::vector. If you don't want it to copy, pass by ref.
>
>> So if you try to treat it like a range, you'll take a 
>> performance hit every time you trigger the postblit, which 
>> seems likely.
>
> You can pass it by ref like I mention above, or you could slice 
> it and pass the slice instead. Without DIP1000 passing the 
> slice wouldn't be @safe but with it, it is.
>
> Again, just like std::vector, which is pretty much always 
> passed by const ref. But safer and with a default allocator.
>
>> Isn't it reasonable to assume a range should act like a 
>> reference to data, rather than a copy of it?
>
> It depends.

This container seems good for short-lived usage. If I wanted to 
pass a bunch of filenames to a function for processing, I would 
consider this container Ok, because it would allocate once, then 
be consumed as a range without having to copy anything. For any 
kind of persistent storage though, I would consider the 
performance costs of using this container's range functionality 
too high.

At this point, I'm leaning toward just building separate 
containers. One would be a vector-like container that's @nogc and 
only has an indexer, but does not support iterators/ranges. The 
second would be a class-based container which *would* have 
range/iterator support since the ranges/iterators could safely 
contain pointers back to the GC-allocated collection for range 
checks and such.

I do think the idea of making the container itself the range is 
interesting, but what ruins it for me is the fact that ranges are 
consumable. So I'm wondering if it would work well to use an 
integer index for the range implementation instead of actually 
depleting the elements as you iterate, and have a "reset" 
function to refill the range so that no copying is necessary. I 
wonder how useful it would be to have some sort of 
NonConsumableRange concept that included reset() function.

   Bit


More information about the Digitalmars-d mailing list