template question

Regan Heath regan at netwin.co.nz
Wed May 31 17:14:12 PDT 2006


On Wed, 31 May 2006 19:55:40 -0400, akcom <CppCoder at 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



More information about the Digitalmars-d-learn mailing list