Thread overview
std.traits.ReturnType b0rking on function pointer.
Jan 17, 2007
Daniel Keep
Jan 17, 2007
Kirk McDonald
Jan 17, 2007
Daniel Keep
Jan 17, 2007
Kirk McDonald
Jan 18, 2007
Daniel Keep
January 17, 2007
Hey there, I'm having problems with getting the return type of a function pointer.  Basically, I want to do this:

template SDL_SafeCall(alias tFn)
{
    ReturnType!(SDL_SetVideoMode) SDL_SafeCall(...)
    {
        ...
    }
}
SDL_SafeCall!(SDL_SetVideoMode)(...);

where SDL_SetVideoMode is declared like so (yes, it's DerelictSDL):

typedef SDL_Surface* function(int,int,int,Uint32) pfSDL_SetVideoMode;
pfSDL_SetVideoMode          SDL_SetVideoMode;

When I try to compile my code, I get the following errors:

C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating

I've tried writing my own version, but that didn't do any better. Anyone have any ideas?

	-- Daniel
January 17, 2007
Daniel Keep wrote:
> 
> Hey there, I'm having problems with getting the return type of a function pointer.  Basically, I want to do this:
> 
> template SDL_SafeCall(alias tFn)
> {
>     ReturnType!(SDL_SetVideoMode) SDL_SafeCall(...)
>     {
>         ...
>     }
> }
> SDL_SafeCall!(SDL_SetVideoMode)(...);
> 
> where SDL_SetVideoMode is declared like so (yes, it's DerelictSDL):
> 
> typedef SDL_Surface* function(int,int,int,Uint32) pfSDL_SetVideoMode;
> pfSDL_SetVideoMode          SDL_SetVideoMode;
> 
> When I try to compile my code, I get the following errors:
> 
> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
> 
> I've tried writing my own version, but that didn't do any better. Anyone have any ideas?
> 
>     -- Daniel

ReturnType has two forms: One which is intended to operate on a function pointer or delegate /type/, and one which is intended to operate on a function alias.

SDL_SetVideoMode is a function pointer. You want to pass its /type/ to ReturnType. By passing it directly, it gets sent to the alias form of ReturnType, which confuses it greatly. Try this:

ReturnType!(typeof(SDL_SetVideoMode))

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
January 17, 2007
Kirk McDonald wrote:
> Daniel Keep wrote:
> 
>>
>> Hey there, I'm having problems with getting the return type of a function pointer.  Basically, I want to do this:
>>
>> template SDL_SafeCall(alias tFn)
>> {
>>     ReturnType!(SDL_SetVideoMode) SDL_SafeCall(...)
>>     {
>>         ...
>>     }
>> }
>> SDL_SafeCall!(SDL_SetVideoMode)(...);
>>
>> where SDL_SetVideoMode is declared like so (yes, it's DerelictSDL):
>>
>> typedef SDL_Surface* function(int,int,int,Uint32) pfSDL_SetVideoMode;
>> pfSDL_SetVideoMode          SDL_SetVideoMode;
>>
>> When I try to compile my code, I get the following errors:
>>
>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
>>
>> I've tried writing my own version, but that didn't do any better. Anyone have any ideas?
>>
>>     -- Daniel
> 
> 
> ReturnType has two forms: One which is intended to operate on a function pointer or delegate /type/, and one which is intended to operate on a function alias.
> 
> SDL_SetVideoMode is a function pointer. You want to pass its /type/ to ReturnType. By passing it directly, it gets sent to the alias form of ReturnType, which confuses it greatly. Try this:
> 
> ReturnType!(typeof(SDL_SetVideoMode))
> 

template SDL_Refcall(alias tFn)
{ // line 57
    ReturnType!(typeof(tFn)) SDL_Refcall(tArgs...)(tArgs args)
    {
        ReturnType!(typeof(tFn)) r = tFn(args);
        if( r is null )
            throw new SDLException(tFn.nameof, 0);
        else
            return r;
    }
}

SDL_Refcall!(SDL_SetVideoMode)(...);

No good.

C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
C:\Daniel\dmd\dmd\src\phobos\std\traits.d(58): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
src\engine\shared_sdl\shared_sdl.d(58): Error: ReturnType!(pfSDL_SetVideoMode) is used as a type
January 17, 2007
Daniel Keep wrote:
> Kirk McDonald wrote:
> 
>> Daniel Keep wrote:
>>
>>>
>>> Hey there, I'm having problems with getting the return type of a function pointer.  Basically, I want to do this:
>>>
>>> template SDL_SafeCall(alias tFn)
>>> {
>>>     ReturnType!(SDL_SetVideoMode) SDL_SafeCall(...)
>>>     {
>>>         ...
>>>     }
>>> }
>>> SDL_SafeCall!(SDL_SetVideoMode)(...);
>>>
>>> where SDL_SetVideoMode is declared like so (yes, it's DerelictSDL):
>>>
>>> typedef SDL_Surface* function(int,int,int,Uint32) pfSDL_SetVideoMode;
>>> pfSDL_SetVideoMode          SDL_SetVideoMode;
>>>
>>> When I try to compile my code, I get the following errors:
>>>
>>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
>>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
>>>
>>> I've tried writing my own version, but that didn't do any better. Anyone have any ideas?
>>>
>>>     -- Daniel
>>
>>
>>
>> ReturnType has two forms: One which is intended to operate on a function pointer or delegate /type/, and one which is intended to operate on a function alias.
>>
>> SDL_SetVideoMode is a function pointer. You want to pass its /type/ to ReturnType. By passing it directly, it gets sent to the alias form of ReturnType, which confuses it greatly. Try this:
>>
>> ReturnType!(typeof(SDL_SetVideoMode))
>>
> 
> template SDL_Refcall(alias tFn)
> { // line 57
>     ReturnType!(typeof(tFn)) SDL_Refcall(tArgs...)(tArgs args)
>     {
>         ReturnType!(typeof(tFn)) r = tFn(args);
>         if( r is null )
>             throw new SDLException(tFn.nameof, 0);
>         else
>             return r;
>     }
> }
> 
> SDL_Refcall!(SDL_SetVideoMode)(...);
> 
> No good.
> 
> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(58): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
> src\engine\shared_sdl\shared_sdl.d(58): Error: ReturnType!(pfSDL_SetVideoMode) is used as a type

I have two thoughts:

pfSDL_SetVideoMode is declared as a typedef. Maybe try it as an alias? ReturnType just uses the "return" TypeSpecialization in the IsExpression, which might get confused by typedefs. (I have not tested this.)

Second, you are passing in a (global?) variable as a template alias parameter. While this is technically allowed, I have had nothing but grief doing that sort of thing. I suggest re-writing it as:

ReturnType!(fn_t) SDL_Refcall(fn_t, tArgs ...) (fn_t fn, tArgs args) {
    // stuff...
}

And then calling it as a regular function template:

SDL_Refcall(SDL_SetVideoMode, ...);

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
January 18, 2007
Kirk McDonald wrote:
> Daniel Keep wrote:
> 
>> Kirk McDonald wrote:
>>
>>> Daniel Keep wrote:
>>>
>>>>
>>>> Hey there, I'm having problems with getting the return type of a function pointer.  Basically, I want to do this:
>>>>
>>>> template SDL_SafeCall(alias tFn)
>>>> {
>>>>     ReturnType!(SDL_SetVideoMode) SDL_SafeCall(...)
>>>>     {
>>>>         ...
>>>>     }
>>>> }
>>>> SDL_SafeCall!(SDL_SetVideoMode)(...);
>>>>
>>>> where SDL_SetVideoMode is declared like so (yes, it's DerelictSDL):
>>>>
>>>> typedef SDL_Surface* function(int,int,int,Uint32) pfSDL_SetVideoMode;
>>>> pfSDL_SetVideoMode          SDL_SetVideoMode;
>>>>
>>>> When I try to compile my code, I get the following errors:
>>>>
>>>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
>>>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
>>>>
>>>> I've tried writing my own version, but that didn't do any better. Anyone have any ideas?
>>>>
>>>>     -- Daniel
>>>
>>>
>>>
>>>
>>> ReturnType has two forms: One which is intended to operate on a function pointer or delegate /type/, and one which is intended to operate on a function alias.
>>>
>>> SDL_SetVideoMode is a function pointer. You want to pass its /type/ to ReturnType. By passing it directly, it gets sent to the alias form of ReturnType, which confuses it greatly. Try this:
>>>
>>> ReturnType!(typeof(SDL_SetVideoMode))
>>>
>>
>> template SDL_Refcall(alias tFn)
>> { // line 57
>>     ReturnType!(typeof(tFn)) SDL_Refcall(tArgs...)(tArgs args)
>>     {
>>         ReturnType!(typeof(tFn)) r = tFn(args);
>>         if( r is null )
>>             throw new SDLException(tFn.nameof, 0);
>>         else
>>             return r;
>>     }
>> }
>>
>> SDL_Refcall!(SDL_SetVideoMode)(...);
>>
>> No good.
>>
>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias declaration
>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(58): template instance std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
>> src\engine\shared_sdl\shared_sdl.d(58): Error: ReturnType!(pfSDL_SetVideoMode) is used as a type
> 
> 
> I have two thoughts:
> 
> pfSDL_SetVideoMode is declared as a typedef. Maybe try it as an alias? ReturnType just uses the "return" TypeSpecialization in the IsExpression, which might get confused by typedefs. (I have not tested this.)

Well, since I'm using Derelict, there isn't a huge amount I can do... ok; I *could* go and change all instances of 'typedef' to 'alias'... might actually do that and see what happens (but I'd prefer to stick to an unmodified version if at all possible).

> Second, you are passing in a (global?) variable as a template alias parameter. While this is technically allowed, I have had nothing but grief doing that sort of thing. I suggest re-writing it as:
> 
> ReturnType!(fn_t) SDL_Refcall(fn_t, tArgs ...) (fn_t fn, tArgs args) {
>     // stuff...
> }
> 
> And then calling it as a regular function template:
> 
> SDL_Refcall(SDL_SetVideoMode, ...);
> 

Aww... but the old way was so much purtier...

Anyway, I'll give these a try once I've sufficiently woken up, and let you know how it goes.

	-- Daniel