Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
November 27, 2014 attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
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é |
November 27, 2014 Re: attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre | 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.
|
November 28, 2014 Re: attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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.
|
November 28, 2014 Re: attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre | 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 |
November 28, 2014 Re: attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 |
November 29, 2014 Re: attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 |
November 29, 2014 Re: attribute length missing in std.array: Appender | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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
|
Copyright © 1999-2021 by the D Language Foundation