Thread overview
How to send variadic arguments
Aug 25, 2008
Zarathustra
Aug 25, 2008
Zarathustra
Aug 25, 2008
Zarathustra
Aug 26, 2008
Sivo Schilling
August 25, 2008
How to send variadic arguments to other function?

Of course, I can read each argument by using:
_argptr is a pointer to arguments list
_arguments is an array of argument types

But I need to straight send all variadic arguments to other function.

for example:

void func1(char [] o_str, ...){
}
void func2(int o_num, ...){
  func2("func2", /* What here? */)
}

Thanks in advance.
August 25, 2008
"Zarathustra" wrote
> How to send variadic arguments to other function?
>
> Of course, I can read each argument by using:
> _argptr is a pointer to arguments list
> _arguments is an array of argument types
>
> But I need to straight send all variadic arguments to other function.
>
> for example:
>
> void func1(char [] o_str, ...){
> }
> void func2(int o_num, ...){
>  func2("func2", /* What here? */)
> }
>

The way it is done in Tango is to put the implementation in a function which takes the _argptr and _arguments as parameters.  Then the actual variadic function is just a wrapper.  If you want to chain another variadic function to it, just pass the _argptr and _arguments.

Passing the argptr and arguments directly really should be a compiler supported thing, as this is all you are doing anyways.  Similar to how you can call opX directly.

-Steve


August 25, 2008
Steven Schveighoffer Wrote:

> The way it is done in Tango is to put the implementation in a function which takes the _argptr and _arguments as parameters.  Then the actual variadic function is just a wrapper.  If you want to chain another variadic function to it, just pass the _argptr and _arguments.
> 
> Passing the argptr and arguments directly really should be a compiler supported thing, as this is all you are doing anyways.  Similar to how you can call opX directly.
> 
> -Steve
> 
> 
Reply to Steve:

Do you mean something like that?

import tango.io.Stdout;
void func(char[] o_char, ...){
  Stdout(o_char, _arguments, _argptr);
}

public static int
main(){
  int l_result = 0;
  try{
    Stdout("smile", 2, 3, 4).newline;
    func("smile", 2, 3, 4);
  }
  catch(Object o){
    l_result = 1;
    Cout(o.toString);
  }
  return l_result;
}

## result:
smile, 2, 3, 4
smile, [int, int, int], 12fe58

August 25, 2008
"Zarathustra" wrote
> Steven Schveighoffer Wrote:
>
>> The way it is done in Tango is to put the implementation in a function
>> which
>> takes the _argptr and _arguments as parameters.  Then the actual variadic
>> function is just a wrapper.  If you want to chain another variadic
>> function
>> to it, just pass the _argptr and _arguments.
>>
>> Passing the argptr and arguments directly really should be a compiler
>> supported thing, as this is all you are doing anyways.  Similar to how
>> you
>> can call opX directly.
>>
>> -Steve
>>
>>
> Reply to Steve:
>
> Do you mean something like that?
>
> import tango.io.Stdout;
> void func(char[] o_char, ...){
>  Stdout(o_char, _arguments, _argptr);
> }
>
> public static int
> main(){
>  int l_result = 0;
>  try{
>    Stdout("smile", 2, 3, 4).newline;
>    func("smile", 2, 3, 4);
>  }
>  catch(Object o){
>    l_result = 1;
>    Cout(o.toString);
>  }
>  return l_result;
> }
>
> ## result:
> smile, 2, 3, 4
> smile, [int, int, int], 12fe58

It would be nice if something like that was supported, which is what I said in the second paragraph, but what I meant in the first paragraph was something like this (had to dig it up from Tango):

void realfunc1(TypeInfo[] arguments, ArgList args)
{
   // function body here
}

void func1(...)
{
  realfunc1(_arguments, _argptr);
}

void func2(char[] o_char, ...)
{
    func1(o_char);
    realfunc1(_arguments, _argptr);
}

Of course, you have to know the realfunc1 function name, or else have to distinguish the parameters somehow.  Tango's tango.text.convert.Layout has a similar strategy.  There's probably a way to use Stdout to call it the way you want.

-Steve


August 25, 2008
Steven Schveighoffer Wrote:

> "Zarathustra" wrote
> > Steven Schveighoffer Wrote:
> >
> >> The way it is done in Tango is to put the implementation in a function
> >> which
> >> takes the _argptr and _arguments as parameters.  Then the actual variadic
> >> function is just a wrapper.  If you want to chain another variadic
> >> function
> >> to it, just pass the _argptr and _arguments.
> >>
> >> Passing the argptr and arguments directly really should be a compiler
> >> supported thing, as this is all you are doing anyways.  Similar to how
> >> you
> >> can call opX directly.
> >>
> >> -Steve
> >>
> >>
> > Reply to Steve:
> >
> > Do you mean something like that?
> >
> > import tango.io.Stdout;
> > void func(char[] o_char, ...){
> >  Stdout(o_char, _arguments, _argptr);
> > }
> >
> > public static int
> > main(){
> >  int l_result = 0;
> >  try{
> >    Stdout("smile", 2, 3, 4).newline;
> >    func("smile", 2, 3, 4);
> >  }
> >  catch(Object o){
> >    l_result = 1;
> >    Cout(o.toString);
> >  }
> >  return l_result;
> > }
> >
> > ## result:
> > smile, 2, 3, 4
> > smile, [int, int, int], 12fe58
> 
> It would be nice if something like that was supported, which is what I said in the second paragraph, but what I meant in the first paragraph was something like this (had to dig it up from Tango):
> 
> void realfunc1(TypeInfo[] arguments, ArgList args)
> {
>    // function body here
> }
> 
> void func1(...)
> {
>   realfunc1(_arguments, _argptr);
> }
> 
> void func2(char[] o_char, ...)
> {
>     func1(o_char);
>     realfunc1(_arguments, _argptr);
> }
> 
> Of course, you have to know the realfunc1 function name, or else have to distinguish the parameters somehow.  Tango's tango.text.convert.Layout has a similar strategy.  There's probably a way to use Stdout to call it the way you want.
> 
> -Steve
> 
> 
Ok it's good idea but "realfunc" is not my own function, it is library function and this can not be modified.

TResult realFunc(TResult)(char[] name, ...)

August 25, 2008
"Zarathustra" <adam.chrapkowski@gmail.com> wrote in message news:g8unfe$1nv0$1@digitalmars.com...
> Steven Schveighoffer Wrote:
>
>> "Zarathustra" wrote
>> > Steven Schveighoffer Wrote:
>> >
>> >> The way it is done in Tango is to put the implementation in a function
>> >> which
>> >> takes the _argptr and _arguments as parameters.  Then the actual
>> >> variadic
>> >> function is just a wrapper.  If you want to chain another variadic
>> >> function
>> >> to it, just pass the _argptr and _arguments.
>> >>
>> >> Passing the argptr and arguments directly really should be a compiler
>> >> supported thing, as this is all you are doing anyways.  Similar to how
>> >> you
>> >> can call opX directly.
>> >>
>> >> -Steve
>> >>
>> >>
>> > Reply to Steve:
>> >
>> > Do you mean something like that?
>> >
>> > import tango.io.Stdout;
>> > void func(char[] o_char, ...){
>> >  Stdout(o_char, _arguments, _argptr);
>> > }
>> >
>> > public static int
>> > main(){
>> >  int l_result = 0;
>> >  try{
>> >    Stdout("smile", 2, 3, 4).newline;
>> >    func("smile", 2, 3, 4);
>> >  }
>> >  catch(Object o){
>> >    l_result = 1;
>> >    Cout(o.toString);
>> >  }
>> >  return l_result;
>> > }
>> >
>> > ## result:
>> > smile, 2, 3, 4
>> > smile, [int, int, int], 12fe58
>>
>> It would be nice if something like that was supported, which is what I
>> said
>> in the second paragraph, but what I meant in the first paragraph was
>> something like this (had to dig it up from Tango):
>>
>> void realfunc1(TypeInfo[] arguments, ArgList args)
>> {
>>    // function body here
>> }
>>
>> void func1(...)
>> {
>>   realfunc1(_arguments, _argptr);
>> }
>>
>> void func2(char[] o_char, ...)
>> {
>>     func1(o_char);
>>     realfunc1(_arguments, _argptr);
>> }
>>
>> Of course, you have to know the realfunc1 function name, or else have to
>> distinguish the parameters somehow.  Tango's tango.text.convert.Layout
>> has a
>> similar strategy.  There's probably a way to use Stdout to call it the
>> way
>> you want.
>>
>> -Steve
>>
>>
> Ok it's good idea but "realfunc" is not my own function, it is library function and this can not be modified.
>
> TResult realFunc(TResult)(char[] name, ...)
>

Then no, there's no way to do it unless either the library provides a version that takes a TypeInfo[]/va_list pair or if you have the ability to modify the library.


August 26, 2008
You can do this stuff using a template function.

Example:
---
// forward variadic function arguments to builtin library functions module fwvargs;

import std.stdio;

void vafunc(T...)(in char[] fmt, T args)
{
    writefln(fmt, args);
}

void main()
{
    vafunc("Called vafunc with argument %f", 2608.2008);
}
---
Output:
$>Called vafunc with argument 2608.200800

Regards.

Zarathustra Wrote:

> Steven Schveighoffer Wrote:
> 
> > "Zarathustra" wrote
> > > Steven Schveighoffer Wrote:
> > >
> > >> The way it is done in Tango is to put the implementation in a function
> > >> which
> > >> takes the _argptr and _arguments as parameters.  Then the actual variadic
> > >> function is just a wrapper.  If you want to chain another variadic
> > >> function
> > >> to it, just pass the _argptr and _arguments.
> > >>
> > >> Passing the argptr and arguments directly really should be a compiler
> > >> supported thing, as this is all you are doing anyways.  Similar to how
> > >> you
> > >> can call opX directly.
> > >>
> > >> -Steve
> > >>
> > >>
> > > Reply to Steve:
> > >
> > > Do you mean something like that?
> > >
> > > import tango.io.Stdout;
> > > void func(char[] o_char, ...){
> > >  Stdout(o_char, _arguments, _argptr);
> > > }
> > >
> > > public static int
> > > main(){
> > >  int l_result = 0;
> > >  try{
> > >    Stdout("smile", 2, 3, 4).newline;
> > >    func("smile", 2, 3, 4);
> > >  }
> > >  catch(Object o){
> > >    l_result = 1;
> > >    Cout(o.toString);
> > >  }
> > >  return l_result;
> > > }
> > >
> > > ## result:
> > > smile, 2, 3, 4
> > > smile, [int, int, int], 12fe58
> > 
> > It would be nice if something like that was supported, which is what I said in the second paragraph, but what I meant in the first paragraph was something like this (had to dig it up from Tango):
> > 
> > void realfunc1(TypeInfo[] arguments, ArgList args)
> > {
> >    // function body here
> > }
> > 
> > void func1(...)
> > {
> >   realfunc1(_arguments, _argptr);
> > }
> > 
> > void func2(char[] o_char, ...)
> > {
> >     func1(o_char);
> >     realfunc1(_arguments, _argptr);
> > }
> > 
> > Of course, you have to know the realfunc1 function name, or else have to distinguish the parameters somehow.  Tango's tango.text.convert.Layout has a similar strategy.  There's probably a way to use Stdout to call it the way you want.
> > 
> > -Steve
> > 
> > 
> Ok it's good idea but "realfunc" is not my own function, it is library function and this can not be modified.
> 
> TResult realFunc(TResult)(char[] name, ...)
>