digitalmars.D - Built-in arrays as output ranges
- Steve Teale (9/9) Feb 07 2010 Not a bug, but would it be reasonable to expand a little on the document...
- Andrei Alexandrescu (13/25) Feb 07 2010 Right. Speaking of which, I think it's sensible to always leave the test
- Steve Teale (14/22) Feb 07 2010 Actually, thinking about this overnight, I'm a bit unhappy about giving
- Andrei Alexandrescu (4/30) Feb 08 2010 copy(source, target) does make sense for arrays as output ranges. Since
Not a bug, but would it be reasonable to expand a little on the documentation
for an output range, perhaps along the lines:
r.put(e) puts e in the range (in a range-dependent manner) and advances to the
popFront position in the range. Successive calls to r.put add elements to the
range. put may throw to signal failure.
When using a built-in array as an output range, to do anything useful it is
necessary to take a reference to the original array before using put. The
original array will be nibbled away by put operations (see std.array). For
example:
int[] a = [ 1,2,3 ];
int[] b = a;
a.put(-a[0]);
a.put(-a[0]);
writefln("([%s] [%s]", b, a);
// [ -1, -2, 3] [ 3 ]
Feb 07 2010
Steve Teale wrote:
Not a bug, but would it be reasonable to expand a little on the documentation
for an output range, perhaps along the lines:
r.put(e) puts e in the range (in a range-dependent manner) and advances to the
popFront position in the range. Successive calls to r.put add elements to the
range. put may throw to signal failure.
When using a built-in array as an output range, to do anything useful it is
necessary to take a reference to the original array before using put. The
original array will be nibbled away by put operations (see std.array). For
example:
int[] a = [ 1,2,3 ];
int[] b = a;
a.put(-a[0]);
a.put(-a[0]);
writefln("([%s] [%s]", b, a);
// [ -1, -2, 3] [ 3 ]
Right. Speaking of which, I think it's sensible to always leave the test
for empty range in, even in release unsafe builds.
void put(T, E)(ref T[] range, E element) if (!isSomeString!(T[]))
{
enforce(!range.empty, "Attempting to put in an empty array");
*range.ptr = element;
range.popFront();
}
enforce() will never be disabled.
As an aside, I just realized I haven't implemented put for strings yet,
and also that I'd promised a check in this weekend.
Andrei
Feb 07 2010
enforce() will never be disabled. As an aside, I just realized I haven't implemented put for strings yet, and also that I'd promised a check in this weekend. AndreiActually, thinking about this overnight, I'm a bit unhappy about giving the impression that a built-in array can serve as an output range. It really isn't true unless you never want to see the output again. If you do, some data structure is required, either a loose combination of an array and an unprotected reference to its original state (arrays a and b), or something more explicit like: struct arrayOutputRange(T) { T[] array; uint pos; this(uint sx) { ... } void put(T val) { ... } } Steve
Feb 07 2010
Steve Teale wrote:copy(source, target) does make sense for arrays as output ranges. Since target is passed by value, your copy will see what's been copied. Andreienforce() will never be disabled. As an aside, I just realized I haven't implemented put for strings yet, and also that I'd promised a check in this weekend. AndreiActually, thinking about this overnight, I'm a bit unhappy about giving the impression that a built-in array can serve as an output range. It really isn't true unless you never want to see the output again. If you do, some data structure is required, either a loose combination of an array and an unprotected reference to its original state (arrays a and b), or something more explicit like: struct arrayOutputRange(T) { T[] array; uint pos; this(uint sx) { ... } void put(T val) { ... } } Steve
Feb 08 2010








Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>