From: Jonathan Turkanis (technews_at_[hidden])
Date: 2004-09-24 11:28:32
"Vladimir Prus" <ghost_at_[hidden]> wrote in message
> Hi Jonathan,
> > I see the library as the inverse of Spirit. Spirit takes a linear text
> > and
> > builds complex objects, while the output formatting library takes complex
> > objects and renders them as linear text.
> Interesting! Hartmut Kaiser has expressed the similar view (off-list).
> > II. A system for allowing user-defined type to advertise their internal
> > structure, so that they can be accessed like the types in I. For example,
> > a Dog class might advertise that it consists of a string name and a float
> > weight. There are a number of ways that this could be done, such as with
> > members-pointers, default-constuctible functors which extract the
> > information, etc. Any combination of these techniques should be allowed.
> Isn't this close to using 'serialize' for extracting members, that I
Could you repeat how this would work? I considered allowing user defined types
to provide a function (member or non-member) which returns a list of members for
use in serialization; unfortunately this was very wastefull in the (common) case
that you don;t need to use all the information
> > III A framework of composable formatting objects (I'm using the term
> > differently than the current library does) used to customize how complex
> > types are output.
> > A. The main building block is the concept of a Formatter (sketched
> > below).
> > There will be a number of built-in formatters, such as
> > 1. sequence_formatter, for formatting objects of a type I.A.1.
> > using
> > specified opening, closing and separator strings
> > 2. nary_formatter<N>, for formatting objects of a type I.A.2. Nary
> > formatters can be specified with expression templates -- e.g.,
> > str("[") << _2 << " : " << _1 << ")"
> > would format a pair (a, b) as [b : a). (Note the reversed order.)
> Wow, that's nice coincidence, here's a part of email I've sent to Hartmut
> Maybe, 'list_'
> should accept two parameters?
> list_(';', str("(") << _1 << "," << _2)[phoenix::val(v)]
> There's still a question where do you specify the stream... but basically,
> the model that each formatter is just a functional object is a very simple
> one, and that's good.
> > C. A single function boost::io::format, which takes an arbitrary type
> > and
> > returns an object which can be output using operator<<. Examples:
> > cout << boost::io::format(obj); // Uses the default style
> > cout << boost::io::format(obj).with(dog_format()) // Doggy-style
> > cout << boost::io::format(obj) // Uses a complex style
> > .use< is_vector<_> >( sequence_format("[", ",", "]")
> > .use< is_pair<_> >( str("(") << _1 << ":" << _2 << "]"
> > );
> Oh, MPL lambda? That's a cool idea! But isn't this a bit too flexible? At
> all events, the smaller the size of the headers I need to include, the
Maybe lamda support could be enabled at user option. Anyway, soon compilers will
have mpl built in, so it should be no problem;-)
> > Finally, let me describe what a formatter looks like. It is a class type
> > with a templated member function format having the following signature
> > template<typename Ch, typename Tr, typename T, typename Context>
> > basic_ostream<Ch, Tr>&
> > format(basic_ostream<Ch, Tr>& out, const T& t, Context& ctx);
> > Here T is the type whose instance is to be formatted, and ctx contains the
> > prevailing Style (a combination of formatters)
> If 'format' is a member of formatter, then why context should store some
> other formatter? Or are they formatters for nested types?
Right. A 3-ary formatter might do this (by the way, the return type should be
template<typename Ch, typename Tr, typename T, typename Context>
format(basic_ostream<Ch, Tr>& out, const T& t, Context& ctx)
out << "<"
<< ctx::format(get<0>)(t) << ","
<< ctx::format(get<1>)(t) << ","
<< ctx::format(get<2>)(t) <<
> - Volodya
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk