RE: [boost] Re: Formal review of "Output Formatters" library begi nstoday

Here some more details:
1. What is your evaluation of the design?
Library trying to solve in fact trivial problem. Would it be
Rozental, Gennadiy wrote: presented
as trivial function
Template<typename C> Foo( C const& c, std::string open, std::string close, std::string sep );
I may understand it.
This would mean that you would duplicate code for rendreing container types.
What code? I have only one function. Could you please be more specific. In worse case I will have as many function as many different UDT I want to support. But this is also the case for you.
Also, you are missing special formatting, e.g. wrapping open/close values around elements, e.g.:
Yeah, maybe. My solution is 5 lines. You solution is 170K of code. I could afford to repeat my function twice would I need to add extra grist.
std::cout << formatob( vec, containerfmt( wrappedfmt().format( "<e>", "</e>" )).format( "<l>", "</l>" )); // output: <l><e>a</e><e>b</e></l>
And again, why would I do this? This code is looking for trouble. How long will it be until I mistype open/close brackets differently?
the indentation functionality that Volodya has expressed an interest in, and position-based output, e.g.:
[0] John, [1] James, [2] Marina
I wonder how your interface would look like. Anyway it's not a part of submitted library. Once you presented it we may discuss it.
Also, the library should be usable on a standard stream. This is one of the key design aims. Can you do:
std::cout << Foo( vec, "< ", " >", " :: " );
? This requires returning an object that has << implemented. The mechanism for this is outlined in the standard by using *manipulators*. Thus, you would need that class to defer processing to the Foo function if you want to use your approach.
*If* I want usual ostream interface, I do need to add one function object (note that it does not matter how many UDT I want to support).
2. What is your evaluation of the implementation?
In most part I either don't understand or don't like it. IMO simple task library trying to solve shouldn't require that much code. Simple overloading base solution should've done the trick.
This does not allow for flexibility to add indenting, wrapped data, etc.
I do not think it's true statement. See my other post.
4. What is your evaluation of the potential usefulness of the library?
Now to the most important: why would I ever want to use library like this?
We have already: std::ostream boost::format boost::serailization
In what scenario I would use this library?
But you can't do:
std::vector< int > vec; std::cout << vec; // oops! no operator << defined for vectors.
Then I will write one. The thing is: I believe what library need to bring more value than just a substitution for 5 lines of custom code (especially since it not that flexible, and any step to the side causing you to write more code that custom solution would require you to).
I most definitely wouldn't want to repeat all this formatting every time I need to output my vector.
If you want [ a, b, c, d ] style output, you don't. The extra machinery is used to customize this.
What if I want { a, b, c, d } for all my vectors? I could write global operator << using your library, using custom loop or using my trivial Foo above. I do it once. So where is the win for your solution?
Also, you can save a format object, e.g.: // old style containerfmt_t< char, pairfmt_t< char > > myformat = containerfmt( pairfmt().format( " = " )).format( "<< ", "
" );
std::cout << formatob( vec, myformat ); // << ( a = 5 ), ( b = 7 ), ...
std::cout << formatob( lst, myformat ); // << ( i = 2.132 ), ( j = 3.14159 ), ... >> std::cin >> formatob( vec, myformat );
And now I need to write std::cout << formatob( lst, myformat ); every time I print list? No, thank you.
If I write output operation rarely - I would use explicit loop -it's more flexible anyway.
Depends what you are outputting. If the type contains nested containers, it can be more complex.
Maybe. But compare user base for container over scalar types with multilevel containers.
I wouldn't use this library for XML printing - why would I want to mention tag name twice?
You can use a wrapper format object:
std::cout << formatob( vec, containerfmt( wrappedfmt().format( "<e>", "</e>" )).format( "<l>", "</l>" )); // output: <l><e>a</e><e>b</e></l>
I can. But I won't. And wouldn't recommend. See above.
Regards, Reece
Gennadiy.

Also, you can save a format object, e.g.: // old style containerfmt_t< char, pairfmt_t< char > > myformat = containerfmt( pairfmt().format( " = "
)).format( "<< ", "
" );
std::cout << formatob( vec, myformat ); // << ( a = 5 ), ( b = 7 ), ...
std::cout << formatob( lst, myformat ); // << ( i = 2.132 ), ( j = 3.14159 ), ... >> std::cin >> formatob( vec, myformat );
And now I need to write
std::cout << formatob( lst, myformat );
every time I print list? No, thank you.
As opposed to Foo(lst, std::cout)? I would certainly go with the former... Also, if you read the rest of the thread, you would have noticed that there were a lot of talk about storing the formatter within the stream itself. Reece has proposed quite a few solutions - and I'm sure he'll come up with a very good one in the end. What he was explaining is how things are done now - in this version of the library. Best, John -- John Torjo -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.4 - save_dlg - true binding of your data to UI controls! + easily add validation rules (win32gui/examples/smart_dlg)
participants (2)
-
John Torjo
-
Rozental, Gennadiy