Boost logo

Boost Users :

From: Bill Lear (rael_at_[hidden])
Date: 2007-03-09 21:24:57


On Friday, March 9, 2007 at 11:47:21 (-0800) Robert Ramey writes:
>
>Second I would make this a "helper class" . Your
>special "Lear Archive" would be derived from
>an existing archive and the helper class using
>multiple inheritance. Look at the implemenation
>of shared_ptr checked into the HEADof CVS
>to see how to do this. ...

I checked out the head of CVS, but did not see anything relating
to a helper class in shared_ptr.hpp. Not sure if I'm looking
in the right place. This is how I checked it out:

% cvs -z3 -d:pserver:anonymous_at_[hidden]:/cvsroot/boost checkout boost

I'm not sure I need to use a cache of strings when saving, in fact,
I think not, but I went ahead and more-or-less followed your
instructions.

I can't seem to get this to compile, but it's getting closer.

The complete code is below my sig.

The compiler (gcc) complains:

error: 'class boost::archive::text_iarchive' has no member named 'cache'
error: 'class boost::archive::text_oarchive' has no member named 'cache'

So, it seems text_iarchive is being used as the type in the
load method, instead of ll_text_iarchive, which I guess makes sense,
but I'm not really sure how to cast to the proper archive, or if
that's even a good idea.

Also, for some reason, I can't use this idiom:

    ar << ll_string(s);

In fact, this won't work, either:

   ar << string("foo");

for some reason.

Finally, I really have no idea how to use the reset_object_address()
method. I looked through the boost code, but couldn't decipher it.

Any help appreciated.

Bill

#include <iostream>
#include <string>
#include <fstream>
#include <set>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

using namespace std;
using namespace boost;
using namespace boost::archive;

typedef set<string> cache_t;
class ll_cache {
public:
    cache_t cache;
};

class ll_text_iarchive: public text_iarchive_impl<text_iarchive>,
                        public ll_cache {
public:
    ll_text_iarchive(std::istream& is, unsigned int flags = 0)
        : text_iarchive_impl<text_iarchive>(is, flags) {}
};

class ll_text_oarchive: public text_oarchive_impl<text_oarchive>,
                        public ll_cache {
public:
    ll_text_oarchive(std::ostream& os, unsigned int flags = 0)
        : text_oarchive_impl<text_oarchive>(os, flags) {}
};

class ll_string: public string {
public:
    ll_string(const std::string& s) : string(s) {}
    ll_string() {}

    typedef mpl::true_ boost::serialization::is_wrapper;

    template <class Archive>
    void save(Archive& ar, const unsigned int version) const {
        cache_t::iterator i = ar.cache.find(*this);
        if (i == ar.cache.end()) {
            pair<cache_t::iterator, bool> p =
                ar.cache.insert(make_pair(*this, true));
            i = p.first;
        }
        ar << *i;
    }

    template <class Archive>
    void load(Archive &ar, const unsigned int version) {
        string t;
        ar >> t;
        cache_t::iterator i = ar.cache.find(t);
        if (i == ar.cache.end()) {
            pair<cache_t::iterator, bool> p =
                ar.cache.insert(make_pair(t, true));
            i = p.first;
        }
        static_cast<string>(*this) = t;
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};

BOOST_CLASS_TRACKING(ll_string, boost::serialization::track_never)

int main(int ac, char* av[]) {
    {
        string a("test");;
        string b = a;
        ofstream ofs("foo", ios::binary);
        ll_text_oarchive oa(ofs);
        ll_string x(a);
        oa << x;
        ll_string y(b);
        oa << y;
    }
    ll_string a;
    ll_string b;
    ifstream ifs("foo", ios::binary);
    ll_text_iarchive ia(ifs);
    ia >> a;
    ia >> b;
}


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