Thread overview
Is this a bug?
Apr 11, 2006
Li Jie
Apr 12, 2006
Li Jie
Apr 12, 2006
David L. Davis
Apr 12, 2006
Li Jie
Apr 14, 2006
David L. Davis
Apr 15, 2006
Li Jie
Apr 14, 2006
Thomas Kuehne
Apr 15, 2006
Walter Bright
April 11, 2006
Code:

template test(char[] str)
{
const char test = test1!(str[0]);  // #LINE 87
}

template test1(char c)
{
const char test1 = c;
}

void main()
{
writefln(test!("a")); // #LINE 105
}


Compile error(dmd 0.150 and dmd 0.153):

testcom.d(87): str is used as a type
testcom.d(87): template instance test1!(void[0]) does not match any template
declaration
testcom.d(87): cannot implicitly convert expression (test1!(void[0])) of type
void to char
testcom.d(105): template instance testcom.test!("a") error instantiating



This is no error:

template test(char[] str)
{
const char test = test1!(str);  // #LINE 87
}

template test1(char[] c)
{
const char test1 = c[0];
}

void main()
{
writefln(test!("a")); // #LINE 105
}


Thanks,

- Li Jie


April 12, 2006
In article <e1fa64$17nq$1@digitaldaemon.com>, Li Jie says...
>
>Code:
>
>template test(char[] str)
>{
>const char test = test1!(str[0]);  // #LINE 87
>}
>
>template test1(char c)
>{
>const char test1 = c;
>}

Modify "test1!(str[0])" to "test1!((str[0]))" can solve the problem.


April 12, 2006
In article <e1hm4c$l39$1@digitaldaemon.com>, Li Jie says...
>
>In article <e1fa64$17nq$1@digitaldaemon.com>, Li Jie says...
>>
>>Code:
>>
>>template test(char[] str)
>>{
>>const char test = test1!(str[0]);  // #LINE 87
>>}
>>
>>template test1(char c)
>>{
>>const char test1 = c;
>>}
>
>Modify "test1!(str[0])" to "test1!((str[0]))" can solve the problem.
>
>

Li Jie, I don't think it's a bug. Below is some code I pull together that I think is sort of what you were trying to do (just remove the '#' characters from the code, they're only there for holding the formating). But I could be wrong...it has happen before. ;)

# // Template Test1
# // temptest1.d - dmd v0.153 WinXP SP2
# // To compiled: C:\dmd>dmd temptest1.d
# private import std.stdio;
#
# template testT(T : char[])
# {
#     char[] value(in char[] T)
#     {
#         writefln("Called testT(T=\"%s\" : char[]).value
#                   alias Test(in char[])", T);
#         return T;
#     }
# }
#
# template testT(T : char)
# {
#     char value(in char T)
#     {
#         writefln("Called testT(T='%s' : char).value alias Test(in char)", T);
#         return T;
#     }
# }
#
# alias testT!(char).value   Test;
# alias testT!(char[]).value Test;
#
# int main()
# {
#     const char[] s = "ABC";
#     writefln("const char[] s = \"%s\"", s);
#     writefln("Test(s[0])='%s', Test(s)=\"%s\"", Test(s[0]), Test(s));
#     return 0;
# }

Output:
----------
C:\dmd>dmd temptest1.d
C:\dmd\bin\..\..\dm\bin\link.exe temptest1,,,user32+kernel32/noi;

C:\dmd>temptest1
const char[] s = "ABC"
Called testT(T="ABC" : char[]).value alias Test(in char[])
Called testT(T='A' : char).value alias Test(in char)
Test(s[0])='A', Test(s)="ABC"

C:\dmd>


David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
-------------------------------------------------------------------

MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html
April 12, 2006
In article <e1hqph$q8g$1@digitaldaemon.com>, David L. Davis says...
>Li Jie, I don't think it's a bug. Below is some code I pull together that I think is sort of what you were trying to do (just remove the '#' characters from the code, they're only there for holding the formating). But I could be wrong...it has happen before. ;)

Thanks David.

Your code is function call, my code is value-parameter template.

I want to write a "__uuidof" template, like VC++. A simple implemention is:

# template __uuidof(T:IUnknown)
# {
#     IID __uuidof = {0x00000000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x46]};
# }

It's too long.

I think the D-template can calculate it from a string, at compile-time. I write some code:

# template HexStrToUbyte(char[] str)
# {
#     const ubyte HexStrToUbyte = cast(ubyte)HexStrToUlong!(str);
# }
#
# template HexStrToUshort(char[] str)
# {
#     const ushort HexStrToUshort = cast(ushort)HexStrToUlong!(str);
# }
#
# template HexStrToUint(char[] str)
# {
#     const uint HexStrToUint = cast(uint)HexStrToUlong!(str);
# }
#
# template HexStrToUlong(char[] s)
# {
#     static if (s.length == 1)
#         const ulong HexStrToUlong = HexToUbyte_bug!((s[0]));
#     else
#         const ulong HexStrToUlong
#             = HexToUbyte_bug!((s[length-1]))
#               + 16 * HexStrToUlong!(s[0..length-1]);
# }
#
# template HexToUbyte(char[] c)
# {
#     static if (c[0] >= '0' && c[0] <= '9')
#         const ubyte HexToUbyte = c[0] - '0';
#     else static if (c[0] == 'A' || c[0] == 'a')
#         const ubyte HexToUbyte = 0xa;
#     else static if (c[0] == 'B' || c[0] == 'b')
#         const ubyte HexToUbyte = 0xb;
#     else static if (c[0] == 'C' || c[0] == 'c')
#         const ubyte HexToUbyte = 0xc;
#     else static if (c[0] == 'D' || c[0] == 'd')
#         const ubyte HexToUbyte = 0xd;
#     else static if (c[0] == 'E' || c[0] == 'e')
#         const ubyte HexToUbyte = 0xe;
#     else static if (c[0] == 'F' || c[0] == 'f')
#         const ubyte HexToUbyte = 0xf;
# }
#
# template HexToUbyte_bug(char c)
# {
#     static if (c >= '0' && c <= '9')
#         const ubyte HexToUbyte_bug = c - '0';
#     else static if (c == 'A' || c == 'a')
#         const ubyte HexToUbyte_bug = 0xa;
#     else static if (c == 'B' || c == 'b')
#         const ubyte HexToUbyte_bug = 0xb;
#     else static if (c == 'C' || c == 'c')
#         const ubyte HexToUbyte_bug = 0xc;
#     else static if (c == 'D' || c == 'd')
#         const ubyte HexToUbyte_bug = 0xd;
#     else static if (c == 'E' || c == 'e')
#         const ubyte HexToUbyte_bug = 0xe;
#     else static if (c == 'F' || c == 'f')
#         const ubyte HexToUbyte_bug = 0xf;
# }
#
# template IIDFromStr(char[] str)
# {
#     const IID IIDFromStr = {
#         HexStrToUint!(str[0..8]),
#         HexStrToUshort!(str[9..13]),
#         HexStrToUshort!(str[14..18]),
#         [
#           HexStrToUbyte!(str[19..21]),
#           HexStrToUbyte!(str[21..23]),
#           HexStrToUbyte!(str[24..26]),
#           HexStrToUbyte!(str[26..28]),
#           HexStrToUbyte!(str[28..30]),
#           HexStrToUbyte!(str[30..32]),
#           HexStrToUbyte!(str[32..34]),
#           HexStrToUbyte!(str[34..36])
#         ]
#     };
# }
#
# template __uuidof(T:IUnknown)
# {
#     IID __uuidof = IIDFromStr!("00000000-0000-0000-C000-000000000046");
# }
#
# template __uuidof(T:IClassFactory)
# {
#     IID __uuidof = IIDFromStr!("00000001-0000-0000-C000-000000000046");
# }
#
#
# void main()
# {
#     IID iu  = __uuidof!(IUnknown);
#     IID icp = __uuidof!(IClassFactory);
#
#     writefln(iu.Data1);
#     writefln(iu.Data2);
#     writefln(iu.Data3);
#     writefln(iu.Data4);
# }


IIDFromStr!("00000000-0000-0000-C000-000000000046");
and
{0x00000000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x46]};

I like the first.


April 14, 2006
Li Jie schrieb am 2006-04-12:
> In article <e1fa64$17nq$1@digitaldaemon.com>, Li Jie says...
>>
>>Code:
>>
>>template test(char[] str)
>>{
>>const char test = test1!(str[0]);  // #LINE 87
>>}
>>
>>template test1(char c)
>>{
>>const char test1 = c;
>>}
>
> Modify "test1!(str[0])" to "test1!((str[0]))" can solve the problem.

Added to DStress as http://dstress.kuehne.cn/compile/t/template_35_A.d http://dstress.kuehne.cn/compile/t/template_35_B.d http://dstress.kuehne.cn/compile/t/template_35_C.d

Thomas



April 14, 2006
In article <e1hvg6$vqj$1@digitaldaemon.com>, Li Jie says...
>
>In article <e1hqph$q8g$1@digitaldaemon.com>, David L. Davis says...
>>Li Jie, I don't think it's a bug. Below is some code I pull together that I think is sort of what you were trying to do (just remove the '#' characters from the code, they're only there for holding the formating). But I could be wrong...it has happen before. ;)
>
>Thanks David.
>
>Your code is function call, my code is value-parameter template.
>
>I want to write a "__uuidof" template, like VC++. A simple implemention is:
>
># template __uuidof(T:IUnknown)
># {
>#     IID __uuidof = {0x00000000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00,
>0x00, 0x00, 0x00, 0x46]};
># }
>
>It's too long.
>
>
>IIDFromStr!("00000000-0000-0000-C000-000000000046");
>and
>{0x00000000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>0x46]};
>
>I like the first.
>

Li Jie, I'm still not sure I see the problem...but it looks like your code should compile and work fine in D. (I made a few changes, but nothing major)

# // Li Jie's uui.d - tested WinXP SP1 D v0.154
# // To Compiled: dmd uui.d ole32.lib uuid.lib
# private import std.stdio;
# private import std.c.windows.com;
#
# template HexStrToUbyte(wchar[] ws)
# {
#     const ubyte HexStrToUbyte = cast(ubyte)HexStrToUlong!(ws);
# }
#
# template HexStrToUshort(wchar[] ws)
# {
#     const ushort HexStrToUshort = cast(ushort)HexStrToUlong!(ws);
# }
#
# template HexStrToUint(wchar[] ws)
# {
#     const uint HexStrToUint = cast(uint)HexStrToUlong!(ws);
# }
#
# template HexStrToUlong(wchar[] ws)
# {
#     static if (ws.length == 1)
#         const ulong HexStrToUlong = HexToUbyte_bug!((ws[0]));
#     else
#         const ulong HexStrToUlong
#             = HexToUbyte_bug!((ws[length-1]))
#               + 16 * HexStrToUlong!(ws[0..length-1]);
# }
#
# template HexToUbyte(wchar[] wc)
# {
#     static if (wc[0] >= '0' && wc[0] <= '9')
#         const ubyte HexToUbyte = wc[0] - '0';
#     else static if (wc[0] == 'A' || wc[0] == 'a')
#         const ubyte HexToUbyte = 0xa;
#     else static if (wc[0] == 'B' || wc[0] == 'b')
#         const ubyte HexToUbyte = 0xb;
#     else static if (wc[0] == 'C' || wc[0] == 'c')
#         const ubyte HexToUbyte = 0xc;
#     else static if (wc[0] == 'D' || wc[0] == 'd')
#         const ubyte HexToUbyte = 0xd;
#     else static if (wc[0] == 'E' || wc[0] == 'e')
#         const ubyte HexToUbyte = 0xe;
#     else static if (wc[0] == 'F' || wc[0] == 'f')
#         const ubyte HexToUbyte = 0xf;
# }
#
# template HexToUbyte_bug(wchar wc)
# {
#     static if (wc >= '0' && wc <= '9')
#         const ubyte HexToUbyte_bug = wc - '0';
#     else static if (wc == 'A' || wc == 'a')
#         const ubyte HexToUbyte_bug = 0xa;
#     else static if (wc == 'B' || wc == 'b')
#         const ubyte HexToUbyte_bug = 0xb;
#     else static if (wc == 'C' || wc == 'c')
#         const ubyte HexToUbyte_bug = 0xc;
#     else static if (wc == 'D' || wc == 'd')
#         const ubyte HexToUbyte_bug = 0xd;
#     else static if (wc == 'E' || wc == 'e')
#         const ubyte HexToUbyte_bug = 0xe;
#     else static if (wc == 'F' || wc == 'f')
#         const ubyte HexToUbyte_bug = 0xf;
# }
#
# template IIDFromStr(wchar[] ws)
# {
#     const IID IIDFromStr = {
#         HexStrToUint!(ws[0..8]),
#         HexStrToUshort!(ws[9..13]),
#         HexStrToUshort!(ws[14..18]),
#         [
#           HexStrToUbyte!(ws[19..21]),
#           HexStrToUbyte!(ws[21..23]),
#           HexStrToUbyte!(ws[24..26]),
#           HexStrToUbyte!(ws[26..28]),
#           HexStrToUbyte!(ws[28..30]),
#           HexStrToUbyte!(ws[30..32]),
#           HexStrToUbyte!(ws[32..34]),
#           HexStrToUbyte!(ws[34..36])
#         ]
#     };
# }
#
# template __uuidof(T:IUnknown)
# {
#     IID __uuidof = IIDFromStr!("00000000-0000-0000-C000-000000000046");
# }
#
# template __uuidof(T:IClassFactory)
# {
#     IID __uuidof = IIDFromStr!("00000001-0000-0000-C000-000000000046");
# }
#
# char[] toString(in IID udtGUID)
# {
#     wchar[ 39 ] wsGUID = '\0';
#     char[]      sGUID2 = "";
#
#     StringFromGUID2( &udtGUID, wsGUID, 39 );
#
#     for ( int ix = 0; ix < wsGUID.length - 1; ix++ )
#     {
#         //writefln( "wsGUID[ %d ] = %s", ix, wsGUID[ ix ] );
#         sGUID2 ~= wsGUID[ ix ];
#     }
#
#     return sGUID2;
# }
#
# void main()
# {
#     IID iu  = __uuidof!(IUnknown);
#     IID icp = __uuidof!(IClassFactory);
#
#     writef("{%08s, ", iu.Data1);
#     writef("%04s, ", iu.Data2);
#     writef("%04s, ", iu.Data3);
#     writefln("%s}", iu.Data4);
#
#     writefln("toString(iu)=", toString(iu));
#     writefln("IIDFromStr!(\"00000000-0000-0000-C000-000000000046\")=\"%s\"",
#              toString(IIDFromStr!("00000000-0000-0000-C000-000000000046")));
# }

Output:
C:\dmd>dmd uui.d ole32.lib uuid.lib
C:\dmd\bin\..\..\dm\bin\link.exe uui,,,ole32.lib+uuid.lib+user32+kernel32/noi;

C:\dmd>uui
{00000000, 0000, 0000, [192,0,0,0,0,0,0,70]}
toString(iu)={00000000-0000-0000-C000-000000000046}
IIDFromStr!("00000000-0000-0000-C000-000000000046")="{00000000-0000-0000-C000-000000000046}"

C:\dmd>

David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
-------------------------------------------------------------------

MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html
April 15, 2006
In article <e1ooai$2tp4$1@digitaldaemon.com>, David L. Davis says...
>Li Jie, I'm still not sure I see the problem...but it looks like your code should compile and work fine in D. (I made a few changes, but nothing major)

Yes, it works find. But it must call like this:
# HexToUbyte_bug!((ws[0])); // work find
# HexToUbyte_bug!(ws[0]); // compile error


April 15, 2006
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Li Jie schrieb am 2006-04-12:
>> In article <e1fa64$17nq$1@digitaldaemon.com>, Li Jie says...
>>> Code:
>>>
>>> template test(char[] str)
>>> {
>>> const char test = test1!(str[0]);  // #LINE 87
>>> }
>>>
>>> template test1(char c)
>>> {
>>> const char test1 = c;
>>> }
>> Modify "test1!(str[0])" to "test1!((str[0]))" can solve the problem.
> 
> Added to DStress as
> http://dstress.kuehne.cn/compile/t/template_35_A.d
> http://dstress.kuehne.cn/compile/t/template_35_B.d
> http://dstress.kuehne.cn/compile/t/template_35_C.d

This is a known issue - a template argument that looks like a type is treated as a type.