Re: attribute length missing in std.array: Appender
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
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
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
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
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
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
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é