Thread overview | |||||
---|---|---|---|---|---|
|
May 31, 2006 template question | ||||
---|---|---|---|---|
| ||||
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? |
June 01, 2006 Re: template question | ||||
---|---|---|---|---|
| ||||
Posted in reply to akcom | 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 |
June 01, 2006 Re: template question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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
|
Copyright © 1999-2021 by the D Language Foundation