CTFE implementation

John C johnch_atms at hotmail.com
Fri Feb 8 11:22:46 PST 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.


More information about the Digitalmars-d-learn mailing list