Boost logo

Boost :

From: Stewart, Robert (stewart_at_[hidden])
Date: 2002-02-01 13:54:31


From: Karl Nelson [SMTP:kenelson_at_[hidden]]

[resurrecting the "A" versus "B" context]

> Does cout << format("%#010x" , complex<int>(20,21) ); mean
> A) the user wants all integers output to be show base with
> 12 charactors zero padded. 0x00000016+0x00000017i
> B) The total width should be 10 with showbase and zero padding?
> 0x16+0x17i
>
> > Still, "0x16+0x17i" is only 10 characters, so output B is what I would
> > expect to be the result.
>
> So how would you then specify you want A? Ie. If printing
> a matrix class and you want every number in the matrix printed
> some way.

There is no way for a format or IOStream object to know enough about a
user-defined type (which complex<> is not, but I think that's really what
we're talking about) to be able to supply correct behavior in all cases.
Instead, we need to give control back to the type to let it format itself
according to the prevailing format flags. Then, if the result exceeds a
maximum field width setting, were we to introduce such a thing, the format
class could truncate it or replace it by the maximum field width number of
"oops" characters.

To clarify my thinking on letting the type control its formatting, consider
this use of format():

    // "aa" and "bb" are placeholders for real format specifiers
    // x and y are objects of any type you want to consider
    std::cout << format("%aa% %bb%", x, y);

I think that could translate into something like this:

    std::cout << x.format("aa") << " " << y.format("bb");

where the mf "format" might actually be found via a traits class such that
built-in types could work the same way:

    template <typename T>
    struct FormatTraits
    {
        static void
        format(
            std::ostream & os_i,
            char const * const pFormat_i,
            T const & value_i)
        {
            value_i.format(
                os_i,
                pFormat_i);
        }
    };

    template <>
    struct FormatTraits<int>
    {
        static void
        format(
            std::ostream & os_i,
            char const * const pFormat_i,
            int const value_i)
        {
            // do something to os_i based upon pFormat_i
            os_i << value_i;
            // undo things done to os_i, if necessary
        }
    }

If someone creates a user-defined type that they want to work with format,
then they can just implement a format() mf on their type or they can
specialize FormatTraits. This puts complete control on how to handle format
flags in the hands of the user-defined class' creator.

Rob
Susquehanna International Group, LLP
http://www.sig.com


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