How to correctly handle immutable ranges
Peter Alexander
peter.alexander.au at gmail.com
Mon Dec 31 06:58:02 PST 2012
On Monday, 31 December 2012 at 14:24:53 UTC, monarch_dodra wrote:
> The same can't be said about ranges: a "immutable(Range!T)"
> might not safely copyable as a "Range!(immutable(T))"
Hmm, are you sure? Can you give an example? Surely if Range is a
struct and everything is copied then it can all change from
mutable to immutable (using a postblit where necessary).
Maybe we just need copy constructors for this to work around the
const issue with postblit.
> 3. No idea.
There is one way you could work around it in a generic manner,
but involves a bit of boilerplate:
auto iterable(R)(R r)
{
struct Iterable
{
this(R range) { _range = range; }
static if (isInputRange!R)
{
alias _range this;
alias _range result;
}
else static if (isRandomAccess!R && hasLength!R && hasSlicing!R)
{
@property auto front() { return _range[_index]; }
@property bool empty() const { return _index == _range.length;
}
void popFront() { ++_index; }
@property auto save() { return this; }
@property R result() { return _range[_index..$]; }
private size_t _index = 0;
}
private R _range;
}
return Iterable(r);
}
You just have to use iterable everywhere instead of the range,
and then use .result to get back to the original range type. e.g.
RoR findSubrange(RoR, R)(RoR ror, R r)
{
auto _ror = iterable(ror);
auto _r = iterable(r);
for (; !_ror.empty; _ror.popFront())
if (equal(iterable(_ror.front), _r))
break;
return _ror.result;
}
Warning: code is totally untested, but should give the gist of
the idea.
> That said, some might question the entire concept of an
> "immutable range". a "range of immutables" makes sense, the
> other way around: less so (IMO).
I kind of agree, but unfortunately immutable arrays are iterable,
and arrays are the most common range, so we really need to
support them.
More information about the Digitalmars-d
mailing list