www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template question

reply akcom <CppCoder gmail.com> writes:
I am translating a C macro I use while manipulating PE files, it has the 
following definition:

#define incptr( Ptr, Increment, CastType ) (CastType *)( (unsigned 
long)(Ptr) + (unsigned long)(Increment) )

I thought using templates would be best, so I came up with the following:

template IncPtr( Ptr:Ptr *, int Increment, T )
{
	const IncPtr = cast(T *)( cast(uint)Ptr + Increment );
}

unfortunately, when I try to use it with something like the following...
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeaders;

ntHeaders = IncPtr!( dosHeader, dosHeader.e_lfanew, IMAGE_NT_HEADERS );

I get the following compilation errors:
pefile.d(194): template instance IncPtr!(dosHeader,incr,ImageNtHeaders ) 
does not match any template declaration
pefile.d(194): voids have no value
pefile.d(194): cannot implicitly convert expression 
(IncPtr!(dosHeader,incr,Imag
eNtHeaders )) of type void to ImageNtHeaders *

any ideas?
May 31 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 31 May 2006 19:55:40 -0400, akcom <CppCoder gmail.com> wrote:
 I am translating a C macro I use while manipulating PE files, it has the  
 following definition:

 #define incptr( Ptr, Increment, CastType ) (CastType *)( (unsigned  
 long)(Ptr) + (unsigned long)(Increment) )

 I thought using templates would be best, so I came up with the following:

 template IncPtr( Ptr:Ptr *, int Increment, T )
 {
 	const IncPtr = cast(T *)( cast(uint)Ptr + Increment );
 }

 unfortunately, when I try to use it with something like the following...
 IMAGE_DOS_HEADER *dosHeader;
 IMAGE_NT_HEADERS *ntHeaders;

 ntHeaders = IncPtr!( dosHeader, dosHeader.e_lfanew, IMAGE_NT_HEADERS );

 I get the following compilation errors:
 pefile.d(194): template instance IncPtr!(dosHeader,incr,ImageNtHeaders )  
 does not match any template declaration
 pefile.d(194): voids have no value
 pefile.d(194): cannot implicitly convert expression  
 (IncPtr!(dosHeader,incr,Imag
 eNtHeaders )) of type void to ImageNtHeaders *

 any ideas?
I'd probably do it like this: typedef int IMAGE_DOS_HEADER; typedef int IMAGE_NT_HEADERS; template IncPtr(T){ T* IncPtr(T* Ptr, int Increment) { return cast(T*)(cast(ubyte*)Ptr + Increment); }} void main() { IMAGE_NT_HEADERS* a; IMAGE_DOS_HEADER* b; b = cast(IMAGE_DOS_HEADER*)IncPtr(a,5); } Notes: A template function is used. I'm hoping it gets inlined. cast(byte*) is used instead of cast(uint); on 64 bit systems, do pointers fit into a uint? The resulting type is not included in the IncPtr template, I prefer to do it explicitly. This allows implicit template argument deduction to function and it just seems more natural/correct to me. Regan
May 31 2006
parent akcom <CppCoder gmail.com> writes:
Regan Heath wrote:
 On Wed, 31 May 2006 19:55:40 -0400, akcom <CppCoder gmail.com> wrote:
 I am translating a C macro I use while manipulating PE files, it has 
 the following definition:

 #define incptr( Ptr, Increment, CastType ) (CastType *)( (unsigned 
 long)(Ptr) + (unsigned long)(Increment) )

 I thought using templates would be best, so I came up with the following:

 template IncPtr( Ptr:Ptr *, int Increment, T )
 {
     const IncPtr = cast(T *)( cast(uint)Ptr + Increment );
 }

 unfortunately, when I try to use it with something like the following...
 IMAGE_DOS_HEADER *dosHeader;
 IMAGE_NT_HEADERS *ntHeaders;

 ntHeaders = IncPtr!( dosHeader, dosHeader.e_lfanew, IMAGE_NT_HEADERS );

 I get the following compilation errors:
 pefile.d(194): template instance IncPtr!(dosHeader,incr,ImageNtHeaders 
 ) does not match any template declaration
 pefile.d(194): voids have no value
 pefile.d(194): cannot implicitly convert expression 
 (IncPtr!(dosHeader,incr,Imag
 eNtHeaders )) of type void to ImageNtHeaders *

 any ideas?
I'd probably do it like this: typedef int IMAGE_DOS_HEADER; typedef int IMAGE_NT_HEADERS; template IncPtr(T){ T* IncPtr(T* Ptr, int Increment) { return cast(T*)(cast(ubyte*)Ptr + Increment); }} void main() { IMAGE_NT_HEADERS* a; IMAGE_DOS_HEADER* b; b = cast(IMAGE_DOS_HEADER*)IncPtr(a,5); } Notes: A template function is used. I'm hoping it gets inlined. cast(byte*) is used instead of cast(uint); on 64 bit systems, do pointers fit into a uint? The resulting type is not included in the IncPtr template, I prefer to do it explicitly. This allows implicit template argument deduction to function and it just seems more natural/correct to me. Regan
Thank you very much for your help
May 31 2006