Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 08, 2008 CTFE implementation | ||||
---|---|---|---|---|
| ||||
I want to initialize constant GUID structure instanzes in D1. This is part of doing a port, so i want to keep most of the original code unchanged. In Java: public static const GUID IIDJavaBeansBridge = IIDFromString("{8AD9C840-044E-11D1-B3E9-00805F499D93}"); This is in Java no problem, IIDFromString is executed at startup. In D i could change it too this: public static const GUID IIDJavaBeansBridge = { 0x8AD9C840, 0x044E, 0x11D1, [0xB3, 0xE9, 0x00, 0x80, 0x5F, 0x49, 0x9D, 0x93]}; This compiles, but there are many of these GUID constants and for later merges and diffs, i really would like to keep the Java form. So i thought CTFE might do the trick. // struct GUID { // size is 16 // align(1): // DWORD Data1; // WORD Data2; // WORD Data3; // BYTE[8] Data4; // } int HexToInt( char[] str ){ uint i = 0; foreach( c; str ){ i <<= 4; int v = -1; if( c >= 'A' && c <= 'F' ){ v = c - 'A' + 10; } else if( c >= '0' && c <= '9' ){ v = c - '0'; } assert( v >= 0 && v < 16, "for "~str~" char "~c ); i |= v; } return i; } private static GUID IIDFromString( char[] str ){ assert( str.length is 38 ); assert( str[0] is '{' ); assert( str[9] is '-' ); assert( str[14] is '-' ); assert( str[19] is '-' ); assert( str[24] is '-' ); assert( str[37] is '}' ); GUID res; res.Data1 = HexToInt( str[1 .. 9] ); res.Data2 = HexToInt( str[10 .. 14] ); res.Data3 = HexToInt( str[15 .. 19] ); //res.Data4[0] = HexToInt( str[20 .. 22] ); //res.Data4[1] = HexToInt( str[22 .. 24] ); //for( int i = 0; i < 5; i++ ){ // res.Data4[i+2] = HexToInt( str[25+2*i .. 25+2*i] ); //} return res; } This works for the member Data1, Data2, Data3. But not for the Data4 member, which is a static array. Uncommenting those lines yield the "cannot evaluate at compile time" error. I tried to do a union, also without luck. Does someone have a solution for this? |
February 08, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit schrieb: > I want to initialize constant GUID structure instanzes in D1. This is part of doing a port, so i want to keep most of the original code unchanged. > > In Java: > public static const GUID IIDJavaBeansBridge = IIDFromString("{8AD9C840-044E-11D1-B3E9-00805F499D93}"); > > This is in Java no problem, IIDFromString is executed at startup. Why not using a module constructor module dwx.guid; static this() { // all GUID init stuff (*IIDFromString ) goes here } ... I am very afraid I miss something. so it's just an idea. |
February 08, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bjoern | Bjoern schrieb:
> I am very afraid I miss something. so it's just an idea.
Because then i need to have the constant declaration/initialization split into two different places.
I just wonder if it could be done in a nice way with CTFE. Then a diff-tool could find matching lines by comparing the java and the ported version.
|
February 08, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit wrote: > I want to initialize constant GUID structure instanzes in D1. This is part of doing a port, so i want to keep most of the original code unchanged. > > In Java: > public static const GUID IIDJavaBeansBridge = IIDFromString("{8AD9C840-044E-11D1-B3E9-00805F499D93}"); > > This is in Java no problem, IIDFromString is executed at startup. > In D i could change it too this: > public static const GUID IIDJavaBeansBridge = { 0x8AD9C840, 0x044E, 0x11D1, [0xB3, 0xE9, 0x00, 0x80, 0x5F, 0x49, 0x9D, 0x93]}; > > This compiles, but there are many of these GUID constants and for later merges and diffs, i really would like to keep the Java form. So i thought CTFE might do the trick. > > // struct GUID { // size is 16 > // align(1): > // DWORD Data1; > // WORD Data2; > // WORD Data3; > // BYTE[8] Data4; > // } > > int HexToInt( char[] str ){ > uint i = 0; > foreach( c; str ){ > i <<= 4; > int v = -1; > if( c >= 'A' && c <= 'F' ){ > v = c - 'A' + 10; > } > else if( c >= '0' && c <= '9' ){ > v = c - '0'; > } > assert( v >= 0 && v < 16, "for "~str~" char "~c ); > i |= v; > } > return i; > } > > private static GUID IIDFromString( char[] str ){ > assert( str.length is 38 ); > assert( str[0] is '{' ); > assert( str[9] is '-' ); > assert( str[14] is '-' ); > assert( str[19] is '-' ); > assert( str[24] is '-' ); > assert( str[37] is '}' ); > GUID res; > res.Data1 = HexToInt( str[1 .. 9] ); > res.Data2 = HexToInt( str[10 .. 14] ); > res.Data3 = HexToInt( str[15 .. 19] ); > //res.Data4[0] = HexToInt( str[20 .. 22] ); > //res.Data4[1] = HexToInt( str[22 .. 24] ); > //for( int i = 0; i < 5; i++ ){ > // res.Data4[i+2] = HexToInt( str[25+2*i .. 25+2*i] ); > //} > return res; > } > > This works for the member Data1, Data2, Data3. But not for the Data4 member, which is a static array. Uncommenting those lines yield the "cannot evaluate at compile time" error. > > I tried to do a union, also without luck. > > Does someone have a solution for this? > > > > This is what I use: template defIID(string g) { static if (g.length == 38) const GUID defIID = defIID!(g[1..$-1]); else static if (g.length == 36) const GUID defIID = { mixin("0x" ~ g[0..8]), mixin("0x" ~ g[9..13]), mixin("0x" ~ g[14..18]), [ mixin("0x" ~ g[19..21]), mixin("0x" ~ g[21..23]), mixin("0x" ~ g[24..26]), mixin("0x" ~ g[26..28]), mixin("0x" ~ g[28..30]), mixin("0x" ~ g[30..32]), mixin("0x" ~ g[32..34]), mixin("0x" ~ g[34..36]) ] }; else static assert(false, "Incorrect format for GUID."); } const GUID IIDJavaBeansBridge = defIID!("{8AD9C840-044E-11D1-B3E9-00805F499D93}"); John. |
February 08, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | "Frank Benoit" <keinfarbton@googlemail.com> wrote in message news:foi6sn$1kb4$1@digitalmars.com... > Does someone have a solution for this? private template IIDFromString(char[] str) { static assert(str.length is 38); static assert(str[0] is '{'); static assert(str[9] is '-'); static assert(str[14] is '-'); static assert(str[19] is '-'); static assert(str[24] is '-'); static assert(str[37] is '}'); const GUID IIDFromString = { Data1: HexToInt(str[1 .. 9]), Data2: HexToInt(str[10 .. 14]), Data3: HexToInt(str[15 .. 19]), Data4: [ HexToInt(str[20 .. 22]), HexToInt(str[22 .. 24]), HexToInt(str[25 .. 27]), HexToInt(str[27 .. 29]), HexToInt(str[29 .. 31]), HexToInt(str[31 .. 33]), HexToInt(str[33 .. 35]), HexToInt(str[35 .. 37]) ] }; } const IIDJavaBeansBridge = IIDFromString!("{8AD9C840-044E-11D1-B3E9-00805F499D93}"); CTFE is terribly buggy, I tend to stay away from it as much as I can. |
February 08, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Reply to Frank,
> Bjoern schrieb:
>
>> I am very afraid I miss something. so it's just an idea.
>>
> Because then i need to have the constant declaration/initialization
> split into two different places.
> I just wonder if it could be done in a nice way with CTFE. Then a
> diff-tool could find matching lines by comparing the java and the
> ported
> version.
have you considered a template?
template GUID(char[GUID_LEN] str)
{
const GUID_str GUID = ....;
}
|
February 08, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Thanks all the answers. Using template/mixin works. Is the my not working example a showcase for a bug, or should it behave like this? |
February 09, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | "Frank Benoit" <keinfarbton@googlemail.com> wrote in message news:foign0$288v$1@digitalmars.com... > Thanks all the answers. > Using template/mixin works. > > Is the my not working example a showcase for a bug, or should it behave like this? It's probably a bug, but it might already have been reported, and a bug in CTFE is kind of like saying a bee in a bee hive. I think that portion of the frontend just needs to be rewritten from scratch, since I wonder if it's really within reason to fix it. |
February 11, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit wrote:
> I want to initialize constant GUID structure instanzes in D1. This is part of doing a port, so i want to keep most of the original code unchanged.
>
> In Java:
> public static const GUID IIDJavaBeansBridge = IIDFromString("{8AD9C840-044E-11D1-B3E9-00805F499D93}");
>
> This is in Java no problem, IIDFromString is executed at startup.
> In D i could change it too this:
> public static const GUID IIDJavaBeansBridge = { 0x8AD9C840, 0x044E, 0x11D1, [0xB3, 0xE9, 0x00, 0x80, 0x5F, 0x49, 0x9D, 0x93]};
>
> This compiles, but there are many of these GUID constants and for later merges and diffs, i really would like to keep the Java form. So i thought CTFE might do the trick.
>
> // struct GUID { // size is 16
> // align(1):
> // DWORD Data1;
> // WORD Data2;
> // WORD Data3;
> // BYTE[8] Data4;
> // }
>
> int HexToInt( char[] str ){
> uint i = 0;
> foreach( c; str ){
> i <<= 4;
> int v = -1;
> if( c >= 'A' && c <= 'F' ){
> v = c - 'A' + 10;
> }
> else if( c >= '0' && c <= '9' ){
> v = c - '0';
> }
> assert( v >= 0 && v < 16, "for "~str~" char "~c );
> i |= v;
> }
> return i;
> }
>
> private static GUID IIDFromString( char[] str ){
> assert( str.length is 38 );
> assert( str[0] is '{' );
> assert( str[9] is '-' );
> assert( str[14] is '-' );
> assert( str[19] is '-' );
> assert( str[24] is '-' );
> assert( str[37] is '}' );
> GUID res;
> res.Data1 = HexToInt( str[1 .. 9] );
> res.Data2 = HexToInt( str[10 .. 14] );
> res.Data3 = HexToInt( str[15 .. 19] );
> //res.Data4[0] = HexToInt( str[20 .. 22] );
> //res.Data4[1] = HexToInt( str[22 .. 24] );
> //for( int i = 0; i < 5; i++ ){
> // res.Data4[i+2] = HexToInt( str[25+2*i .. 25+2*i] );
> //}
> return res;
> }
>
> This works for the member Data1, Data2, Data3. But not for the Data4 member, which is a static array. Uncommenting those lines yield the "cannot evaluate at compile time" error.
>
> I tried to do a union, also without luck.
>
> Does someone have a solution for this?
Looks like a CTFE bug.
Try creating the GUID struct in place, that often works better.
return GUID(HexToInt( str[1 .. 9] ), ...
[HexToInt( str[25+2*0 .. 25+2*0], ...
,HexToInt( str[25+2*5 .. 25+2*5]] );
|
February 11, 2008 Re: CTFE implementation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | Don Clugston schrieb:
> Looks like a CTFE bug.
> Try creating the GUID struct in place, that often works better.
>
> return GUID(HexToInt( str[1 .. 9] ), ...
> [HexToInt( str[25+2*0 .. 25+2*0], ...
> ,HexToInt( str[25+2*5 .. 25+2*5]] );
I tried this without luck:
struct __GUID{
static __GUID opCall( uint Data1_, ushort Data2_, ushort Data3_, ubyte[8] Data4_ ){
__GUID s;
s.Data1 = Data1_;
s.Data2 = Data2_;
s.Data3 = Data3_;
s.Data4[0..8] = Data4_[0..8];
return s;
}
align(1):
uint Data1;
ushort Data2;
ushort Data3;
ubyte[8] Data4;
}
alias __GUID GUID;
GUID IIDFromString(char[] d) {
return GUID(1,2,3,[0,1,2,3,4,5,6,7]);
}
|
Copyright © 1999-2021 by the D Language Foundation