From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-02-04 08:46:24
>From: "Vladimir Prus" <ghost_at_[hidden]>
> Terje Slettebø wrote:
> > Incidentally, I've just made a version that does exactly this. :) I've
> > attached it, including a test, with this posting.
> I've take a look and I like it -- quite lean and does the work.
> I've some concerns, though:
> 1. Are "default" breaces/separators possible? I'd rather not use
> io_format every time I had to output a vector.
Good point. As it is now, it just defaults to empty strings for the
separators. Any idea how to specify such a default? If it's specified in the
header, it may be hard to select one that is sensible for all people.
> 2. Is that good idea to set brace style on vector<int> and vector<double>
> separately? It would increase pword() array, and not sure if this will
> benefit us much. Are nested containers the primary motivation?
Another good point. I guess there isn't any point in separate formats for
different element types, no.
The way it works now is that it instantiates an
basic_composite_format<CharType, TypeToOutput> (name changed from
basic_io_format), containing a static function with a static xalloc() index,
for each type to be output. Thus, it's parameterised on a type, not a
partially specified type.
I'll look into this, as well. Partial specialisation, inheriting from a
less-parameterised base comes to mind.
There are also some other issues: The current version assumes basic_string
for the delimiters. I've found it hard to let it take an arbitrary string
type, as the format-object (which the manipulator, basic_composite_format,
doubles as) stores a format parameterised on type to output and character
type. The latter is so that if multiple streams with different character
types are used, they should not use the same format-object..
This means that one must know the character type of the delimiter strings,
in order to parameterise the format object correctly. That's why
basic_string is used, as you then get access to the character type.
By the way, just for fun. Adding the following output operator for arrays,
to the header I gave in the previous posting:
template<class CharType,class CharTraits,class T,std::size_t N>
(std::basic_ostream<CharType,CharTraits> &stream,T (&array)[N])
typedef basic_io_format<CharType,T(&)[N]> format_type;
const format_type &format=format_type::format(stream);
stream << format.start << array;
stream << format.delimiter << array[i];
stream << format.end;
and given this:
std::cout << io_format<char (&)>("\n|","|\n","|")
<< io_format<char (&)>("-------","-------","-------")
<< board << '\n';
"Shall we play a game?" :)
By the way, in the first posting, I figured you knew about stream iterators,
so I was a little puzzled, but then it turned out I had just misunderstood
what you meant. Reading it more carefully later, I saw that you did mention
The names and interface is just chosen tentatively, and I'm open to
suggestions for better names. I changed the "*io_format" names to
"*composite_format", as it reflects better what it does, and reduces the
chance for name collision. I didn't want to call it container_format, or
something like that, as it's not restricted to containers, but may output
any composite object, given suitably defined output operators (such as
std::vector, std::pair, arrays, etc.)
Thanks for the feedback.
I've uploaded the new version here
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk