Boost logo

Boost :

Subject: [boost] [Serialization] How to force an archive to store true_type even if it is this_type?
From: nico (nicolas.guillot_at_[hidden])
Date: 2012-04-18 12:20:13


Hello.

When we serialize a polymorphic object, an archive stores the information
about true_type (i.e. the concrete type of an object) only if it is not
equal to this_type (i.e. the type of the serialized object).

I.e. : the type of the serialized object is stored only if it is serialized
from a base class.

How can I force the archive to always store the type?

Let's illustrate with a sample, I'm not sure the above text is so
obvious...:

Let's have 2 classes serializable:

class Base { ... };
class Leaf : public Base { ... };

If I do :
    std::stringstream ios(std::ios_base::binary | std::ios_base::out |
std::ios_base::in);

* Base** b = new *Leaf*();
    boost::archive::text_oarchive ar(ios);
    ar & b;

Then the archive contains:
    22 serialization::archive 9 0 4 *Leaf* 1 0
    0 0 0 0 0 0 0
It contains the Leaf concrete type information.

However if I do :
* Leaf** b = new *Leaf*();
    boost::archive::text_oarchive ar(ios);
    ar & b;

Then the archive contains:
    22 serialization::archive 9 0 1 0
    0 0 0 0 0 0 0
It doesn't contain Lef type info.

How can I produce an archive WITH the true_type all the type?

I search 2 ways:
    - calling a method of archive type (register_type, save_pointer, ...)
unsuccessfully
    - directly change the boost/archive/detail/oserializer.hpp file:
in struct polymorphic, in function template<class T> static void
save(Archive &ar, T & t)
I comment out
            if(*this_type == *true_type){
                const basic_pointer_oserializer * bpos = register_type(ar,
t);
                ar.save_pointer(vp, bpos);
                return;
            }
unsuccessfully.

Thank you for help.

Nicolas.

PS : a word about why I'm trying to do that.
When the true_type is "registered" (I'm not sure register is the right
word), we can deserialize the object to any base class.
Exemple:

    SERIALIZATION:
        Leaf* leaf = new Leaf();
        ar & leaf;

    SERIALIZATION:
        Base* b = 0;
        ar & b; // would work only if Leaf has been saved in the archive as
true_type

For tools in a multi-team project, it' powerfull : data for tests has been
serialized by a team, and the other team can deserialize, let's say an
image, to the interface class IImage without asking: what was the true_tyep
: an Image3D, an AImage2D, an Image2DRGB, an Image2DRAW, and so on.


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