www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12484] New: Template Overloading or Pattern Matching Failure

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12484

           Summary: Template Overloading or Pattern Matching Failure
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: monkeyworks12 hotmail.com


--- Comment #0 from monkeyworks12 hotmail.com 2014-03-27 15:28:24 PDT ---
I'm not sure which is failing here, but this doesn't work (and I'm pretty sure
it should).

struct Zero    {}
struct Succ(a) {}

alias One = Succ!Zero;

struct Less    {}
struct Equal   {}
struct Greater {}

struct Cmp(x: Zero,   y: Zero,      c: Equal)   {}
struct Cmp(x: Zero,   y: Succ!n, n, c: Less)    {}
struct Cmp(x: Succ!n, y: Zero,   n, c: Greater) {}

void main()
{
    assert(is(Cmp!(Zero, Zero, Equal)));   //Ok
    assert(is(Cmp!(Zero, One,  Less)));    //Fails
    assert(is(Cmp!(One,  Zero, Greater))); //Fails
}

The error message given in both cases is:

Error: struct Cmp does not match any template declaration

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 27 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12484


monkeyworks12 hotmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


--- Comment #1 from monkeyworks12 hotmail.com 2014-03-27 15:32:25 PDT ---
And I just realized that the error is mine. The extra n parameter must go at
the end or template inference can't figure it out, of course. This works:

struct Cmp(x: Zero,   y: Succ!n, c: Less,    n) {}
struct Cmp(x: Succ!n, y: Zero,   c: Greater, n) {}


void main()
{
    assert(is(Cmp!(Zero, Zero, Equal)));   //Ok
    assert(is(Cmp!(Zero, One,  Less)));    //Ok
    assert(is(Cmp!(One,  Zero, Greater))); //Ok
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 27 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12484


bearophile_hugs eml.cc changed:

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


--- Comment #2 from bearophile_hugs eml.cc 2014-03-27 16:33:19 PDT ---
(In reply to comment #1)
 And I just realized that the error is mine.

In some cases it's better to ask first in D.learn.
 The extra n parameter must go at
 the end or template inference can't figure it out, of course. This works:
 
 struct Cmp(x: Zero,   y: Succ!n, c: Less,    n) {}
 struct Cmp(x: Succ!n, y: Zero,   c: Greater, n) {}
 
 
 void main()
 {
     assert(is(Cmp!(Zero, Zero, Equal)));   //Ok
     assert(is(Cmp!(Zero, One,  Less)));    //Ok
     assert(is(Cmp!(One,  Zero, Greater))); //Ok
 }

It's better to use static asserts: struct Zero {} struct Succ(a) {} alias One = Succ!Zero; struct Less {} struct Equal {} struct Greater {} enum Cmp(x: Zero, y: Zero, c: Equal) = true; enum Cmp(x: Zero, y: Succ!n, c: Less, n) = true; enum Cmp(x: Succ!n, y: Zero, c: Greater, n) = true; static assert(Cmp!(Zero, Zero, Equal)); static assert(Cmp!(Zero, One, Less)); static assert(Cmp!(One, Zero, Greater)); Also take a look at the new std.traits.TemplateOf and std.traits.TemplateArgsOf (2.066). In D you can compare values with ==, types with is(x == y), and type constructors (all successive ranks) with __traits(isSame, x, y). Also take a look at the new enum/alias short syntax. An alternative implementation mixes types and values (I have had to add a new CMP): struct Zero {} struct Succ(a) {} alias One = Succ!Zero; alias Two = Succ!One; enum CMP { less, equal, greater } enum Cmp(x: Zero, y: Zero, ) = CMP.equal; enum Cmp(x: Zero, y: Succ!n, n ) = CMP.less; enum Cmp(x: Succ!n, y: Zero, n ) = CMP.greater; enum Cmp(x: Succ!n, y: Succ!m, n, m) = Cmp!(n, m); static assert(Cmp!(Zero, Zero) == CMP.equal); static assert(Cmp!(Zero, One) == CMP.less); static assert(Cmp!(One, Zero) == CMP.greater); static assert(Cmp!(One, Two) == CMP.less); -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 27 2014