On Sunday, May 24, 2015 22:13:25 Steven Schveighoffer via Digitalmars-d-learn wrote: > On 5/23/15 4:27 AM, Jonathan M Davis via Digitalmars-d-learn wrote: > > On Saturday, May 23, 2015 07:03:33 Vladimir Panteleev via > > Digitalmars-d-learn wrote: > >> int[] arr = [1, 2, 3]; > >> auto r = iota(4, 10); > >> // ??? > >> assert(equal(arr, iota(1, 10))); > >> > >> Hopefully in one GC allocation (assuming we know the range's > >> length). > >> > >> I tried std.range.primitives.put but its behavior seems a little > >> mysterious: > >> > >> This compiles but asserts at runtime: > >> > >> int[] arr = [1, 2, 3]; > >> arr.put(iota(4, 10)); > >> > >> And this is even weirder, can you guess what it will print? > >> > >> int[] arr = [1, 2, 3]; > >> arr.put(4); > >> writeln(arr); > > > > For better or worse, put does not append to arrays. It fills them. If you > > want to append using put, then using std.array.Appender. > > Yes, think of an array as a buffer. When you put into it, you are > overwriting the contents. > > In addition to using Appender (which BTW will add an allocation), you > can extend the array and then fill the extended slice: > > auto oldlen = arr.length; > arr.length += someRange.length; > put(arr[oldlen..$], someRange); > > I wish there was a shorter way to do this...
Honestly, I think that output ranges need at least a minor redesign. They haven't been used as heavily as input ranges and really aren't ironed out as well. A prime example of this is that output ranges assume that put will succeed, and there's no way to even ask how much room an output range has left or whether a call to put will succeed or not. The current state of things works reasonably well with Appender, but it's abysmal if you're dealing with arrays. - Jonathan M Davis