Bug 13409 – std.range.padLeft/Right

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-08-31T20:15:00Z
Last change time
2016-03-24T19:56:27Z
Keywords
pull
Assigned to
nobody
Creator
peter.alexander.au
Depends on
15236

Comments

Comment #0 by peter.alexander.au — 2014-08-31T20:15:44Z
Would be useful to have two new higher-order ranges in std.range: padLeft(R, E)(R r, E e, size_t n) if (isInputRange!R && hasLength!R && !is(CommonType!(ElementType!R, E) == void)) padRight(R, E)(R r, E e, size_t n) is (isInputRange!R && !is(CommonType!(ElementType!R, E) == void)) padLeft returns a range that is padded on the left up to 'n' elements with 'e', and padRight pads on the right. Example: int[] a = [1, 2, 3]; padLeft(a, 0, 5) == [0, 0, 1, 2, 3] padRight(a, 0, 5) == [1, 2, 3, 0, 0] Notes: * If r.length >= n then neither add any padding, and just iterates r. * padLeft requires hasLength, but padRight does not. * If R is forward, then so will padLeft/Right * If R is bidirectional, and hasLength, then so will padLeft/Right * If R is random access, and hasLength, then so will padLeft/Right * If R is infinite, padLeft/Right will return r and be type R.
Comment #1 by monarchdodra — 2014-08-31T21:01:19Z
Is there a use case for this outside of string formatting? Also, does it justify having a new range, when the same end result could be had with chain and repeat? auto padLeft(R, E)(R r, E e, size_t n) { return chain(repeat(e, n > r.length ? n - r : 0), r) } For padLeft, I'm making the assumption that r is random access. If we want to accept forward range (input is not possible), then we have to use r.save.walkLength(), presuming the extra complexity is acceptable. The only case where your proposal could make sense, is for padRight on a pure input range (no length, no save). But that's one hell of a particular case...
Comment #2 by peter.alexander.au — 2014-08-31T21:32:49Z
(In reply to monarchdodra from comment #1) > Is there a use case for this outside of string formatting? I need it for padding data buffers out. > Also, does it justify having a new range, when the same end result could be > had with chain and repeat? I think it is justified. When using chain/repeat, it isn't immediately clear what you are doing, whereas padLeft/Right are self documenting. If I needed to do this, I would create padLeft/Right myself as separate functions to make it clear. If people are going to do this then it might as well be in Phobos, in my opinion. Also, padRight with an input range without length cannot be implemented in terms of other ranges, I think (not easily anyway). I actually only need padRight, but I feel padLeft should exist for symmetry. > For padLeft, I'm making the assumption that r is random access. If we want > to accept forward range (input is not possible), then we have to use > r.save.walkLength(), presuming the extra complexity is acceptable. > > The only case where your proposal could make sense, is for padRight on a > pure input range (no length, no save). But that's one hell of a particular > case... Random access is unnecessary. You only need hasLength + input range (see proposal). Incidentally, these kind of subtleties are a good reason why Phobos should provide them instead of relying on users to do so. The case for input range with no length for padRight is actually exactly what prompted me to create this. I'm generating some data of unknown length (it is lazily generated) that I want to copy into a pre-sized buffer, and then fill the rest of the buffer with 0's.
Comment #3 by jack — 2015-10-23T14:01:06Z
Comment #4 by github-bugzilla — 2016-03-24T19:56:26Z