Re: metaprogramming question
On Mon, Apr 19, 2010 at 07:43, Justin Spahr-Summers < justin.spahrsumm...@gmail.com> wrote: > > Yes, sorry. That's what I was trying to do originally, but I couldn't > quite spit it out. Indeed, templating the actual arguments is a horrible > idea. > Sorry to comment on it, then. I'm discovering all this by myself, so I don't know if what I generally post is a well-known established practice or a nice trick few people use... (or a brillant idea only a genius could utter, but hey...) Just to complete it, and as it's on my mind: I found one case, yesterday, when you have to pass the args as CT args: filtering on a tuple. Strange idea maybe, but fun to code. That is: auto t = tuple(1, 'a', "abc", 3.14159); auto f = filterTuple!(polymorphicPredicate)(t); // should return a smaller tuple, with 1, 'a',... filtered according to polymPredicate This does not work, because I have to determine the return type of filterTuple as CT, obviously. And this return type in turn depends on the _values_ stored inside the tuple. At CT, I can check the types, but not the values, unless I use them as CT args: auto f = filterTuple!(polymorphicPredicate, t)(); But then, I'm limited by what you can use as a template parameter (not all possible D types are allowed, I think). Maybe as an alias... I'll stop, now, before derailing the thread. I'm trying to use tuples as a sort-of cousin of ranges, by mapping, chaining or truncating them... Philippe
Re: metaprogramming question
On Mon, Apr 19, 2010 at 07:31, BCS wrote: > Or you can mangel that a bit: > > template check(alias func) { > bool check(EL ...)() { > > GError* err; > bool ok = func(EL, &err); > if (!ok) >throw new Exception((*err).message); > return ok; > } > } > > that should allow you to call it like: > > check!(fooXXX)(arg1, ..., argN); (I guess you meant bool check(EL...)(EL el) in the second stage.) Yes, this example is even more powerful. The version I posted already allows you to write check!fun(params); // no need to give explictly the EL, the compiler wil deduce them for you but yours allow you to 'store' the checking of fun and then to use it for any parameter typetuple. Maybe not useful for the OP, but mighty handy in some other cases. I discovered this trick a few weeks ago and, though a bitch to code sometimes, it's very nice to have. Usage: alias check!foo fooCheck; // checkFoo is a templated function, so it's _not_ a function. You cannot assign it to a variable. // use alias instead. // some other code // auto check1 = fooCheck(1,2,3); // auto check2 = fooCheck("a","b", 2.34); It's particularly useful when foo is polymorphic. Again, not interesting for the OP, but very fun. Philippe
Re: metaprogramming question
On Mon, 19 Apr 2010 07:28:09 +0200, Philippe Sigaud wrote: > > On Mon, Apr 19, 2010 at 05:21, Justin Spahr-Summers < > justin.spahrsumm...@gmail.com> wrote: > > > You can use some expression tuple magic to accomplish something like > > that: > > > > bool check(alias func, EL ...)() { > >GError* err; > >bool ok = func(EL, &err); > > if (!ok) > >throw new Exception((*err).message); > > > > return ok; > > } > > > > // used like: > > check!(fooXXX, arg1, ..., argN); > > > > > But in this case, you need to know the ELs at compile-time. You can make > them run-time values that way: > > bool check(alias func, EL ...)(EL el) { >GError* err; >bool ok = func(el, &err); > if (!ok) >throw new Exception((*err).message); > > return ok; > } > > // used like: > check!fooXXX(arg1, ..., argN); Yes, sorry. That's what I was trying to do originally, but I couldn't quite spit it out. Indeed, templating the actual arguments is a horrible idea.
Re: metaprogramming question
Hello Justin Spahr-Summers, On Mon, 19 Apr 2010 00:12:28 + (UTC), Graham Fawcett wrote: Hi folks, I'd like to wrap a family of C functions that look like this: gboolean fooXXX(arg1, ..., argN, GError** err) Their signatures and arities vary, but they all have a GError** as their last argument. If a function returns false, then 'err' will be set to a relevant Error struct. I would like to write a wrapper that would let me call these functions sort of like this: check!(fooXXX(arg1, ..., argN)) where the 'check' expression would be equivalent to: GError* err; bool ok = fooXXX(arg1, ..., argN, &err); if (!ok) throw new Exception((*err).message); Does D (2.0) offer a metaprogramming technique I could use to accomplish this -- particularly, to inject that 'err' argument into the tail of the fooXXX call? Thanks, Graham You can use some expression tuple magic to accomplish something like that: bool check(alias func, EL ...)() { GError* err; bool ok = func(EL, &err); if (!ok) throw new Exception((*err).message); return ok; } // used like: check!(fooXXX, arg1, ..., argN); IIRC that should be: check!(fooXXX, argType1, ..., argTypeN)(arg1, ..., argN); See http://digitalmars.com/d/2.0/template.html#TemplateTupleParameter Or you can mangel that a bit: template check(alias func) { bool check(EL ...)() { GError* err; bool ok = func(EL, &err); if (!ok) throw new Exception((*err).message); return ok; } } that should allow you to call it like: check!(fooXXX)(arg1, ..., argN); -- ... <
Re: metaprogramming question
Hello Philippe, Of course, it'd be nice to check the EL at CT to see if they correspond to func parameters types. The call inside check will coever that for you as long as you don't mind getting the error in an odd place. -- ... <
Re: metaprogramming question
On Mon, Apr 19, 2010 at 05:21, Justin Spahr-Summers < justin.spahrsumm...@gmail.com> wrote: > You can use some expression tuple magic to accomplish something like > that: > > bool check(alias func, EL ...)() { >GError* err; >bool ok = func(EL, &err); > if (!ok) >throw new Exception((*err).message); > > return ok; > } > > // used like: > check!(fooXXX, arg1, ..., argN); > > But in this case, you need to know the ELs at compile-time. You can make them run-time values that way: bool check(alias func, EL ...)(EL el) { GError* err; bool ok = func(el, &err); if (!ok) throw new Exception((*err).message); return ok; } // used like: check!fooXXX(arg1, ..., argN); Of course, it'd be nice to check the EL at CT to see if they correspond to func parameters types. I don't know if you can do this with C functions, but for D funcs you can add: import std.traits; bool check(alias func, EL ...)(EL el) if (is(ParameterTypeTuple!func[0..$-1] == TypeTuple!(EL, GError*)) { ... It's a bit strict, as it doesn't deal with implicit conversions. Cheers, Philippe
Re: metaprogramming question
http://while-nan.blogspot.com/2007/06/wrapping-functions-for-fun-and-profit.html It shouldn't be too difficult to inject an extra parameter; just add it to the end of the call to the wrapped function after args.
Re: metaprogramming question
On Mon, 19 Apr 2010 00:12:28 + (UTC), Graham Fawcett wrote: > > Hi folks, > > I'd like to wrap a family of C functions that look like this: > > gboolean fooXXX(arg1, ..., argN, GError** err) > > Their signatures and arities vary, but they all have a GError** as > their last argument. If a function returns false, then 'err' will be > set to a relevant Error struct. > > I would like to write a wrapper that would let me call these functions > sort of like this: > > check!(fooXXX(arg1, ..., argN)) > > where the 'check' expression would be equivalent to: > > GError* err; > bool ok = fooXXX(arg1, ..., argN, &err); > if (!ok) > throw new Exception((*err).message); > > Does D (2.0) offer a metaprogramming technique I could use to > accomplish this -- particularly, to inject that 'err' argument into > the tail of the fooXXX call? > > Thanks, > Graham You can use some expression tuple magic to accomplish something like that: bool check(alias func, EL ...)() { GError* err; bool ok = func(EL, &err); if (!ok) throw new Exception((*err).message); return ok; } // used like: check!(fooXXX, arg1, ..., argN); See http://digitalmars.com/d/2.0/template.html#TemplateTupleParameter
metaprogramming question
Hi folks, I'd like to wrap a family of C functions that look like this: gboolean fooXXX(arg1, ..., argN, GError** err) Their signatures and arities vary, but they all have a GError** as their last argument. If a function returns false, then 'err' will be set to a relevant Error struct. I would like to write a wrapper that would let me call these functions sort of like this: check!(fooXXX(arg1, ..., argN)) where the 'check' expression would be equivalent to: GError* err; bool ok = fooXXX(arg1, ..., argN, &err); if (!ok) throw new Exception((*err).message); Does D (2.0) offer a metaprogramming technique I could use to accomplish this -- particularly, to inject that 'err' argument into the tail of the fooXXX call? Thanks, Graham
Re: Newsgroups, off-topic
Jérôme M. Berger wrote: Actually, gcc doesn't require Walter to give away all rights to his work just to use it as a backend (or else the gdc project wouldn't exist). It would require ceding the rights only if Walter wanted D to be part of the official gcc distribution. You're right, I'm sorry. -- Simen
Re: reading a global external (C) char* in D2
Graham Fawcett wrote: On Sun, 18 Apr 2010 19:14:33 +0200, Lars T. Kyllingstad wrote: Graham Fawcett wrote: Hi folks, I'm having trouble reading an external(C) global value in D2. I think I'm using __gshared properly to sidestep the TLS issues, but I'm still getting an incorrect result. [...] Am I doing something wrong? Thanks, Graham Try adding a second 'extern': extern(C) extern __gshared char* gdbm_version; That did it! Thank you. I have much to learn. No problem. :) I ran into the same issue myself a few weeks ago, and it took a while before I figured it out. I believe the explanation is that - 'extern(C)' means that it is a C variable, i.e. its name isn't mangled like a D variable in the object file. - 'extern' means that it's not a part of the current module, and has to be linked in from elsewhere. -Lars
Re: Newsgroups, off-topic
Simen kjaeraas wrote: > Joseph Wakeling wrote: > >> Maybe true, but I was thinking of it from a different angle -- why the >> main D2 development does not switch backends. > > So which do you suggest be used instead - the one that doesn't work on > Windows (no exceptions) or the one that requires Walter to give away > all rights to his work? > Actually, gcc doesn't require Walter to give away all rights to his work just to use it as a backend (or else the gdc project wouldn't exist). It would require ceding the rights only if Walter wanted D to be part of the official gcc distribution. Jerome -- mailto:jeber...@free.fr http://jeberger.free.fr Jabber: jeber...@jabber.fr signature.asc Description: OpenPGP digital signature
Re: reading a global external (C) char* in D2
On Sun, 18 Apr 2010 19:14:33 +0200, Lars T. Kyllingstad wrote: > Graham Fawcett wrote: >> Hi folks, >> >> I'm having trouble reading an external(C) global value in D2. I think >> I'm using __gshared properly to sidestep the TLS issues, but I'm still >> getting an incorrect result. >> >> Consider the two following programs, one in C, the other D2: >> >> // testc.c >> #include >> extern char *gdbm_version; // or #include >> >> int main() { >> printf("VERSION (C): %s.\n", gdbm_version); >> } >> >> $ gcc -o testc testc.c -lgdbm && ./testc VERSION (C): GDBM version >> 1.8.3. 10/15/2002 (built Nov 5 2008 02:36:47). >> >> // testd.d >> import std.stdio; >> import std.conv; >> >> __gshared extern (C) char *gdbm_version; >> >> void main() { >> string v = to!string(gdbm_version); >> writef("VERSION (D): %s.\n", v); >> } >> >> $ dmd testd.d -L-lgdbm && ./testd >> VERSION (D): . >> >> Am I doing something wrong? >> >> Thanks, >> Graham > > > Try adding a second 'extern': > >extern(C) extern __gshared char* gdbm_version; That did it! Thank you. I have much to learn. Cheers, Graham > > -Lars
Re: reading a global external (C) char* in D2
Graham Fawcett wrote: Hi folks, I'm having trouble reading an external(C) global value in D2. I think I'm using __gshared properly to sidestep the TLS issues, but I'm still getting an incorrect result. Consider the two following programs, one in C, the other D2: // testc.c #include extern char *gdbm_version; // or #include int main() { printf("VERSION (C): %s.\n", gdbm_version); } $ gcc -o testc testc.c -lgdbm && ./testc VERSION (C): GDBM version 1.8.3. 10/15/2002 (built Nov 5 2008 02:36:47). // testd.d import std.stdio; import std.conv; __gshared extern (C) char *gdbm_version; void main() { string v = to!string(gdbm_version); writef("VERSION (D): %s.\n", v); } $ dmd testd.d -L-lgdbm && ./testd VERSION (D): . Am I doing something wrong? Thanks, Graham Try adding a second 'extern': extern(C) extern __gshared char* gdbm_version; -Lars
reading a global external (C) char* in D2
Hi folks, I'm having trouble reading an external(C) global value in D2. I think I'm using __gshared properly to sidestep the TLS issues, but I'm still getting an incorrect result. Consider the two following programs, one in C, the other D2: // testc.c #include extern char *gdbm_version; // or #include int main() { printf("VERSION (C): %s.\n", gdbm_version); } $ gcc -o testc testc.c -lgdbm && ./testc VERSION (C): GDBM version 1.8.3. 10/15/2002 (built Nov 5 2008 02:36:47). // testd.d import std.stdio; import std.conv; __gshared extern (C) char *gdbm_version; void main() { string v = to!string(gdbm_version); writef("VERSION (D): %s.\n", v); } $ dmd testd.d -L-lgdbm && ./testd VERSION (D): . Am I doing something wrong? Thanks, Graham
Re: Newsgroups, off-topic
Joseph Wakeling wrote: Maybe true, but I was thinking of it from a different angle -- why the main D2 development does not switch backends. So which do you suggest be used instead - the one that doesn't work on Windows (no exceptions) or the one that requires Walter to give away all rights to his work? -- Simen
Re: Newsgroups, off-topic
Hello Joseph, I can also see the desire to have a backend that is fully under the control of the main developers. There is also the point that if Walter never looks at the source for another compiler, it is nearly impossible for him to be sued for stealing from them. -- ... <
Re: Newsgroups, off-topic
Moritz Warning wrote: > I think many people behind these compilers lack the personal motivation > to integrate the D2 front end. > That may change, but it may take time. Maybe true, but I was thinking of it from a different angle -- why the main D2 development does not switch backends. To be fair, the work involved would surely detract from the main development effort on the language and features. I can also see the desire to have a backend that is fully under the control of the main developers. > - not everybody likes the road the D2 design takes What are the concerns here ... ? I don't currently have a strong enough sense of the differences. > anyway, gdc has D2 support already (but not up to date/DMD), see http:// > bitbucket.org/goshawk/gdc/overview I've been following that D2 work for a while now, and am looking forward to where it is going ... :-) Best wishes, -- Joe