Type-Strict Indexes: IndexedBy

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Feb 17 07:02:04 PST 2015


On Tuesday, 17 February 2015 at 13:38:41 UTC, Per Nordlöw wrote:
> This looses most of the meaning of my idea. I still want my 
> range to inherit all the powers of its wrapped range.
>
> Is there no way to disable member functions in D?

I hadn't thought of @disable. Played around with it a bit. The 
following code seems to work. I didn't really test it or think 
very hard about it, though.

Regarding opIndexAssign: Without it, alias this jumps in on 
assignments, and the ref opIndex is not considered. This may be a 
compiler bug.

Be aware that with alias this, IndexedBy!(R, I) implicitly 
converts to R. So it's easy to (accidentally) fall back to a 
plain R, where nothing is `@disable`d. I don't know if this is 
desirable or not.

----
struct Ix(T = size_t)
{
     @safe pure: @nogc nothrow:
     this(T ix) { this._ix = ix; }
     alias _ix this;
     private T _ix = 0;
}

struct IndexedBy(R, I)
{
     auto ref opIndex(I ix) inout { return _r[ix]; }
     void opIndexAssign(V)(V value, I ix) {_r[ix] = value;}
     alias RI = size_t; /* TODO: Extract this from R somehow. */
     static if(!is(RI == I))
     {
         @disable void opIndex(RI i);
         @disable void opIndexAssign(V)(V value, RI i);
     }
     R _r;
     alias _r this;
}

auto indexedBy(I, R)(R range)
{
     return IndexedBy!(R, I)(range);
}

unittest
{
     import std.stdio;
     auto x = [1, 2, 3];
     alias I = int;
     auto ix = x.indexedBy!I;
     ix[0] = 11;

     alias J = Ix!size_t;
     auto jx = x.indexedBy!J;
     jx[J(0)] = 11;
     static assert(!__traits(compiles, (jx[0] = 11)));
}
----


More information about the Digitalmars-d-learn mailing list