Move semantics for D

monarch_dodra monarch_dodra at gmail.com
Fri Jul 13 02:23:41 PDT 2012


On Friday, 13 July 2012 at 09:09:03 UTC, Benjamin Thaut wrote:
> Am 13.07.2012 10:59, schrieb Christophe Travert:
>> Benjamin Thaut , dans le message (digitalmars.D:172207), a 
>> écrit :
>>> Move semantics in C++0x are quite nice for optimization 
>>> purposes.
>>> Thinking about it, it should be fairly easy to implement move 
>>> semantics
>>> in D as structs don't have identity. Therefor a move 
>>> constructor would
>>> not be required. You can already move value types for example 
>>> within an
>>> array just by plain moving the data of the value around. With 
>>> a little
>>> new keyword 'mov' or 'move' it would also be possible to move 
>>> value
>>> types into and out of functions, something like this:
>>>
>>> mov Range findNext(mov Range r)
>>> {
>>>    //do stuff here
>>> }
>>>
>>> With something like this it would not be neccessary to copy 
>>> the range
>>> twice during the call of this function, the compiler could 
>>> just plain
>>> copy the data and reinitialize the origin in case of the 
>>> argument.
>>> In case of the return value to only copying would be 
>>> neccessary as the
>>> data goes out of scope anyway.
>>
>> If Range is a Rvalue, it will be moved, not copied.
>> It it's a Lvalue, your operation is dangerous, and does not 
>> bring you
>> much more than using ref (it may be faster to copy the range 
>> than to
>> take the reference, but that's an optimiser issue).
>>
>> auto ref seems to be the solution.
>>
>>> I for example have a range that iterates over a octree and 
>>> thus needs to
>>> internally track which nodes it already visited and which 
>>> ones are still
>>> left. This is done with a stack container. That needs to be 
>>> copied
>>> everytime the range is copied, which causes quite some 
>>> overhead.
>>
>> I would share the tracking data between several instance of 
>> the range,
>> making bitwise copy suitable. Tracking data would be 
>> duplicated only on
>> call to save or opSlice(). You'd hit the issue of foreach not 
>> calling
>> save when it should, but opSlice would solve this, and you 
>> could still
>> overload opApply if you want to be sure.
>>
>
> I couldn't find anything in the documentation about foreach 
> calling save or opSlice(). So I assume foreach calls opSlice if 
> aviable?
>
> foreach(el; range) { ... }
> translates to:
>
> for(auto r = range[]; !r.empty(); r.popFront()
> {
>   auto el = r.front();
>   ...
> }
>
> Kind Regards
> Benjamin Thaut

Depends if you are asking about "what the compiler does", or 
"what the compiler should do" or "what the documentation says". 
There is a discussion about it here:
http://forum.dlang.org/thread/rxpbtrawpjzvdfuuwmwp@forum.dlang.org

I think that in the case of your example, if "range" fulfills the 
requirements for (at least) an input range, then "save" *should* 
be called instead of "opSlice". I'm *think* this is what the 
compiler does, but I'm not 100% sure.


More information about the Digitalmars-d mailing list