moveAt vs opIndex

Chris Cain clcain at uncg.edu
Fri May 18 10:56:11 PDT 2012


In your case, I don't think you really need to define a moveAt. 
opIndex is what's required for a Random Access Range and it 
really doesn't make sense to define moveAt for your particular 
problem.

On Friday, 18 May 2012 at 12:21:31 UTC, maarten van damme wrote:
> Whats the difference between destructively reading and 
> returning?

Destructively reading means it can clear out the space that it's 
returning from. It does this by (effectively) setting that 
position to ElementType.init.

Let's assume it did this for ints (but it doesn't): So, if I have 
an array [2,5,3] and I say "moveAt(1)" it would return 5 and the 
array would be [2,0,3].

The reason it doesn't always work that way is because it will 
only "destructively" read when it's a struct who has a destructor 
defined or has a copy constructor defined. It basically bit 
copies an ElementType.init version over the source to prevent 
that destructor or copy constructor from being called and 
(potentially) doing some unintended things ... like double 
freeing memory (if your struct frees memory).

Generally, most moveAt, moveFront, and moveBack implementations 
will end up calling std.algorithm's move function:
http://dlang.org/phobos/std_algorithm.html#move
https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L1325
https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L1417

> And why would I need to define moveFront and front when I 
> already
> defined opIndex?

front is required for your range to be an input range. The 
compiler does not transfer calls from .front to .opIndex(0) 
implicitly (and it might be problematic for some people if it did 
as you don't want everything to be a range).

If you want that behavior, you have to explicitly define it to 
work that way:
ElementType front() @property { return this[0]; }


More information about the Digitalmars-d-learn mailing list