Scope Containers
Atila Neves
atila.neves at gmail.com
Mon Mar 11 18:29:23 UTC 2019
On Monday, 11 March 2019 at 17:00:35 UTC, bitwise wrote:
> 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.
Why?
> 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.
Or you don't consume it all and slice it (as I mentioned in my
last post):
@safe unittest {
scope v = vector(1, 2, 3);
static void fun(R)(R range) {
import std.array: array;
assert(range.array == [1, 2, 3]);
}
fun(v[]);
// wasn't consumed
assert(v[] == [1, 2, 3]);
}
Again, it's @safe because the slice is scoped.
> For any kind of persistent storage though, I would consider the
> performance costs of using this container's range functionality
> too high.
There aren't any performance costs. You pass a fat pointer just
like you would with a GC array.
> 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.
Which is why Vector has both opSlice and copies by default. It's
only a range itself if the element type is mutable, otherwise it
doesn't even define popFront.
> So I'm wondering if it would work well to use an integer index
> for the range implementation
That's what slices are.
More information about the Digitalmars-d
mailing list