Boost logo

Boost :

From: Matthias Troyer (troyer_at_[hidden])
Date: 2002-02-08 12:29:32


Maybe I miss the point but I don't see how this will work. In

//-----------------------------

// Class A uses Jens Maurer binary_stream
// to serialize

struct A
        {
        int I;
        };

DECLARE_SERIAL( A );

std::streambuf& operator<<( std::streambuf& dest, const A& a )
        {
        binary_stream s( &dest );
        s << I;
        return dest;
        }

std::streambuf& operator>>( std::streambuf& src, const A& a )
        {
        binary_stream s( &src );
        s >> I;
        return src;
        }

you explicitly write the stream type (binary_stream) in the
(de)serialization functions for the class A. Thus as far as I
can see, you only use one type of stream ever. In my applications
I use usually two, for debugging three types of streams all the time.
These are:

i) the binary_stream (or no stream at all) for message passing between
    nodes

ii) the XDR_Stream for writing portable checkpoint files

iii) sometimes ascii-based streams using standard iostreams
      for debugging

As I don't want to duplicate code I don't see a way around either
runtime or compile time polymorphism on the stream. Can you explain
how this would work in your approach?

Best regards,

Matthias

On Friday, February 8, 2002, at 06:15 PM, quendezus wrote:
>
> It is possible to templatized the whole system on the stream type. I
> have tried and it seems to work. But doing so, I realized that it is
> not necessary a good thing, for the following reasons:
>
> - 1 -
>
> If the user gives an asymetrical stream (like stringstream,
> filestream, etc.), the result is undefined. As Jens Maurer says in
> persistence2/persistence.zip/persistence.html :
>
> "Traditionally, these shift operators have been used to provide user-
> readable input and output. However, it is not always ensured that the
> output of operator<< can be used by operator>> to produce an object
> which is equivalent to that written. For example, writing a string
> with an embedded newline will produce two strings upon reading."
>
> If the stream was only to serialize the user's data, it would not be
> a problem (he gives a stream and then manages to put his data in it,
> we don't care how he does so). The problem is that the framework
> needs also to put data in the stream, like type infos.
>
> To make the stream "safe", Jens Maurer applies a Reader or a Writer
> object to the stream. So you have a stream buffer, with a stream on
> top, then a writer or a reader on top.
>
> - 2 -
>
> If you templatized the system on the stream type, it is difficult for
> the user to be consistent : he must uses the same stream type in many
> places, including his shift operators, the call to the serialize
> functions, etc.
>
> Moreover, it is not logic that the serialize functions should be
> templatized on the stream type. For me, a stream is a formating
> mechanism on top of a stream buffer. Only types should be allowed to
> choose their serialization format : it is a local choice for a type,
> which has nothing to do with the place where an object is serialized.
>
> --------------------------------
>
> I don't think we need an abstract base class as a stream. It seems to
> me that the framework could directly write into std::streambuf. Then,
> all user's type can use whatever stream they want to write in it, and
> the framework is free to use whatever stream it wants to write its
> internal data. Below is a pseudo code to illustrate that.
>
> What do you think ?
>
>
> Sylvain
>
>
>
> //-----------------------------
>
> // Class A uses Jens Maurer binary_stream
> // to serialize
>
> struct A
> {
> int I;
> };
>
> DECLARE_SERIAL( A );
>
> std::streambuf& operator<<( std::streambuf& dest, const A& a )
> {
> binary_stream s( &dest );
> s << I;
> return dest;
> }
>
> std::streambuf& operator>>( std::streambuf& src, const A& a )
> {
> binary_stream s( &src );
> s >> I;
> return src;
> }
>
> //-----------------------------
>
> // Class B uses no stream
> // to serialize (class B has no
> // need to be portable accross
> // little and big endians).
>
> struct B
> {
> int I;
> };
>
> DECLARE_SERIAL( B );
>
> std::streambuf& operator<<( std::streambuf& dest, const A& a )
> {
> dest.sputn( ( char* )&I, sizeof( I ) );
> return dest;
> }
>
> std::streambuf& operator>>( std::streambuf& src, const A& a )
> {
> dest.sgetn( ( char* )&I, sizeof( I ) );
> return src;
> }
>
> //-----------------------------
>
> // Class C uses XDR_Stream
> // to serialize. More difficult
> // because char_type of XDR_Stream
> // is 2 bytes long (and
> // std::streambuf is
> // basic_streambuf< char, ...>)
>
> struct C
> {
> int I;
> };
>
> DECLARE_SERIAL( C );
>
> std::streambuf& operator<<( std::streambuf& dest, const A& a )
> {
> XDR_Stream s(
> &char_to_doublechar_streambuf_converter(
> &dest ) );
> s << I;
> return dest;
> }
>
> std::streambuf& operator>>( std::streambuf& src, const A& a )
> {
> XDR_Stream s(
> &char_to_doublechar_streambuf_converter(
> &src ) );
> s >> I;
> return src;
> }
>
>
>
>
>
>
> Info: http://www.boost.org Send unsubscribe requests to:
> <mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to
> http://docs.yahoo.com/info/terms/
>


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