From: Samuel Krempp (krempp_at_[hidden])
Date: 2001-07-01 13:59:10
> Since people seem to feel allegiance to the printf conventions, I am willing
> to sacrifice terseness and live with %1%, %2%, etc if there is no better
> alternative. I don't like it, but would live with it.
I was wanting to provide this very short style if at all possible.
So well, I separated clearly short-style from printf-directives,
and provided wrappers around printf directives
( say %xxxx is a printf directive, you can use it in format, of course not
directly, since it collides with %N,
but via "%pxxxx" , or "#xxxx" - # is the new replacement for $..
OR in pformat, directly ( %xxxx. And symmetrically short-style
arguments become #1 in pformat )
I uploaded my updated files in the vault.
I modified them heavily, and it begins to look good.
Of course syntax needs to be fixed, sooner or later, and some
class design matters need reflexion. like, obviously, my usage of
operator* to pass manipulators..
After all the fuss the use of operator% produced, I can guess that I will
difficultly convince the world that I need an other operator to
be able to flexibly use manipulators...
So let me reassure you, I am looking for alternatives right now..
One new thing is the tabulation stuff. working all right, and if I am
given the right to add only one formating option, this will definitely be
Also, the possibilty to store format objects, like :
format formatter("%1 %2 %3 \n");
cerr << formatter.print() %1 %2 %3;
cerr << formatter.print() %-1 %-2 %-3;
assert( (formatter.print() %-1 %-2 %-3).str() == "-1 -2 -3 \n");
( I'll try a loop of those and compare efficiency of this to re-parsing
the string each time.. might not be very compelling, but well...)
if you dont use print() but applies the arguments directly, the
formatter is modified at each call of operator%, so it works only for
the first line (normal)
Next time, you get an exception as soon as you feed arguments to the
that feels like a natural behaviour to me.
For this, I provided a copy ctor to the class.
It is needed if you want to store vectors of formatters.
hum, bad argument, I know...
The truth is it makes it possible to do the
previous stuff with a very simple design. Because, sooner or later, you
need to create a new object. when you feed your arguments to your
formatter, you dont want it modified.
And it is pretty safe, all it does is copy an array of strings, no data is
shared between copies, at all.
BTW, I could have used std::vector here, since it's exactly its
behaviour that I need. Is it all right, or is it better to do without ?
since there is just creations, copying, and destroying, but
*no* resizing or anything special, the vector was not hard to do
without. But then I do memory management myself, and
I'm not used to making sure everything is exception-safe.
I tried to, and so should it be exception-safe, though.
so there's no harm providing this copy ctor, right ?
The alternative would be to design a formatter class so that
you dont need to call print() :
format_launcher printer("%1 %2");
cout << printer %x %y;
cout << printer %380 %340;
for this to work, I only need to provide a special operator% to
the formatter class, which does :
. create a format obect from the data stored in formatter
. calls operator% on this format object.
But I dont think it is worth the extra code and complexity.
On this matter, I'd like to get back to Dave's recommendation,
> Just be careful not to overdesign this library. Simpler is
> usually better.
In my view, it applies both to
. simplicity of use
. simplicity of the implementation
Or would you use a very complex design just in order to provide one more
feature, or have a nicer syntax of use ?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk