autoprintf("hello world\n"); autoprintf("hello ",7," world\n"); autoprintf("hello %03d\n",7); autoprintf("hello ","world %.1f",3.f,"\n"); autoprintf("hello %d",3," world %.1f\n",3.f); autoprintf("hello ",(size_t)400,"\n"); autoprintf("hello ",L"unicode is balls"," \n"); autoprintf("hello ",String("world")," \n");In particular, all of the following things work :
- Regular old printf stuff works just like always.
- .. except that it does type validation against the format string using my old "safeprintf" system
- You can put args anywhere on the line, not just at the end. This is handy when you get really long printfs
going, and makes it easier to copy-paste and rearrange.
Similarly you can put format strings anywhere on the line, which is handy when you have a long printf set up and you want to
just add something on the end.
- Does automatic type deduction and output of types that are not explicitly qualified in the format string. In particular a
handy one is (size_t) which is not properly supported in a cross-platform way. Any type that doesn't have a
% format thingy provided by the caller gets an automatic one.
- Supports non-basic types in a clean template overriding way. So things like that line that pass a String() as an argument - you will get a compile error if you haven't made a compatible template for that type, or if you have you get nice autoconversion. Basically all the advantages of the C++ iostream << dealy but without the horribleness of having to do your printing that way.
I'm gonna clean up the code a bit and try to extricate it from cblib (meh or maybe not) and I'll post it in a few days.
It does pretty much everything I've always wanted from a printf. There is one thing missing, which is formatting for arbitrary types. Currently you can only format the basic types, and the non-basic types go through a different system. eg. you can either do :
autoprintf("hello %5d ",anInt);or
autoprintf("hello ",(size_t)anInt);but you can't yet do
autoprintf("hello %5",(size_t)anInt);(note that the type specifier is left off, only format specifiers are on the %). I know how to make this work, but it makes the implementation a lot more complicated, so I might punt on it.
The more complicated version is to be able to pass through the format spec into the templated converter. For example, you might have a ToString() for your Vec3 type which makes output like ("{%f,%f,%f}",x,y,z) . With the current system you can do :
Vec3 v; autoprintf("v = ",v);and it will call your ToString, but it would be groovy if you could do :
Vec3 v; autoprintf("v = %.1",v);as well and have that format apply to the conversion for the type. But that's probably more complication than I want to get into.
Another thing that might be nice is to have an explicit "%a" or something for auto-typed, so you can use them at the end like normal printf args. eg :
autoprintf("hello %d %a %f\n", 3, String("what"), 7.5f );
10 comments:
Cool stuff, I'm looking forward to seeing the code.
Sweet. This looks great.
I realize you don't NEED %s, but does %s work or is it incompatible (since it can't tell the difference between a format string and an "argument" string)?
What about order-independent arguments which are handy for L10n?
printf("%s said %s is cool", person1, person2);
might need order of person1 and person2 swapped for some other language.
So in such case it would be handy to have:
printf("%{2}s blabla %{1}s bla", person1, person2);
Apart from missing this, your autoprintf seems very cool! :-D
" I realize you don't NEED %s, but does %s work or is it incompatible (since it can't tell the difference between a format string and an "argument" string)? "
That mostly works out automatically. There are possible ambiguities, and what I do is look in the string for '%' , so there could be a problem if you are trying to pass a string literal with a % in it, and I treat it as a format string. eg. things like :
autoprintf("tricky %s","yes 100%",7);
sounds good, lets see some code :)
Random question: does this expand your code substantially?
I'll investigate that. It depends how much I make inline I guess.
BTW I'm gonna support arg reordering partly for that reason. Reordering would require me to generate a template function for each possible reorg, which is N! for N arguments. Way too much code. eg. something like :
U32 reorgCode = GetReorg(formatString);
switch(reorgCode) {
case 0: printf(a1,a2,a3);
case 1: printf(a1,a3,a2);
case 2: printf(a2,a1,a3);
...
no fun.
"I'm gonna support arg reordering "
->
"I'm *NOT* gonna support arg reordering"
Post a Comment