On 04/15/2015 03:42 PM, "Nordlöw" wrote:

> On Wednesday, 15 April 2015 at 20:12:27 UTC, Ali Çehreli wrote:
>> Ali
>
> I cracked it:
>
> Reason: I hade a failing unittest using it as
>
>      auto xs = x.indexedBy!"I";
>
> which I changed to
>
>      auto xs = x.indexedBy!"Ix";
>
> For some reason the mixin magic becomes confused when I equals "I".
>
> Do you have any clues as to why?

That is because you have a nested struct named I inside IndexedBy. :) I print it with pragma(msg) below. So, mixin(I) is not happy because it thinks you mean 'struct I' :)

struct IndexedBy(R, string I = "Index") if (isArray!R)
{
    enum toMixin = q{ struct } ~ I ~
          q{ {
                  alias T = size_t;
                  this(T ix) { this._ix = ix; }
                  T opCast(U : T)() const { return _ix; }
                  private T _ix = 0;
              }
          };
    pragma(msg, toMixin);
    mixin(toMixin);

    mixin genOps!(mixin(I));
    R _r;
alias _r this; // TODO Use opDispatch instead; to override only opSlice and opIndex
}

void main()
{
    auto i = IndexedBy!(int[], "I")();
}

The output:

 struct I {
                  alias T = size_t;
                  this(T ix) { this._ix = ix; }
                  T opCast(U : T)() const { return _ix; }
                  private T _ix = 0;
              }
> Should we restrict IndexedBy to not allow I to equal "I"?

I don't think there is a general solution but you can always disallow as a template constraint or as a static assert:

struct IndexedBy(R, string I = "Index")
    if (isArray!R &&
        I != "I")    // <-- ADDED
{
    // ...
}

>
> :)
>
> Thx anyway.

Ali

Reply via email to