|
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