Boost logo

Boost :

From: Jonathan Turkanis (technews_at_[hidden])
Date: 2004-11-11 14:09:12


"Pavel Vozenilek" <pavel_vozenilek_at_[hidden]> wrote in message
news:cmu1n0$p1j$1_at_sea.gmane.org...
> > I've just finished documenting a small library, available here:
> >
> > http://home.comcast.net/~jturkanis/format_lite/
> >
> I took (brief) look and have question about feasibility of other idea:
>
> - would it be possible to combine format_lite functionality with
> Boost.Serialization to take advantage of both libs?
>
>
> Imagine solution like:
>
> // the formatting info is provided via boost::archive compatible object
> formatted_text_oarchive arch(a_ostream, default_formatting_settings ....);
>
> arch << my_data;
>
>
> class MyObject
> {
> template<class Archive>
> void serialize(Archive& ar, const unsigned) {
> .... normal serialization code, used when we DO NOT do formatting
> output
> }
> // specialization for debug formatting
> template<>
> void serialize<formatted_text_oarchive>(....) {

I believe this specialization is illegal. You could write

        void serialize(formatted_text_oarchive&ar, const unsigned)

but I can't say whether this will work (I seem to remember Robert saying
somewhere in the documentation that he was relying on the fact that
non-templates are better matches than templates.)

> ar << my_vector; // default formatting will apply
>
> ar << "some info text...";
> ar.increase_indentation();
>
> // use different formatting for next vector
> punctuate<vector<...>(ar)(....);
> ar << my_other_vector;
> }
> };

I have two separate ideas for formatting libraries:

- one lightweight, which I posted, for input and output of ranges and
tuples-like objects
- one for output only, which allows much more customization; I see this as an
inverse of Spirit

Your suggestion looks similar to the second (except that you want to support
input), so let me sketch my idea (which has improved since I sketched it here
last time), and then ask some questions about yours.

----
The motivation for both libraries is that the mechanism provided by the standard
library for formatted output (overloading operator<<) leaves all the work to the
designer of the type to be formatted. The designer determines the extent to
which formatting is customizable, if at all. In particular, the user has no say
about how nested objects are formatted, unless they are formatted by delegating
to ostream::operator<<, in which case the user is at the mercy of the designer
of the nested type.
----
The main limitation of Format Lite is that at the point where an object is
formatted:
      out << obj
the static type of obj is available, but the static type of any fancy formatting
information added to out has been collapsed to some concrete type known in
advance. My idea is to solve this problem with an ostream wrapper that has an
ostream-compatible interface and contains stylistic information as part of its
static type:
     ostream out;
     catfish fish;
     styled_ostream<cajun_style> cajun_out(out);
     cajun_out<< fish; // formats fish using cajun_style
The main template is
    template<typename Style, typename Ch, typename Tr>
    struct styled_ostream;
Concepts:
   Formatter
       - provides access to a boolean metafunction which returns true for types
which can be formatted by its instances
       - defines a templates operator() like so
          struct Formatter {
               /* ... */
               tempalte<typename StyledOstream, typename T>
               void operator()(StyledOstream& out, const T& t) const
               {
                   // writes t to out, using out's ostream interfaces
                   // as well as its additional styled_ostream members
               }
          };
       - formatters for sequences or tuple-like types can be specified with
expression templates, e.g.,
          str("[") << _2 << ":" _1 << ")"
   Style
         - default constructable
         - provides access to a collection of Formatters and Styles
         - for a given type, can search its collections and produce an
appropriate formatter, or a default formatter if none has been specified for
that type
         - the manner in which Formatters and Styles are composed to produce
additional Styles yields a cascading effect similar to CSS
The advantages of this approach are:
    - an arbitrary amount of contextual information, such as indentation and
numbering, can be stored in the styled_stream and accessed directly by
formatters
    - arbitrary user-defined types can be formatted non-intrusively
    - flexible formatting is built-in for sequences and tuple-like types (and
user-defined types can choose to present themselves as sequences or tuple-like
types to take advantage of this feature.)
----
"Pavel Vozenilek" <pavel_vozenilek_at_[hidden]> wrote:
> The advantages I see:
>  - the whole infrastructure of Boost.Serialization is available and ready
>    and it handles all situations like cycles. format_lite could concentrate
>    on just formatting.
This is a big plus, obviously. (However, I remember Robert saying her prefered
to keep formatting and serialization separate.)
> - the debugging output can be separated from other serialization types
>   (but doesn't need to be)
>
> - formatting directives can be "inherited" from
>   "higher level of data" to "lower levels". Newly added data would
>    not need formatting of its own by default. Change on higher level
>    would propagate itself "down".
Can you explain how this works?
> - indentation for pretty printing could be handled (semi)automatically
>   by formatting archive.
Would this involve modifying the archive interface? I'd like a formatter for a
given type (or an overloaded serialize function) to be able to access these
properties directly.
> - multiple formatting styles could be provided for any class.
It would be one formatting style for each archive type for which serialize has
been specialized, correct? Would this allow styles for various types to be mixed
freely?
> My experience is that Serialization is quite easy to use and
> lightweight enough so I do not consider it any disadvantage
> for practical use.
I've read the Serialization documentation, but haven't used it yet. I've noticed
it takes a long time to build, but this is probably because of the various
combinations of threading, debugging and linking options.My inclination is to
keep formatting separate from serialization, though, because they have different
aims. If you believe they can be integrated, without making serialization harder
to learn or sacrifying flexibility of formatting options, it should definitely
be considered.
>
> /Pavel
>
Jonathan

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