Thread overview
Class Array in D?
Nov 20, 2013
Jeroen Bollen
Nov 20, 2013
Ali Çehreli
Nov 20, 2013
Jeroen Bollen
Nov 20, 2013
Adam D. Ruppe
November 20, 2013
is there a way I can pass a TypeTulip to a function?
Something like:

Can I create a class array in D? Something like:

interface A {}
class AA: A {}
class AB: A {}
class AC: A {}

ClassList!A list = new ClassList!A {AA, AB, AC};

void testf(ulong testv) {
    A a = new list[testv];
}

I know about TypeTuple but that doesn't allow setting a requirement does it?
November 20, 2013
On 11/20/2013 10:12 AM, Jeroen Bollen wrote:

> is there a way I can pass a TypeTulip to a function?

alias TypeTulip = TypeTuple;

;)

> Something like:
>
> Can I create a class array in D? Something like:
>
> interface A {}
> class AA: A {}
> class AB: A {}
> class AC: A {}
>
> ClassList!A list = new ClassList!A {AA, AB, AC};
>
> void testf(ulong testv) {
>      A a = new list[testv];
> }
>
> I know about TypeTuple but that doesn't allow setting a requirement does
> it?

import std.stdio;
import std.typetuple;

interface A {}
class AA: A {}
class AB: A {}
class AC: A {}

alias TypeTulip = TypeTuple;
alias list = TypeTuple!(AA, AB, AC);

void testf(ulong testv) {
    // NOTE: This is a compile-time foreach
    foreach (i, Type; list) {
        if (i == testv) {
            A a = new Type();
            writefln("I made it: %s", a);
        }
    }
}

void main()
{
    testf(1);
}

Note that the foreach loop above is not a loop that gets executed at run time. Its body is expanded inline as code multiple times as needed. I try to explain this a little under the "Compile-time foreach" and "foreach with TypeTuple" sections here:

  http://ddili.org/ders/d.en/tuples.html

Ali

November 20, 2013
On Wednesday, 20 November 2013 at 18:23:37 UTC, Ali Çehreli wrote:
> On 11/20/2013 10:12 AM, Jeroen Bollen wrote:
>
> > is there a way I can pass a TypeTulip to a function?
>
> alias TypeTulip = TypeTuple;
>
> ;)
>
> > Something like:
> >
> > Can I create a class array in D? Something like:
> >
> > interface A {}
> > class AA: A {}
> > class AB: A {}
> > class AC: A {}
> >
> > ClassList!A list = new ClassList!A {AA, AB, AC};
> >
> > void testf(ulong testv) {
> >      A a = new list[testv];
> > }
> >
> > I know about TypeTuple but that doesn't allow setting a
> requirement does
> > it?
>
> import std.stdio;
> import std.typetuple;
>
> interface A {}
> class AA: A {}
> class AB: A {}
> class AC: A {}
>
> alias TypeTulip = TypeTuple;
> alias list = TypeTuple!(AA, AB, AC);
>
> void testf(ulong testv) {
>     // NOTE: This is a compile-time foreach
>     foreach (i, Type; list) {
>         if (i == testv) {
>             A a = new Type();
>             writefln("I made it: %s", a);
>         }
>     }
> }
>
> void main()
> {
>     testf(1);
> }
>
> Note that the foreach loop above is not a loop that gets executed at run time. Its body is expanded inline as code multiple times as needed. I try to explain this a little under the "Compile-time foreach" and "foreach with TypeTuple" sections here:
>
>   http://ddili.org/ders/d.en/tuples.html
>
> Ali

That doesn't allow specifying a base class all members should be a part of though, or does it?
November 20, 2013
On Wednesday, 20 November 2013 at 18:31:37 UTC, Jeroen Bollen wrote:
> That doesn't allow specifying a base class all members should be a part of though, or does it?

You could write your own tuple template for it, or just let the compile fail on the factory function: the A a = new T(); will fail if A isn't a base class or interface of T.

Putting the check in the list could look like this:

bool checkClassList(Base, T...)() {
   foreach(t; T) {
     static if(!is(t : Base))
         static assert(0, t.stringof ~ " is not a child of " ~ Base.stringof);
   }
   return true;
}

template ClassList(Base, T...) if(checkClassList!(Base, T)) {
    alias ClassList = T;
}


Usage:

alias list = ClassList!(A, AA, AB, AC); // good


add:

class B {}
alias list = ClassList!(A, AA, AB, AC, B);

and get error:

test50.d(12): Error: static assert  "B is not a child of A"
test50.d(19):        instantiated from here: checkClassList!(A, AA, AB, AC, B)