Boost logo

Boost Users :

From: Robert Ramey (ramey_at_[hidden])
Date: 2008-04-08 12:20:36


Jeffrey A. Edlund wrote:
> I'm trying to serialize a hierarchical data structure like the
> following:
>
> class StorageVar;
>
> typedef std::vector<StorageVar> sv_list;
> typedef std::map<std::string, StorageVar > sv_dict;
> typedef std::pair<std::string, StorageVar > sv_dict_pair;
>
> typedef boost::variant <
> boost::shared_ptr<size_t>,boost::shared_ptr<int>,boost::shared_ptr<double>,boost::shared_ptr<std::string>,
> boost::shared_ptr<std::vector<size_t> >,
> boost::shared_ptr<std::vector<int> >,
> boost::shared_ptr<std::vector<double> >,
> boost::recursive_wrapper<boost::shared_ptr< sv_list > >,
> boost::recursive_wrapper<boost::shared_ptr< sv_dict > >,
> boost::recursive_wrapper<boost::shared_ptr< sv_dict_pair > > >
> StorageVar_data_imp;
>
> class StorageVar_imp {
> public:
> StorageVar_imp(): data(new StorageVar_data_imp) {};
> boost::shared_ptr<StorageVar_data_imp> data;
> boost::shared_ptr<sv_dict> attributes;
> };
>
> class StorageVar {
> public:
> boost::shared_ptr<StorageVar_imp> content;
> StorageVar(): content(new StorageVar_imp) {};
> /* Further functionality removed for clarity. */
> }
>
> I had been hoping to serialize this nonintrustively, but quickly ran
> into problems. Here's my understanding of the situation: As has been
> mentioned on the list before, Boost.Serialize refuses to serialize
> shared_ptrs to primitive types because tracking is turned off for
> primitive types and cannot be turned on. Primitive types used in my
> example include size_t,int,double, and std::string. I can understand
> (sort of) why you wouldn't want to track all the numeric types, but I
> don't understand why std::string is considered now considered a
> primitive. (Looking at boost/serialization/string.hpp indicates that
> it wasn't a primitive type at some point.)

I didn't want to make std::string a primitive type. It just turned
out I had to do it get out of a corner related to the fact that
std::string type is used in the serialization header. I also felt
that accidently tracking every std::string probably would't
be a good idea in any case - so here we are.

> The way that's mentioned in the archive to get around this is to use
> BOOST_STRONG_TYPEDEF(int,tracked_int) etc. This would require that I
> change the data structure (an intrusive change) and add a static_cast<
> T&>(variable) everywhere these wrapped variables are used. (This is
> because the "strong" typedef really just makes a new class with your
> type inside it with basic methods defined.)

I think you could make a temporary wrapper something like

    ar & static_cast<BOOST_STRONG_TYPEDEF(int, tracked_int) &> i

I don't think the follow should be necessary, but maybe it is.

class template<class Archive>
serialize(
    Archive &ar,
    BOOST_STRONG_TYPEDEF(int, tracked_int) & i,
    const unsigned version
){
    ar & i;
}

> I might be missing something, but couldn't
> boost/serialization/shared_ptr.hpp be rewritten to keep track of all
> the pointers that it sees without turning tracking on for all primitive
> types?

LOL - be my guest. boost::shared_ptr does not meet the requirements
of the "serializable concept". Hence it has to be turned into something
that does and that is what is serialized. Sure its inefficient - but its
the
only think that can be done under the circumstances.

> Basically just automatically track anything that's inside a
> shared_ptr. The programmer shouldn't be storing both a shared_ptr to
> memory and a normal pointer to the same memory anyway.

Robert Ramey


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