How to append range to array?

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 24 19:28:04 PDT 2015


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



More information about the Digitalmars-d-learn mailing list