Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2000-08-21 18:18:42


Karl,

I am beginning to like your proposal more and more. I think I would "insist"
on having a wide version for boost. I also think there are simple ways we
can produce the fully templatized version that will work with the current
gcc lib (but only for narrow streams in that environment) by using
appropriate full specialization.

One other question: is it really neccessary to have a separate format() and
string_format() in the usage syntax? It seems (without looking at the
details) like you could make the following work:

cout << format("The Truth is %^20s\n")
     << (format("%f != %f") << 1 << 2);
cout << format("The Truth is %^25s\n") << setfill('.')
     << (format("%.5f != %f) << 1.9999 << 2.000 );

The key is that you can have separate return types (X and Y) for

X operator<<(ostream&, const <type-of-format>&)

   and

template <class T>
Y operator<<(const <type-of-format>&, T)

Am I onto something here or am I speaking from a "dark place"?

-Dave

----- Original Message -----
From: "Karl Nelson" <kenelson_at_[hidden]>
To: <boost_at_[hidden]>
Cc: <kenelson_at_[hidden]>
Sent: Monday, August 21, 2000 6:41 PM
Subject: Re: [boost] Re: formatting manipulator for UTF-8

Beman,

There are actually 3 different proposals. Here is a rundown.

-------------------------------------------------------------------
The oldest is from Valentin. His is the most basic design
which uses awk/perl(??) like rearrangements. His is
stream based largely (uses << for arguments) and was coded with full charT
specifications. His focuses exclusively on position and
thus there are no specifications of format.

  http://www.eleves.ens.fr:8080/home/bonnard/Boost/PosStream/

  boost::format(cout, "Cannot $1 at $2:$3\nCause: $4\n")
    << "frobnicate"
    << "blaz"
    << showbase << hex << uppercase << 10
    << "no more foobars";

------------------------------------------------------------------
The second was from a discussion titled "basic i/o" initiated by
David Abrahams coded by Loos Rudiger. It provides some formatting
functionality by does not use a streams like format but rather
a very overloaded template. This limits the number of arguments
to 9. The format is entirely of its own creation.

cout << format("%1 chickens can be found in coop number %2.\n",
   chicken_cnt , coop_num);
cout << format("Dans la cage le numéro %2, on y trouve %1 poulets.\n",
   chicken_cnt , coop_num);
cout << format("%1 costs %2%3%4\n", item, setprecision(2), fixed, price);
cout << format("The Truth is %w20%c%1", format("%1 != %2", 1, 2))<<endl;
cout << format("The Truth is %2%w25%c%1",
        format("%3%4%1 != %2", 1.9999, 2.000, setprecision(5), fixed),
        setfill('.')) << '\n';

The implementation is coded in charT templates.

It has some advantages in that it has a clear start and close
which allows embedding formats, however it loses much of this in that
manipulators count as arguments unlike the 2 others.

It has a few problems currently in that it always copies by value
and at least I believe may cause incorrect selection or operators.
It is also in question how many templates it will end up
implementing because every set of arguments forms its own unique
format function. Inventing a syntax is also somewhat problematic.

  http://www.egroups.com/files/boost/format/,

This one was the closest to boost acceptance.

-----------------------------------------------------------------------
The third is mine and was developed independently for use in the
GNOME project. It is stream based and uses template proxies. Unlike
either of the previous it was targeted specifically for gcc and
UTF-8 that it does not have charT specs.

Its features use of Unix 98 printf format extended to such
that the indicators specify formating rather than type. Thus
it is very compact while still allowing specification with C++
like manipulators.

It is written to appear as close as possible to a normal
manipulator just changing the arguments following it.

cout << format("%s chickens can be found in coop number %d.\n")
   << chicken_cnt << coop_num;
cout << format("Dans la cage le numéro %2$d, on y trouve %1$s poulets.\n")
   << chicken_cnt << coop_num;
cout << format("%s costs %.2f\n") << item << price;

(optional endf to stop formating not shown.)

(or if precision is variable
  cout << format("%s costs %f\n") << item << precision(2) << price;
)

It proposes to add a string formatter as well, which allows embedding

cout << format("The Truth is %^20s\n")
     << (string_format("%f != %f") << 1 << 2);
cout << format("The Truth is %^25s\n") << setfill('.')
     << (string_format("%.5f != %f) << 1.9999 << 2.000 );

The benefits, use of current standard and easy non-sticky manipulators,
are balanced against disadvantages, allowing C indicators to loss meaning
(%s means any literal type) and the inherent ambiguities of
where does the format end.

It is not close to boost submission in that a good deal of work
will be necessary to make it conform. I merely sent it for
preliminary review.

----------------------------------------------------------------------

There were about several other pieces of code linked to earlier threads.
One was like number 3 but attempts to error check the printf
resulting in many limitations, a serious mistake in my mind.

Okay that about wraps up the summary. Clearly having a
format command in boost is a good idea, but the implementation
has a rather large design area.

Things to be decided like

       stream/manipulator like verses function like
  Unix 98 printf specification verses creating our own format
       simple positional verses handles formating
       full charT verses just a ostream and wostream version

--Karl


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