Boost logo

Boost :

From: s_krempp (krempp_at_[hidden])
Date: 2001-12-18 11:27:08


--- "vonosan" <alnsn_at_m...> wrote:
> I put the code here:
> http://groups.yahoo.com/group/boost/files/formatter/formatter-1.0-
> beta.zip

it's more simple and compact than mine, since your choice is to simply translate the format string into stream flags.
Also, in my class I added some features that seemed natural and potentially useful, so my code grew a bit more complex than yours
The differences betwwen our 2 classes mainly come from those extra features.
I hope you agree that they make sense :

1:
 parse a format string once, and use the format object many times on different arguments.
1-bis :
My format objects are regular objects that can be copied, assigned, fed arguments, dumped to a stream, re-fed arguments, etc...
So users can use them the way they like.

2. Once a format object is constructed, eg format fmter("%2 %1 %2");
I can write fmter.set_flag(3, setw(10) );
and fmter is now the same as if I had specified 'width 10' for the third directive in the format-string.
format("%2 %1 %p2$10s");
Thus I can use any manipulator with my format objects.

3. I can also 'bind' an argument to a given value, eg
fmter.bind_arg(2, "<N/A>");
cout << fmter % 10; // prints "<N/A> 10 <N/A>"
Maybe this wont be very useful, but it seems right to provide the full set of possible manipulations on format objects.
(this feature is straightforward to implement)

4. I can pass manipulators along with the arguments, to modify the way they will be formatted
cout << format("%2 %1 %2") % 1 % glue(showpos) % 2;
// prints "+2 1 +2"
This is not the same as feature2 since all occurences of the argument in the conversion string are affected by the manipulator.
Also, this is treated like arguments, and if reusing the format object,
those manipulators will be forgotten. (whereas set_flag's effect on the object is permanent)
Well, Maybe this feature could be left aside.
feature2 provides almost the same possibilites, and does not require using a 'glue' function to wrap manipulators (so that they
are distinct from regular arguments)

You chose to store one stringstream for each directive (or block, as you call them)
This has the great advantage that you apply formatting options on the concerned stream immediately at parsing.

While I store strings, and stream states separately, and use only one stringstream for all the conversions.
Thus I have to manipulate stream states, which can make things a bit ugly,
but since I don't use stringstream for storage of the formatting options,
my objects can be copied and manipulated easily.
(anyway, some features require manipulating stream states. eg to get both features 4 and 1, you have to store 2 stream states for
each block, then one stringstream is not enough for a block in this case)

Aslo, storing strings rather than stringstreams can be an advantage for performance :
In my class all the dynamic allocations take place inside the stringstream
(string results are then copied inside a vector, 'cvted_items')
So I get less overhead from dynamic allocation, at the price of copying every formatted strings into a new storage (of
known-size, that's the all point).

Well, this is my point of view, and I'm waiting to hear others'

-- 
Sam
PS: I updated my files in the vault : the manipulation of stream format states is now tremendously prettier
and all source files are a lot more commented.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk