immutable range
Steven Schveighoffer
schveiguy at yahoo.com
Mon Oct 17 05:29:18 PDT 2011
On Sun, 16 Oct 2011 07:37:03 -0400, kenji hara <k.hara.pg at gmail.com> wrote:
> I got an idea.
>
> import std.range;
>
> template isImmutableInputRange(R)
> {
> enum bool isImmutableInputRange = is(typeof(
> {
> R r; // can define a range object
> if (r.empty) {} // can test for empty
> auto r2 = r.nextFront(); // can invoke nextFront()
> auto h = r2.front; // can get the front of the range
> }));
> }
>
> template isImmutableForwardRange(R)
> {
> enum bool isImmutableForwardRange = isImmutableInputRange!R &&
> is(typeof(
> {
> R r1;
> R r2 = r1.save; // can call "save" against a range object
> }));
> }
>
> template isImmutableBidirectionalRange(R)
> {
> enum bool isImmutableBidirectionalRange = isImmutableForwardRange!R
> && is(typeof(R.init.back()) == typeof(R.init.front()))
> && is(typeof({ R r; auto r2 = r.nextBack(); }));
> }
>
> void immutableForeach(R, E)(R r, scope void delegate(E) dg)
> if (isImmutableInputRange!R && is(ElementType!R : E))
> {
> if (r.empty)
> return;
> dg(r.front);
> immutableForeach(r.nextFront(), dg); // tail recursion
> }
> void immutableForeachReverse(R, E)(R r, scope void delegate(E) dg)
> if (isImmutableBidirectionalRange!R && is(ElementType!R : E))
> {
> if (r.empty)
> return;
> dg(r.back);
> immutableForeachReverse(r.nextBack(), dg); // tail recursion
> }
>
> const struct Range
> {
> int[] arr;
>
> @property int front() const { return arr[0]; }
> @property bool empty() const { return arr.length > 0; }
> const(Range) nextFront() const { return Range(arr[1..$]); }
>
> const(Range) save() const { return this; }
>
> @property int back() const { return arr[$-1]; }
> const(Range) nextBack() { return Range(arr[0..$-1]); }
> }
>
> static assert(isImmutableInputRange!Range);
> static assert(isImmutableForwardRange!Range);
> static assert(isImmutableBidirectionalRange!Range);
>
> void main()
> {
> const r = Range([1,2,3]);
>
> int i = 0;
> immutableForeach(r, (int v)
> {
> assert(v == ++i);
> });
>
> int j = 3;
> immutableForeachReverse(r, (int v)
> {
> assert(v == j--);
> });
> }
>
> Kenji Hara
I don't think this scales well. Not only are you introducing a new type
of range, you are introducing a new *class* of range. One which does not
work with any existing algorithms.
The solution must be compatible with all the existing range functions
(which do not modify data), or it doesn't work.
-Steve
More information about the Digitalmars-d
mailing list