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/[email protected]
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.