A problem with AAs

bearophile bearophileHUGS at lycos.com
Thu Jan 24 03:09:14 PST 2008


Sometimes it can be useful a function that returns a light iterable that yields the keys or values of an AA, so such iterable can be given to templated functions that blindly iterate on their input using a foreach. So I've tried to create an xvalues (and xkeys) iterable, like this:

Xvalues!(TK, TV) xvalues(TK, TV)(TV[TK] aa) {
  return new Xvalues!(TK, TV)(aa);
}

class Xvalues(TK, TV) {
  TV[TK] aa;
  this(TV[TK] aa) { this.aa = aa; }

  int opApply(int delegate(ref TV) dg) {
    int result;
    foreach(val; aa) {
      result = dg(val);
      if (result) break;
    }
    return result;
  }
}

void main() {
  xvalues(["ab":"AB"]);
}


But as you probably know that doesn't work, it gives:
xtest.d(10): Error: cannot have out or ref parameter of type char[2u]
xtest.d(1): template instance xtest.Xvalues!(char[2u],char[2u]) error instantiating

So far the only way I have found to solve that is something like this:

template IsArray(T) {
    const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) &&
                         is(typeof(T.reverse)) && is(typeof(T.dup));
}

template ArrayType1(T: T[]) {
    alias T ArrayType1;
}

template DeconstArrType(T) {
    static if (IsArray!(T))
        alias ArrayType1!(T)[] DeconstArrType;
    else
        alias T DeconstArrType;
}

class Xvalues(TK, TV) {
  TV[TK] aa;
  alias DeconstArrType!(TV) TyItem;
  this(TV[TK] aa) { this.aa = aa; }

  int opApply(int delegate(ref TyItem) dg) {
    int result;
    foreach(val; aa.values) {
      TyItem item = val;
      result = dg(item);
      if (result) break;
    }
    return result;
  }
}

But I can't accept that because it changes the type of the values (from a static to a dynamic array). (If this problem can't be solved then I think I'll just restrict the xvalues/xkeys to AAs that don't have static arrays as keys/values).

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list