Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2004-11-12 15:28:41


"Jonathan Turkanis" <technews_at_[hidden]> wrote in message
news:cn31ps$64u$1_at_sea.gmane.org...

>
> > > You mean no changes to the library code -- we would just define
additional
> > > archive concepts and types?
> >
> > additional archive types.
>
> If the archives are to have additional member functions, as Pavel
suggested, it
> would probably be good to codify them with a new archive concept.

I understand Pavel's proposals to be more specialized serialiizations. This
can be either more specialized member templates or more specialized free
templates. The idea that an archive is totally independent of the types it
serializes would remain intact. What would happen is that now the
serialization of a selected classes would be dependent upon the type of
archive used.

If we wanted a special type of archive, we could derive from an existing one
just to get a new type which can be used to specialize the templated
serialze function

>
> > > What I meant to ask can be illustrated by an example. Suppose you have
two
> > > classes, Duck and Goose. Duck and Goose each have two associated
> > > formatting styles. The choice of styles should be independent, so we
would
> > > need four archive types to handle the various combinations.
> > >
> > > Now my question is: would Duck need four specializations of serialize,
or
> > > just two? In my system, formatting options for Duck and Goose could be
> > > added to a Style independently; I want to know if overloading
serialize can
> > > handle this.
> >
> > Its not clear to me how this would be done with your proposal.
>
> It would look something like this:
>
> struct Duck;
> struct Gooose;
>
> struct DuckStuffedWithPork
> : single_class_formatter<Duck>
> {
> template<typename StyledOstream>
> void operator()(StyledOstream& out, const Duck& d)
> { /**/ }
> };
>
> struct BlackenedGoose
> : single_class_formatter<Goose>
> {
> template<typename StyledOstream>
> void operator()(StyledOstream& out, const Goose& d)
> { /**/ }
> };
>
> struct cajun_style
> : style<
> use<Duck, DuckStuffedWithPork>,
> use<Goose, BlackenedGoose>
> >
> { };
>
> styled_ostream<cajun_style> cajun_out(cout);
>
> If DuckStuffedWithPork and BlackenedGoose weren't default constructible,
I'd
> have to write a cajun_style constructor sepcifying instances of these
types.
>
> > Whatever method you use to implement this idea with the
> > formating library would carry over to the implementation of the same
idea
> > with the serialization library.
>
> >From what you and Pavel are saying, I'm hoping the above could be
implemented
> just by defining a templated archive type parameterized by a Style:
>
> template<typename Style, ... >
> class styled_oarchive;
>
> > What Pavel's idea does is to introduce the idea of an archive format
> > selector which would choose between different desired formats.
> >
> > Of course the formt library could easily do the same thing by defining
> > derivations from output streams and implementing different versions of
> > operator<< for each one. The usage would be identical.

I don't really understand the above example but here is what I think you
want to do using free serialization functions.

// default serialization
template<class Archive>
void serialize(Archive &ar, Duck &d){
    ar & d;
}

// serialization cajun style
template<>
void serialize(cajun_style_oarchive &ar, Duck &d){
    ar & punctuation("&*^#@#@&" & d;
}

// define a type for cajun style archives// this is just a named wrapper for
text archives.
class cajun_style_archive : public text_archive
{};

// serialize normal style
Duck d;
text_oarchive tar;
tar << d;

// serialize cajun style
cajun_style_oarchive car;
car << d;

That would be about it.

Of course you're serialize template specialization could be as elaborat as
you which to accomodate some program drivien customization. Notice that
none of requires alteration of either the classes to be serialized or the
archives used.

> I prefer to definine an ostream wrapper with an ostream-compatible
interface.
> This way you can use several different wrappers with the same ostream and
> there's no possibility of passing it to a function taking an ostream&
argument,
> which would cause the formatting information to be lost.

I think that's what I meant to say.

> > > 2. If a type defines a member function serialize, can it be bypassed
> > altogether
> > > in favor of an end-user supplied formatting style?
> >
> > one would define a member function serialize for a specific archive
class.
> > This would bypass the standard templated one generally defined.
>

> Would the member function be a member of the archive or the type to be
> formatted?

of the type to be serialized/formatted not of the archive. see above

> I'd like to be able to tell an archive to format a Duck in a
> particular way whether the Duck likes it or not.

Then you wouldn't specialize the duck serialization for this particular type
of archive and it would just use the default one. Or you would

> > > Would this really be desirable for human-readable output? Perhaps the
> > > formatting
> > > library should concern itself only with cycle-free data structures.
> >
> > Your library is very attractive and easy to use. I can imagine that
people
> > will find it attractive and start to use it. Then you start to get
requests
> > like, can I use it for pointers?, what about multiple copies, what about
> > built in support for arrays, etc on and on and on. The your very
readable
> > document starts to get cluttered up with special cases (e.g. cycles,
> > pointers, etc), and your code starts to get complicated with code to
detect
> > violations (e.g. detecting cycles, etc). You really can't get the
monkey
> > off your back until you end up covering just about everything. oh - but
> > then its not simple anymore and you have to go back and try to
> > re-rationalize it. The point is that the serialization library has
already
> > been through that mill - and more or less emerged intact.
>
> Okay, I get the picture ;-)
>
>
> Regarding pointers, would you agree that most of the thorniest issues
relating
> to pointers disappear if you concern yourself with output only, since you
> wouldn't have to detect or record the fully derived type or have a
mechanism for
> constructing new objects?

Hmm - maybe - about 5 seconds reflection raise questions like - what about
pointers to abstract base classes. Should they serialized the named class,
or the most derived class. Should the library use be permited to choose? If
so how would he do this. What about systems that don't support RTTI?

>Would cycle-detection be the only remaining issue? Note the question of
cycles is not limited to pointers. References could also cycle

I have no idea
>

> By multiple copies, do you mean multiple pointers that point to the same
object?
> I think an output formatting library should just output each as if the
other
> didn't exist.

If you want to avoid an infinite loops if a cycle occurs, then you'll
automatically have multiple detection. Will some user ask for a method to
inhibit/enable this?

As I've said before, its not really a technical issue. Its a question of
what happens when supplies an elegant solution to part of a hard problem.
Depending on the problem domain, that may be just fine. With serialization
its exceedingly annoying to start using the system and start to depend upon
it only to find that there's an area where you can't use it. Then you're
faced with making some sort of kludge to get around it. and the whole
appeal of having a "definitive" solution goes out the windows and users
howl.

Its a slippery slope. Once you start its hard to stop until you get to the
end.

Robert Ramey


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