Thread overview
how does range.put work
Aug 06, 2009
O.K.
Aug 07, 2009
Daniel Keep
Aug 07, 2009
O.K.
Aug 08, 2009
Jos van Uden
Aug 08, 2009
Daniel Keep
Aug 08, 2009
Jos van Uden
August 06, 2009
Hello,
could someone plz clearify what the exact semantics of "put"
are ?
Put works with an appender, but gives me a runtime exception
when using an array.

Best regards,
Oliver
August 07, 2009

O.K. wrote:
> Hello,
> could someone plz clearify what the exact semantics of "put"
> are ?
> Put works with an appender, but gives me a runtime exception
> when using an array.
> 
> Best regards,
> Oliver

The source code for the standard library comes with the compiler.

If you look in std\array.d, you find this around line 279 (reflowed for
readability):

> void put(T, E)(ref T[] a, E e) {
>     assert(a.length);
>     a[0] = e; a = a[1 .. $];
> }
August 07, 2009
Good point ! Use the [S/F]o[u]rce !
Thx, Oliver

> O.K. wrote:
> > Hello,
> > could someone plz clearify what the exact semantics of "put"
> > are ?
> > Put works with an appender, but gives me a runtime exception
> > when using an array.
> >
> > Best regards,
> > Oliver
> The source code for the standard library comes with the compiler.
> If you look in std\array.d, you find this around line 279 (reflowed for
> readability):
> > void put(T, E)(ref T[] a, E e) {
> >     assert(a.length);
> >     a[0] = e; a = a[1 .. $];
> > }

August 08, 2009
Oliver wrote:
>> The source code for the standard library comes with the compiler.
>> If you look in std\array.d, you find this around line 279 (reflowed for
>> readability):
>>> void put(T, E)(ref T[] a, E e) {
>>>     assert(a.length);
>>>     a[0] = e; a = a[1 .. $];
>>> }

Would anybody care to explain what this is used for? I find
the example in array.d rather unhelpful.

Example:
----
void main()
{
    int[] a = [ 1, 2, 3 ];
    int[] b = a;
    a.put(5);
    assert(a == [ 2, 3 ]);
    assert(b == [ 5, 2, 3 ]);
}

You're putting an element in a, but then the first element is moved out of a and the new one shows up in b? Weird. I guess I don't understand what a range is.

Jos


August 08, 2009

Jos van Uden wrote:
> Oliver wrote:
>>> The source code for the standard library comes with the compiler.
>>> If you look in std\array.d, you find this around line 279 (reflowed for
>>> readability):
>>>> void put(T, E)(ref T[] a, E e) {
>>>>     assert(a.length);
>>>>     a[0] = e; a = a[1 .. $];
>>>> }
> 
> Would anybody care to explain what this is used for? I find the example in array.d rather unhelpful.
> 
> Example:
> ----
> void main()
> {
>     int[] a = [ 1, 2, 3 ];
>     int[] b = a;
>     a.put(5);
>     assert(a == [ 2, 3 ]);
>     assert(b == [ 5, 2, 3 ]);
> }
> 
> You're putting an element in a, but then the first element is moved out of a and the new one shows up in b? Weird. I guess I don't understand what a range is.
> 
> Jos

No; read the code.  Before the put, a and b are pointing to the same
span of memory.  a.put(5) puts the value 5 into the front (first
element) of the array, then advances the array.

However, put can't "see" b, so it doesn't get updated along with a.  The end result is that b = [5,2,3] and a = b[1..3] = [2,3].

Why do it like this?  Here's an example:

void putNumbers(Range)(Range r)
{
    int i = 0;
    while( !r.empty )
    {
        r.put(i);
        ++i;
    }
}

void main()
{
    int[10] ten_numbers;
    putNumbers(ten_numbers);
    assert( ten_numbers = [0,1,2,3,4,5,6,7,8,9] );
}

Note that putNumbers will work with any type that supports the range API, not just arrays.
August 08, 2009
Daniel Keep wrote:

> No; read the code.  Before the put, a and b are pointing to the same
> span of memory.  a.put(5) puts the value 5 into the front (first
> element) of the array, then advances the array.
> 
> However, put can't "see" b, so it doesn't get updated along with a.  The
> end result is that b = [5,2,3] and a = b[1..3] = [2,3].
> 
> Why do it like this?  Here's an example:
> 
> void putNumbers(Range)(Range r)
> {
>     int i = 0;
>     while( !r.empty )
>     {
>         r.put(i);
>         ++i;
>     }
> }
> 
> void main()
> {
>     int[10] ten_numbers;
>     putNumbers(ten_numbers);
>     assert( ten_numbers = [0,1,2,3,4,5,6,7,8,9] );
> }

I see.

Your example should be in the documentation in my opinion, rather
then the meaningless one that's there now. Something like this
perhaps:

void putNumbers(Range, T)(Range r, T start, T incr) {
    T i = start;
    while( !r.empty )
    {
        r.put(i);
        i += incr;
    }
}

void main() {
   int[10] ten_ints;
   putNumbers!(int[])(ten_ints, 4, 2);
   assert( ten_ints == [4,6,8,10,12,14,16,18,20,22] );
}

Jos