digitalmars.D.learn - CTFE implementation
- Frank Benoit (59/59) Feb 08 2008 I want to initialize constant GUID structure instanzes in D1. This is
- Bjoern (9/18) Feb 08 2008 Why not using a module constructor
- Frank Benoit (6/7) Feb 08 2008 Because then i need to have the constant declaration/initialization
- BCS (6/16) Feb 08 2008 have you considered a template?
- John C (17/90) Feb 08 2008 This is what I use:
- Jarrett Billingsley (32/33) Feb 08 2008 private template IIDFromString(char[] str)
- Frank Benoit (4/4) Feb 08 2008 Thanks all the answers.
- Jarrett Billingsley (6/10) Feb 09 2008 It's probably a bug, but it might already have been reported, and a bug ...
- Don Clugston (6/75) Feb 11 2008 Looks like a CTFE bug.
- Frank Benoit (22/28) Feb 11 2008 I tried this without luck:
- Don Clugston (3/36) Feb 11 2008 opCall definitely won't work with CTFE yet. But struct constructors work...
- Don Clugston (19/22) Feb 12 2008 This works. I reduced the size of Data4 bcos I was lazy -- you'll need ...
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?
Feb 08 2008
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.
Feb 08 2008
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.
Feb 08 2008
Reply to Frank,Bjoern schrieb:have you considered a template? template GUID(char[GUID_LEN] str) { const GUID_str GUID = ....; }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.
Feb 08 2008
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.
Feb 08 2008
"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.
Feb 08 2008
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?
Feb 08 2008
"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.
Feb 09 2008
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]] );
Feb 11 2008
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]); }
Feb 11 2008
Frank Benoit wrote:Don Clugston schrieb:opCall definitely won't work with CTFE yet. But struct constructors work in every case I've ever tried.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]); }
Feb 11 2008
Frank Benoit wrote:Don Clugston schrieb:This works. I reduced the size of Data4 bcos I was lazy -- you'll need to add the other 4 members 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 '}' ); return GUID(HexToInt( str[1 .. 9] ), HexToInt( str[10 .. 14] ), HexToInt( str[15 .. 19]), [cast(ubyte)HexToInt( str[20 .. 22] ), HexToInt( str[22 .. 24] ), HexToInt( str[25+2 .. 25+1*2]),HexToInt( str[25+1*2 .. 25+2*2]), // other 4 entries...]); } const GUID IIDJavaBeansBridge = IIDFromString("{8AD9C840-044E-11D1-B3E9-00805F499D93}");Looks like a CTFE bug. Try creating the GUID struct in place, that often works better.
Feb 12 2008