www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - variadic args

reply novice2 <sorry nom.ail> writes:
can i pass variadig arguments from one function to other?
siomething like:

void func1(...)
{
  func2(...);
}

is it still not possible?

(sorry, i was asked this some time ago. but now i see array
literals are mnaked and other good changes - may be this question
changed too.)
Dec 07 2006
next sibling parent reply "JohnC" <johnch_atms hotmail.com> writes:
"novice2" <sorry nom.ail> wrote in message 
news:el9brb$lug$1 digitaldaemon.com...
 can i pass variadig arguments from one function to other?
 siomething like:

 void func1(...)
 {
  func2(...);
 }

 is it still not possible?

 (sorry, i was asked this some time ago. but now i see array
 literals are mnaked and other good changes - may be this question
 changed too.)

This is what I do: import std.stdarg; void resolveArgs(inout TypeInfo[] arguments, inout void* argptr) { if (arguments.length == 2 && arguments[0] is typeid(TypeInfo[]) && arguments[1] is typeid(void*)) { arguments = va_arg!(TypeInfo[])(argptr); argptr = *cast(void**)argptr; if (arguments.length == 2 && arguments[0] is typeid(TypeInfo[]) && arguments[1] is typeid(void*)) resolveArgs(arguments, argptr); } } void func1(...) { resolveArgs(_arguments, _argptr); func2(_arguments, _argptr); } void func2(...) { resolveArgs(_arguments, _argptr); // Do something with the args }
Dec 07 2006
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
JohnC wrote:

 This is what I do:
 
 import std.stdarg;
 
 void resolveArgs(inout TypeInfo[] arguments, inout void* argptr) {
   if (arguments.length == 2 && arguments[0] is typeid(TypeInfo[]) && 
 arguments[1] is typeid(void*)) {
     arguments = va_arg!(TypeInfo[])(argptr);
     argptr = *cast(void**)argptr;
 
     if (arguments.length == 2 && arguments[0] is typeid(TypeInfo[]) && 
 arguments[1] is typeid(void*))
         resolveArgs(arguments, argptr);
   }
 }

This is not portable to GDC, however. (type of argptr should be va_list) Comparing typeids with 'is' doesn't always work but using '==' should... --anders
Dec 08 2006
parent "JohnC" <johnch_atms hotmail.com> writes:
"Anders F Bj÷rklund" <afb algonet.se> wrote in message 
news:elbfah$2u9i$1 digitaldaemon.com...
 JohnC wrote:

 This is what I do:

 import std.stdarg;

 void resolveArgs(inout TypeInfo[] arguments, inout void* argptr) {
   if (arguments.length == 2 && arguments[0] is typeid(TypeInfo[]) && 
 arguments[1] is typeid(void*)) {
     arguments = va_arg!(TypeInfo[])(argptr);
     argptr = *cast(void**)argptr;

     if (arguments.length == 2 && arguments[0] is typeid(TypeInfo[]) && 
 arguments[1] is typeid(void*))
         resolveArgs(arguments, argptr);
   }
 }

This is not portable to GDC, however. (type of argptr should be va_list)

Oh right, I didn't know that.
 Comparing typeids with 'is' doesn't always work but using '==' should...

It should, but doesn't in my experience.
 --anders 

Dec 08 2006
prev sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
novice2 wrote:
 can i pass variadig arguments from one function to other?
 siomething like:
 
 void func1(...)
 {
   func2(...);
 }
 
 is it still not possible?
 
 (sorry, i was asked this some time ago. but now i see array
 literals are mnaked and other good changes - may be this question
 changed too.)

The new variadic templates make this easy: void func1(T ...)(T t) { func2(t); } -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Dec 07 2006
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Kirk McDonald wrote:
 novice2 wrote:
 can i pass variadig arguments from one function to other?
 siomething like:

 void func1(...)
 {
   func2(...);
 }

 is it still not possible?

 (sorry, i was asked this some time ago. but now i see array
 literals are mnaked and other good changes - may be this question
 changed too.)

The new variadic templates make this easy: void func1(T ...)(T t) { func2(t); }

... if you don't mind compile-time variadic behavior. I.e. can't pass func1 around as a function pointer, can't make it a polymorphic member in a class, you don't mind different code being generated for every place you call it, don't mind making the function's definition available as source code ... etc. But if you are ok with that then, yeh, variadic templates work quite nicely. --bb
Dec 07 2006
parent reply novice2 <sorry noem.ail> writes:
thanks for all replies!
resume: basically nothing changed yet,
no language support for this (yet?).
Dec 08 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"novice2" <sorry noem.ail> wrote in message 
news:elbedj$2t21$1 digitaldaemon.com...
 thanks for all replies!
 resume: basically nothing changed yet,
 no language support for this (yet?).

Nope. Though the "standard" method to do this, kind of carried over from C, is to have a 'v' version of each function, and then a truly variadic version which just calls the 'v' version. In this way you can pass the variadic args to the other 'v' functions. void vFoo(TypeInfo[] arguments, va_list argptr) { // do the actual body of the function here vBar(arguments, argptr); } void foo(...) { vFoo(_arguments, _argptr); } void vBar(TypeInfo[] arguments, va_list argptr) { } void bar(...) { vBar(_arguments, _argptr); }
Dec 08 2006
parent reply novice2 <sorry noem.ail> writes:
many thanks, Jarrett Billingsley.
i don't like templates, so you solution good.
i hope, Walter will add support for this in language,
and such ugly construction will gone from sources in future.
Dec 11 2006
next sibling parent reply Aarti_pl <aarti interia.pl> writes:
novice2 napisał(a):
 many thanks, Jarrett Billingsley.
 i don't like templates, so you solution good.
 i hope, Walter will add support for this in language,
 and such ugly construction will gone from sources in future.

You can try with Any ported to D. It allows quite nice solution for variadic arguments: void printVector(Any[] vec) { // printing vector of different type arguments // see Any description and code; eventually boost any // documentation } void printVariadic(Any[] var...) { printVector(var); } void main() { Any[] vec; vec~=(new Any).assign(6); vec~=(new Any).assign("Text"[]); vec~=(new Any).assign(5.5); printVector(vec); auto v = new Any; auto z = new Any; v.assign(2.5); z.assign("Another text"[]); printVariadic(v, z); } I will send at the end of week updated version of Any, which supports new opAssign() overloaded operator, so it will be possible: v=2.5; instead of v.assign(2.5); Using Any you do not have to use va_list, TypeInfo, pointers etc. It's just redundant then... I just would wish myself that Walter will add support for templatized constructors to achieve following: # printVariadic(new Any(4), new Any("Yet another text"[]), new Any(3.14)); // it doesn't work now... Best Regards Marcin Kuszczak
Dec 11 2006
parent reply Endea <notknown none.com> writes:
Aarti_pl kirjoitti:
 I just would wish myself that Walter will add support for templatized 
 constructors to achieve following:
     # printVariadic(new Any(4), new Any("Yet another text"[]), new 
 Any(3.14)); // it doesn't work now...
 

Would this work? static Any opCall(T)(T t) { return (new Any()).assign(t); }
Dec 11 2006
parent Aarti_pl <aarti interia.pl> writes:
Endea napisał(a):
 Aarti_pl kirjoitti:
 I just would wish myself that Walter will add support for templatized 
 constructors to achieve following:
     # printVariadic(new Any(4), new Any("Yet another text"[]), new 
 Any(3.14)); // it doesn't work now...

Would this work? static Any opCall(T)(T t) { return (new Any()).assign(t); }

Yes, it should work... BR Marcin Kuszczak
Dec 11 2006
prev sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
novice2 wrote:
 many thanks, Jarrett Billingsley.
 i don't like templates, so you solution good.
 i hope, Walter will add support for this in language,
 and such ugly construction will gone from sources in future.

There's also Chris Miller's Variadic class (and my modification of it) http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=42894 Oh, dang, the fine news group software doesn't handle uuencoded attachments :-/ Check out this link instead: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=42648 --bb
Dec 11 2006
next sibling parent Bill Baxter <wbaxter gmail.com> writes:
Bill Baxter wrote:
 novice2 wrote:
 
 many thanks, Jarrett Billingsley.
 i don't like templates, so you solution good.
 i hope, Walter will add support for this in language,
 and such ugly construction will gone from sources in future.

There's also Chris Miller's Variadic class (and my modification of it) http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digita mars.D&artnum=42894 Oh, dang, the fine news group software doesn't handle uuencoded attachments :-/ Check out this link instead: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digita mars.D&artnum=42648 --bb

Here's the link I meant to post: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=42894 --bb
Dec 11 2006
prev sibling parent reply novice2 <sorry noem.ail> writes:
thanx Bill Baxter.
but i don't need foreach...
no need any *processing*
just repassing to variadic function, not my, for example format
(...) or writef(...)

please, don't show me how to reimplement format with doFormat(),
i already to do it. but it is ugly :)
Dec 11 2006
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
novice2 wrote:
 thanx Bill Baxter.
 but i don't need foreach...
 no need any *processing*
 just repassing to variadic function, not my, for example format
 (...) or writef(...)
 
 please, don't show me how to reimplement format with doFormat(),
 i already to do it. but it is ugly :)

Ok, then for you I'll make the special "lean and mean" version: struct VArgs { static VArgs opCall(TypeInfo[] arguments, va_list argptr) { VArgs result; result.arguments = arguments; result.argptr = argptr; return result; } TypeInfo[] arguments; va_list argptr; } void vFoo(VArgs args) { // do the actual body of the function here vBar(args); } void foo(...) { vFoo(VArgs(_arguments, _argptr)); } void vBar(VArgs args) { } void bar(...) { vBar(VArgs(_arguments, _argptr)); } ---- The point is more that _arguments and _argptr belong together, so it makes sense to package them up into a single struct to pass them around together rather than always passing them as two separate arguments. Whether or not you want the struct to help with processing the arguments is up to you. Personally I wish that D would a) pass a struct like the above to variadic functions, and b) let users specify a name rather than giving access to them through magic parameter names. Magic parameter names with underscores just look terribly hackish. Instead we could have something like: void bar(...args) { //use args.types[i], *args.argptr here } --bb
Dec 12 2006
parent novice2 <sorry noema.ail> writes:
Thanx again.
Sorry for my dumbness.
But i specially emphasized that target function not my.
Alien/legacy/phobos code.
How i can create vWritef() for example?
As i see in std.stdio we have xwritef()
But it not accessible outside module :(

So i don't see other way to repassing variadic args to other
function else some "syntatic shugar" like

void foo(...)
{
  bar(...);
}

or something other syntax.

may be this problem is forced and not actual, but i meet this :)


== Quote from Bill Baxter (dnewsgroup billbaxter.com)'s article
 novice2 wrote:
 thanx Bill Baxter.
 but i don't need foreach...
 no need any *processing*
 just repassing to variadic function, not my, for example format
 (...) or writef(...)

 please, don't show me how to reimplement format with doFormat(),
 i already to do it. but it is ugly :)

struct VArgs { static VArgs opCall(TypeInfo[] arguments, va_list argptr) { VArgs result; result.arguments = arguments; result.argptr = argptr; return result; } TypeInfo[] arguments; va_list argptr; } void vFoo(VArgs args) { // do the actual body of the function here vBar(args); } void foo(...) { vFoo(VArgs(_arguments, _argptr)); } void vBar(VArgs args) { } void bar(...) { vBar(VArgs(_arguments, _argptr)); } ---- The point is more that _arguments and _argptr belong together, so

 makes sense to package them up into a single struct to pass them

 together rather than always passing them as two separate

 Whether or not you want the struct to help with processing the

   is up to you.
 Personally I wish that D would a) pass a struct like the above to
 variadic functions, and b) let users specify a name rather than

 access to them through magic parameter names.  Magic parameter

 with underscores just look terribly hackish.   Instead we could

 something like:
 void bar(...args) {
     //use args.types[i], *args.argptr here
 }
 --bb

Dec 12 2006