std.range.put?

jerro a at a.com
Mon May 21 06:16:04 PDT 2012


On Monday, 21 May 2012 at 11:26:33 UTC, simendsjo wrote:
> Shouldn't the following work?
>
> import std.range;
> import std.stdio;
>
> void main() {
>     int[] a;
>     a.reserve(10);
>     //a.put(1); // Attempting to fetch the front of an empty 
> array of int
>     a.length = 1;
>     writeln(a.length); // 1
>     a.put(2);
>     writeln(a.length); // 0 - what?
>     writeln(a); // [] - come on!
>
>     char[] b;
>     //b.put('a'); // range.d(615): Error: static assert  
> "Cannot put a char into a char[]"
> }

Input ranges are supposed to work like that when use as output
range. You could change that by also defining a put member for
them, but I don't think doing that would be a good idea. The
current behavior allows you to fill an input range using a
function that takes an output range. For example you can do
the following with an array:


auto a = [4, 3, 2, 1, 0];
copy([0,1,2], a);
writeln(a); // prints [0, 1, 2, 1, 0]

If an array had a put member that would append to it, this
would print [4, 3, 2, 1, 0, 0, 1, 2]. I think it is better
to have to explicitly state that you want to append to an
array. It should be possible to use RefAppender for that:

copy([0, 1, 2], appender(&a)); // error

This currently doesn't work (I think that because RefAppender 
implements
put through opDispatch and constraint for range.put checks for 
put member
using hasMember). You could write your own function to work 
around that:

auto output(T)(ref T[] arr)
{
     static struct R
     {
         T[]* arr;
         void put(int v){ arr ~= v; }
     }
     return R(&arr);
}

auto a = [4, 3, 2, 1, 0];
copy([0,1,2], output(a));
writeln(a); // prints [4, 3, 2, 1, 0, 0, 1, 2]



More information about the Digitalmars-d-learn mailing list