views:

54

answers:

1

I'd like to be able to create an multidim associative array where one dimension is a class. Like this:

class Node{
    Node[?classType?][string] inputs;
}

so that I later can do

Node[] getInputsOfType(?? aClass){
   if(aClass in this.inputs)
      return this.inputs[aClass];
   else
      return null;
}

// meanwhile in another file...

Node[] effects = someAudioNode.getInputsOfType(AudioEffect);

I'm just lost. Any ideas?
Regarding the last part: Can a class be used as a parameter all by itself like that? (AudioEffect in this example is a class.)

BR

[update/resolution]

Thanks for the answer(s)!

I thought it'd be nice to post the result. Ok, I looked up .classinfo in the source code and found that it returns an instance of TypeInfo_Class, and that there's a .name-property, a string. So this is what I came up with:

#!/usr/bin/env dmd -run
import  std.stdio;
class A{
    int id;
    static int newId;
    A[string][string] list;
    this(){ id = newId++; }
    void add(A a, string name){
        writefln("Adding: [%s][%s]", a.classinfo.name, name);
        list[a.classinfo.name][name] = a;
    }
    T[string] getAllOf(T)(){
        return cast(T[string]) list[T.classinfo.name];
    }
}
class B : A{ }
void main(){
    auto a = new A();
    a.add(new A(), "test");
    a.add(new B(), "bclass");
    a.add(new B(), "bclass2");

    auto myAList = a.getAllOf!(A);
    foreach(key, item; myAList)
        writefln("k: %s, i: %s id: %s",
                key, item.toString(), item.id);

    auto myBList = a.getAllOf!(B);
    foreach(key, item; myBList)
        writefln("k: %s, i: %s id: %s",
                key, item.toString(), item.id);
}

It outputs:

Adding: [classtype.A][test]
Adding: [classtype.B][bclass]
Adding: [classtype.B][bclass2]
Trying to get [classtype.A]
k: test, i: classtype.A id: 1
Trying to get [classtype.B]
k: bclass2, i: classtype.B id: 3
k: bclass, i: classtype.B id: 2

So yeah, I suppose it works. Yey! Anyone has ideas for improvement?

Are there any pitfalls here?

  • Can classinfo.name suddenly behave unexpedictly?
  • Is there a »proper» way of getting the class name?

Also, is this the fastest way of doing it? I mean, all class names seems to start with classtype.. Oh well, that's perhaps another SO-thread. Thanks again!

BR

+3  A: 

You can use the ClassInfo class (accessible through the .classinfo property) to refer to class types at runtime. However, the ClassInfo class doesn't implement the necessary methods to be used in an associative array (see the D reference page on AAs regarding using classes/structs in AAs). I suppose this is possible if you implement your own wrapper for ClassInfo that can be used as an AA key. This should be fairly simple, as you can expect that a class type will have only one ClassInfo instance, thus you can simply use the ClassInfo's address as the unique hash.


By the way, a simpler and faster way to write

if (key in aa)
    return aa[key];
else
    return null;

is

auto pvalue = key in aa;
return pvalue ? *pvalue : null;
CyberShadow
Re each class only having one classinfo: IIRC that might not be true if you are using DLLs or SOs. But in those cases you end up with other problems as well.
BCS
Thanks! I ended up using the `.name`-property in the classinfo, which is just a string, so that was no problem using in an associative array, although it feels like it could be faster. /BR
0scar