Search code examples
templatesconstraintsd

Check if a type is an instantiation of a template


I have structs like


struct RGBA (T) {/* ... */}
struct BMPFile (DataT) if (is(DataT == RGBA)) {/* ... */}

But is(DataT == RGBA) cannot work because DataT is a type and RGBA is a template. Instead I need check if a type is an instantiation of a template in order to declare file like


BMPFile!(RGBA!ushort) file;

In a comment @FeepingCreature showed


    struct RGBA(T) {
        alias void isRGBAStruct;
    }
    struct BMPFile (DataT) if (is(DataT.isRGBAStruct)) {}

Although to be working I have no tips on alias void isRGBAStruct, that seems a hack. Hopefully std.traits will cover this.


Solution

  • I think you're trying to be over-specific. The way I would handle this is to allow any type for DataT, so long as it implements whatever interface I need.

    The way this is done in the D2 standard library, I believe, is to have templates like IsIntegral that test various properties of a type.

    For example, let's say your requirement for DataT is that you can finangle it. You might write:

    template IsAppropriate(DataT)
    {
        enum IsAppropriate = is(typeof( { DataT d; d.finangle(); }() ));
    }
    

    Take the above with a grain of salt: I haven't tested it, but I believe that's the basic pattern. If you aren't familiar with the above, what it's doing is checking to see if the given anonymous function compiles; it can only compile if it's possible to finangle the DataT.