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