digitalmars.D.learn - attribute length missing in std.array: Appender
- Andre (22/22) Nov 27 2014 Hi,
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (13/35) Nov 27 2014 You can initialize the appender with an existing array, or put an
- andre (4/44) Nov 27 2014 Thanks a lot for the help.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/13) Nov 28 2014 A fancy way: :)
- bearophile (21/30) Nov 28 2014 Now we have a better syntax for implicit casts:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (24/33) Nov 28 2014 Much better! :)
- bearophile (8/14) Nov 28 2014 I'd like a function like that in Phobos (with a little
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é
Nov 27 2014
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.
Nov 27 2014
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.
Nov 27 2014
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 0A fancy way: :) import std.range; // ... app.put(repeat(cast(ubyte)0).take(5)); Ali
Nov 28 2014
Ali Çehreli: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, bearophileauto app = appender!(ubyte[])(); app.put(cast(ubyte)40); app.put(cast(ubyte)5); app.put(cast(ubyte)234); // ... add 5 times 0A fancy way: :) import std.range; // ... app.put(repeat(cast(ubyte)0).take(5));
Nov 28 2014
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
Nov 28 2014
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
Nov 28 2014