Boost logo

Boost :

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.

Thanks. :)

> 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:

// operator<<(stream,T[N])

template<class CharType,class CharTraits,class T,std::size_t N>
std::basic_ostream<CharType,CharTraits> &operator<<
  (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[0];

  for(std::size_t i=1;i!=N;++i)
    stream << format.delimiter << array[i];

  stream << format.end;

  return stream;

and given this:

int main()
char board[3][3]=

std::cout << io_format<char (&)[3]>("\n|","|\n","|")
          << io_format<char (&)[3][3]>("-------","-------","-------")
          << board << '\n';

we get:


"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
stream operators.

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, gregod at, cpdaniel at, john at