Re: attribute length missing in std.array: Appender

2014-11-28 Thread bearophile via Digitalmars-d-learn

Ali Çehreli:


void expandWith(A, R)(ref A arr, R range)
{
foreach (e; range) {
arr ~= e;
}
}


I'd like a function like that in Phobos (with a little 
improvement: when the length of the given range is available 
inside expandWith, it should first extend the capacity to 
increase performance a little). But I'd call it "extend" as in 
Python.


Bye,
bearophile


Re: attribute length missing in std.array: Appender

2014-11-28 Thread Ali Çehreli via Digitalmars-d-learn

On 11/28/2014 12:44 AM, bearophile wrote:

> Now we have a better syntax for implicit casts:

[...]

>  app.put(ubyte(0).repeat.take(5));

Much better! :)

> But I have a question too. What's the best way to append several lazy
> items to a dynamic array? This doesn't work:
>
> void main() {
>  import std.array, std.range;
>  int[] arr;
>  arr.put(only(1, 2, 3));
> }

I don't think there is a better way in Phobos. (?) The following trivial 
function would do as long as the array has room at the end, which 
requires that it is "safe to append":


void expandWith(A, R)(ref A arr, R range)
{
foreach (e; range) {
arr ~= e;
}
}

void main() {
import std.range;

int[] arr = [ 42 ];

// Ensure that there is room for new elements
arr.reserve(100);
assumeSafeAppend(arr);

const oldPlace = arr.ptr;
arr.expandWith(only(1, 2, 3));
const newPlace = arr.ptr;

assert(newPlace == oldPlace);
}

Ali



Re: attribute length missing in std.array: Appender

2014-11-28 Thread bearophile via Digitalmars-d-learn

Ali Çehreli:


auto app = appender!(ubyte[])();
app.put(cast(ubyte)40);
app.put(cast(ubyte)5);
app.put(cast(ubyte)234);
// ... add 5 times 0


A fancy way: :)

import std.range;

// ...

app.put(repeat(cast(ubyte)0).take(5));


Now we have a better syntax for implicit casts:

void main() {
import std.array, std.range;
Appender!(ubyte[]) app;
app.put(ubyte(0).repeat.take(5));
}


Single line, but not lazy:

void main() {
import std.array, std.range;
Appender!(ubyte[]) app = ubyte(0).repeat.take(5).array;
}


But I have a question too. What's the best way to append several 
lazy items to a dynamic array? This doesn't work:


void main() {
import std.array, std.range;
int[] arr;
arr.put(only(1, 2, 3));
}

Bye,
bearophile


Re: attribute length missing in std.array: Appender

2014-11-28 Thread Ali Çehreli via Digitalmars-d-learn

On 11/27/2014 08:08 AM, Andre wrote:


import std.array: appender;
const HEADER_LENGTH = 8;

auto app = appender!(ubyte[])();
app.put(cast(ubyte)40);
app.put(cast(ubyte)5);
app.put(cast(ubyte)234);
// ... add 5 times 0


A fancy way: :)

import std.range;

// ...

app.put(repeat(cast(ubyte)0).take(5));

Ali



Re: attribute length missing in std.array: Appender

2014-11-27 Thread andre via Digitalmars-d-learn

Thanks a lot for the help.

Kind regards
André



On Thursday, 27 November 2014 at 17:29:50 UTC, Marc Schütz wrote:

On Thursday, 27 November 2014 at 16:08:13 UTC, Andre wrote:

Hi,

I implement a network protocol and use an Appender!(ubyte[])().
I have following issue. The first three bytes I have to fill,
the following bytes are reserved and must be 0. In this example
the overall header length must be 8.

import std.array: appender;
const HEADER_LENGTH = 8;

auto app = appender!(ubyte[])();
app.put(cast(ubyte)40);
app.put(cast(ubyte)5);
app.put(cast(ubyte)234);
// ... add 5 times 0
// variable length body will follow

In case of dynamic array I can simple set the length to 8.
Appender doesn't have a length attribute.

Is there some other nice D functionaliy I can use?
Maybe some functionality in std.array is missing: app.fill(0, 
HEADER_LENGTH)?

Currently I do a work around with a for loop.

Kind regards
André


You can initialize the appender with an existing array, or put 
an entire array into it at once:


import std.array: appender;
ubyte[] temp;
temp.reserve(8);  // reserve first, so that only one 
allocation happens

temp[0 .. 3] = [40, 5, 234];
temp.length = 8;
auto app = appender!(ubyte[])(temp);
// or:
app.put(temp);

The array will not be copied when the appender is constructed.




Re: attribute length missing in std.array: Appender

2014-11-27 Thread via Digitalmars-d-learn

On Thursday, 27 November 2014 at 16:08:13 UTC, Andre wrote:

Hi,

I implement a network protocol and use an Appender!(ubyte[])().
I have following issue. The first three bytes I have to fill,
the following bytes are reserved and must be 0. In this example
the overall header length must be 8.

import std.array: appender;
const HEADER_LENGTH = 8;

auto app = appender!(ubyte[])();
app.put(cast(ubyte)40);
app.put(cast(ubyte)5);
app.put(cast(ubyte)234);
// ... add 5 times 0
// variable length body will follow

In case of dynamic array I can simple set the length to 8.
Appender doesn't have a length attribute.

Is there some other nice D functionaliy I can use?
Maybe some functionality in std.array is missing: app.fill(0, 
HEADER_LENGTH)?

Currently I do a work around with a for loop.

Kind regards
André


You can initialize the appender with an existing array, or put an 
entire array into it at once:


import std.array: appender;
ubyte[] temp;
temp.reserve(8);  // reserve first, so that only one 
allocation happens

temp[0 .. 3] = [40, 5, 234];
temp.length = 8;
auto app = appender!(ubyte[])(temp);
// or:
app.put(temp);

The array will not be copied when the appender is constructed.


attribute length missing in std.array: Appender

2014-11-27 Thread Andre via Digitalmars-d-learn

Hi,

I implement a network protocol and use an Appender!(ubyte[])().
I have following issue. The first three bytes I have to fill,
the following bytes are reserved and must be 0. In this example
the overall header length must be 8.

import std.array: appender;
const HEADER_LENGTH = 8;

auto app = appender!(ubyte[])();
app.put(cast(ubyte)40);
app.put(cast(ubyte)5);
app.put(cast(ubyte)234);
// ... add 5 times 0
// variable length body will follow

In case of dynamic array I can simple set the length to 8.
Appender doesn't have a length attribute.

Is there some other nice D functionaliy I can use?
Maybe some functionality in std.array is missing: app.fill(0, 
HEADER_LENGTH)?

Currently I do a work around with a for loop.

Kind regards
André