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.

Reply via email to