Thread overview
[Issue 5390] New: Make it possible to test whether a type is an instantiation of a particular template
Dec 29, 2010
Jonathan M Davis
Dec 30, 2010
Andrej Mitrovic
Dec 30, 2010
Michal Minich
December 29, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5390

           Summary: Make it possible to test whether a type is an
                    instantiation of a particular template
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: jmdavisProg@gmx.com


--- Comment #0 from Jonathan M Davis <jmdavisProg@gmx.com> 2010-12-29 15:10:35 PST ---
I'm marking this as dmd, because I don't think that it's currently possible to do this with the language as-is - I think that __traits needs to be updated. But if there _is_ a way to do this as-is, then it should probably be a Phobos issue for std.traits.

In any case, what one thing that I'm seeing people ask for is the ability to ask in a template constraint whether a type is an instantiation of a particular template. e.g.

struct A(T)
{
}

struct B(T)
    if(is(T : A))
{
}

Of course, this particular syntax doesn't work, but it's the kind of thing that some folks are trying. They want a way to test whether T is A!(any type whatsoever). As far as I can determine, there is _no_ generic way to do this. You can do stuff like

struct B(T, U)
    if(is(T == A!U) && isIntegral!U)
{
}

but you generally have to find some way to either get the template constraint to give you the value for U so that you can test that T is an instantiation of A!U, or you have add some kind of flag or variable to the type that you test to see whether it exists on the type that you're testing. Ideally, you'd be able to do something like

struct B(T)
    if(__traits(instantiatedFrom, T, A))
{}

or

struct B(T)
    if(instantiationOf(T, A))
{
}

There is not currently any such trait in __traits or std.traits, and as far as I can determine, one cannot be built from the current building blocks. I expect that a change will be have to made to __traits on the compiler side of things to make such a test possible. But regardless of what changes would or wouldn't have to be made to make such a test possible, _having_ such a test seems to definitely be something that some folks are looking for. I know that I would find it useful, and we really should have a straightforward way of doing such tests.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5390


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-12-29 17:44:29 PST ---
The only thing I can think of would be using strings and mixins, but this would look really bad and would essentially be just a hack.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5390


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #2 from bearophile_hugs@eml.cc 2010-12-29 22:42:39 PST ---
See also issue 5361

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5390


Michal Minich <michal.minich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |michal.minich@gmail.com


--- Comment #3 from Michal Minich <michal.minich@gmail.com> 2010-12-30 12:32:30 PST ---
This works:

import std.stdio;

class Dict (K, V) {}

void main () {
    Dict!(string, int) dict;
    Foo (dict);
}

template Foo (C : T!(P1, P2), alias T, P1, P2)
{
    void Foo (C container)
    {
        writeln(C.stringof);  // Dict
        writeln(T.stringof);  // Dict(K, V)
        writeln(P1.stringof); // string
        writeln(P2.stringof); // int
    }
}

Unfortunately it seems not to work with variadic templates, so overloads for parameter P# need to be created currently, to make it practically generic. If needed, this template can be called recursively in case P# is template instance.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------