www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - moveAt vs opIndex

reply maarten van damme <maartenvd1994 gmail.com> writes:
I am trying to write a randomaccessinfinite range that returns primes
using the sieve of aristotle. I am however having problems
understanding the difference between moveAt and opIndex;

according to dlang;
ElementType=A0opIndex(size_t=A0n);
Returns the=A0nth element in the composite range. Defined if all ranges
offer random access.

ElementType=A0moveAt(size_t=A0n);
Destructively reads the=A0nth element in the composite range. Defined if
all ranges offer random access.

Whats the difference between destructively reading and returning?

And why would I need to define moveFront and front when I already
defined opIndex?
May 18 2012
parent "Chris Cain" <clcain uncg.edu> writes:
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]; }
May 18 2012