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









BCS <ao pathlink.com> 