Jump to page: 1 2
Thread overview
Type-Strict Indexes: IndexedBy
Feb 16, 2015
Nordlöw
Feb 16, 2015
Nordlöw
Feb 16, 2015
anonymous
Feb 16, 2015
Nordlöw
Feb 16, 2015
Nordlöw
Feb 16, 2015
Nordlöw
Feb 17, 2015
Per Nordlöw
Feb 17, 2015
anonymous
Feb 17, 2015
Nordlöw
Feb 18, 2015
anonymous
Feb 18, 2015
Nordlöw
Feb 18, 2015
Tobias Pankrath
Feb 16, 2015
Tobias Pankrath
February 16, 2015
I'm trying to figure out how to implement a light-weight wrappr realizing type-safe indexing á lá Ada. Here's my first try:

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]; }
    auto ref opSlice(I lower, I upper) inout { return _r[lower .. upper]; }
    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;              // should compile
    jx[0] = 11;                 // TODO how can I make this not compile?
}

My question now of course is:

How can I prevent

    jx[0] = 11;

from compiling?
February 16, 2015
On Monday, 16 February 2015 at 20:09:09 UTC, Nordlöw wrote:
> I'm trying to figure out how to implement a light-weight wrappr realizing type-safe indexing á lá Ada. Here's my first try:

See also: https://github.com/nordlow/justd/blob/master/typecons_ex.d#L83
February 16, 2015
On Monday, 16 February 2015 at 20:09:09 UTC, Nordlöw wrote:
> How can I prevent
>
>     jx[0] = 11;
>
> from compiling?

Remove that `alias _r this;`. You don't want to forward opIndex, so you can't use alias this which forwards everything that doesn't compile. opDispatch may be an option to forward everything but opIndex.
February 16, 2015
On Monday, 16 February 2015 at 20:09:09 UTC, Nordlöw wrote:
> I'm trying to figure out how to implement a light-weight wrappr realizing type-safe indexing á lá Ada. Here's my first try:
>
> 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]; }
>     auto ref opSlice(I lower, I upper) inout { return _r[lower .. upper]; }
>     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;              // should compile
>     jx[0] = 11;                 // TODO how can I make this not compile?
> }
>
> My question now of course is:
>
> How can I prevent
>
>     jx[0] = 11;
>
> from compiling?

Did you actually try that? This does not compile because of c[13]

struct IndexT
{
        this(size_t s) { x = s; }
        size_t x;
}

struct Container
{
        int opIndex(IndexT i) { return 12; }
}

void main()
{
        auto it = IndexT(13);
        Container c;
        c[it];
        c[13];
}

February 16, 2015
On Monday, 16 February 2015 at 20:17:55 UTC, anonymous wrote:
> Remove that `alias _r this;`. You don't want to forward opIndex, so you can't use alias this which forwards everything that doesn't compile. opDispatch may be an option to forward everything but opIndex.

Thanks!
February 16, 2015
On Monday, 16 February 2015 at 20:48:29 UTC, Nordlöw wrote:
> Thanks!

See also: http://forum.dlang.org/thread/akibggljgcmmacsbahmm@forum.dlang.org
February 16, 2015
On Monday, 16 February 2015 at 20:17:55 UTC, anonymous wrote:
> that doesn't compile. opDispatch may be an option to forward everything but opIndex.

What about disable?
February 17, 2015
On Monday, 16 February 2015 at 20:17:55 UTC, anonymous wrote:
> Remove that `alias _r this;`. You don't want to forward opIndex, so you can't use alias this which forwards everything that doesn't compile. opDispatch may be an option to forward everything but opIndex.

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?
February 17, 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)));
}
----
February 17, 2015
On Tuesday, 17 February 2015 at 15:02:05 UTC, anonymous wrote:
> 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.

Superb! I'd like to see this getting into std.typecons.

Having this in the language will attract (more) Ada programmers to D.

Should I do PR for std.typecons.[iI]ndexedBy?
« First   ‹ Prev
1 2