Using arrays with functions taking ranges

monarch_dodra monarchdodra at gmail.com
Fri Dec 14 06:01:06 PST 2012


On Friday, 14 December 2012 at 13:09:15 UTC, Mu wrote:
> Thank you, monarch_dodra. This looks like what I wanted.
>
> I have a question:
> How come the function works with MmFile.opSlice's without 
> appender(&)?
> And is this reliable behavior?
>
> caesarCipher(cast(ubyte[]) inputFile.opSlice, cast(ubyte[]) 
> outputFile.opSlice, 13);

It "works" because in theory, all mutable ranges verify the "is 
output range" trait. However, they are not "sinks", so if you 
write too much into them, you'll get an out of index exception. 
Does it work at runtime, and do you get the correct behavior?

In this case, I don't think appender would work, because it would 
just re-allocate to a GC-allocated slice, and not your MM.

Reading the MM doc, I don't think it offers output range 
interface.

In this specific case, I think you are supposed to reserve the 
correct amount of space beforehand, and copy using input range 
interface. You'll have to make sure there is enough room first 
though. That's basically what you'd do with iterators mind you.

> Trying to use appender(&) on the casted opSlice's yields a "is 
> not an lvalue" error.

Yes, that's because when you are casting to ubyte[], you are 
creating a new *slice*. It refers to the same data as your 
"outputFile.opSlice" object, but the slice itself is a new 
object, so you cannot extract its address.

You might as well just use Appender instead of RefAppender: they 
both do exactly the same thing. The difference is that 
RefAppender will always re-assign your slice to the current 
buffer, so you can "see" the updates as it goes.


More information about the Digitalmars-d-learn mailing list