Boost logo

Boost Users :

Subject: Re: [Boost-users] Usingboost::serializationinreal-timewithoutallocating memory
From: Peter Soetens (peter.soetens_at_[hidden])
Date: 2009-09-21 17:44:58


On Mon, Sep 21, 2009 at 21:25, Robert Ramey <ramey_at_[hidden]> wrote:
> Stefan Strasser wrote:
>> Am Monday 21 September 2009 20:27:59 schrieb Robert Ramey:
>>> Stefan Strasser wrote:
>>>> I think to support this an other use cases like it common_archive
>>>> would have to be moved outside of the linked library into a header
>>>> and be made more generic.
>>>
>>> common_archive is a template - it's not in the linked library.
>>
>> ok, I must have mixed up some types. the point was that the ultimate
>> base class, that handles the type registration and object tracking
>> etc., is
>> linked .cpp and not very configurable.
>> the optimum case imho would be that you could pass a traits class to
>> that archive base class, that gets called whenever there is an object
>> or type to be registered and is queried for existing objects and
>> types later on.
>> that way you could disable registration, save type registration
>> outside of the archive itself, let type registration span multiple
>> archives etc, make sure type registration doesn't allocate etc.
>
> as I alluded to before - what I would like to know is why I derived
> trivial_archive from common_archive.  I don't remember what
> made me do this.  It seems that if this isn't done then save/load_object
> is necessary.  So the question is - why is this?  It is an oversight
> somewhere? or does the archive concept have to be changed.
>
> Personally, I generally don't like the "traits class" as an argument.
> It sort of implies that that the template has a lot of "if -" code
> which navigates the traits. A "policy class" is better but can
> still make things complex.  Personally I prefer composition
> of funtionality through inheritance. This can be seen in
> the class diagram for the serialization library. And your example
> makes me more convinced than ever that this is basically
> right.  Now the only loose end it investigate why save/load
> object is required.

I found a lead to that. When the archive calls archive::save, a chain
of 'invoke' calls is done to select the right serialization method for
type T. When I pass std::vector<double> as T, it encounters a branch
in oserializer.hpp:245, in struct 'save_conditional::invoke' .

<code>
    // adds class information to the archive. This includes
    // serialization level and class version
    struct save_conditional {
        static void invoke(Archive &ar, const T &t){
            //if(0 == (ar.get_flags() & no_tracking))
                save_standard::invoke(ar, t);
            //else
            // save_only::invoke(ar, t);
        }
    };
</code>

 The alternative branch is commented out, but let that be the path
that needs to be taken by my code. Current code calls save_standard,
which calls directly ' ar.save_object'. save_object in turn depends on
basic_oarchive to do its job. If save_only was taken, the
'non-basic_oarchive' serialization code path would have been taken.

For some reason (I've spent an hour staring at it), my unit test did
not discover this flaw in my code and does as if serialisation of the
std::vector was fine. I'm overlooking something stupid clearly...

Anyway, as it seems now, the code path taken by archive::save/load
mandates derivation of basic_?archive. Maybe I should have called
another 'selection' function ? like archive::save_only directly ?

Peter


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net