From: Diane Trout Date: Thu, 7 Sep 2006 00:34:30 +0000 (+0000) Subject: Figured out how to serialize a shared_ptr X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=da1e3c31d8fcf07269e06ba08a8e88e88332ca9b Figured out how to serialize a shared_ptr My previous efforts at serializing a std::string stored as a shared_ptr appear to have been foiled because the default shared_ptr serializaiton code was expecting the class serializaiton code to be part of the class member and alas std::string has out of class serialization. So the simple solution was to make a subclass of std::string whose only contribution was to define the serialization code. Also it turns out there were some problems with the BOOST_SERIALIZATION_BASE_NVP macro for the seq_string class, however when I expanded it manually, everything seemed to work. --- diff --git a/alg/sequence.cpp b/alg/sequence.cpp index b2fa011..e318207 100644 --- a/alg/sequence.cpp +++ b/alg/sequence.cpp @@ -254,7 +254,7 @@ void Sequence::set_filtered_sequence(const std::string &old_seq, if ( count == 0) count = old_seq.size() - start; - boost::shared_ptr new_seq(new std::string); + boost::shared_ptr new_seq(new seq_string); new_seq->reserve(count); // Make a conversion table diff --git a/alg/sequence.hpp b/alg/sequence.hpp index 34c28b6..6c5b3b6 100644 --- a/alg/sequence.hpp +++ b/alg/sequence.hpp @@ -18,18 +18,17 @@ #include #include +#include #include #include #include #include #include -#include +#include +#include #include -#include -#include -#include #include // Sequence data class @@ -84,6 +83,21 @@ private: }; BOOST_CLASS_EXPORT(motif); +//! the only purpose of this class is that the shared_ptr template +//! functions need the serialization support to be in-class. +class seq_string : public std::string +{ +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int /*version*/) { + //ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(std::string); + ar & boost::serialization::make_nvp("bases", + boost::serialization::base_object(*this) + ); + } +}; + //! sequence track for mussa. class Sequence { @@ -213,7 +227,7 @@ public: void load_museq(boost::filesystem::path load_file_path, int seq_num); private: - boost::shared_ptr seq; + boost::shared_ptr seq; std::string header; std::string species; @@ -237,6 +251,6 @@ private: ar & BOOST_SERIALIZATION_NVP(motif_list); } }; -//BOOST_CLASS_EXPORT(Sequence); +BOOST_CLASS_EXPORT(Sequence); #endif diff --git a/alg/test/test_sequence.cpp b/alg/test/test_sequence.cpp index 350deed..c6a4ca6 100644 --- a/alg/test/test_sequence.cpp +++ b/alg/test/test_sequence.cpp @@ -482,7 +482,7 @@ BOOST_AUTO_TEST_CASE( get_name ) seq.set_fasta_header("fasta human"); BOOST_CHECK_EQUAL( seq.get_name(), "fasta human"); } -/* + BOOST_AUTO_TEST_CASE( serialize_simple ) { std::string seq_string = "AAGGCCTT"; @@ -496,7 +496,6 @@ BOOST_AUTO_TEST_CASE( serialize_simple ) BOOST_CHECK_EQUAL(seq, const_seq); oarchive << const_seq; } - Sequence seq_loaded; { std::istringstream iss(oss.str()); @@ -535,7 +534,9 @@ BOOST_AUTO_TEST_CASE( serialize_tree ) BOOST_CHECK_EQUAL(seq_loaded, seq); } -BOOST_AUTO_TEST_CASE( serialize_xml_tree ) +// this writes out an "old" style annotated sequence +// with annotations attached as "motifs" and "annots" +BOOST_AUTO_TEST_CASE( serialize_xml_sequence ) { std::string seq_string = "AAGGCCTT"; Sequence seq(seq_string); @@ -551,15 +552,43 @@ BOOST_AUTO_TEST_CASE( serialize_xml_tree ) boost::archive::xml_oarchive oarchive(oss); const Sequence& const_seq(seq); BOOST_CHECK_EQUAL(seq, const_seq); - oarchive << boost::serialization::make_nvp("seq", const_seq); + oarchive << boost::serialization::make_nvp("root", const_seq); } - Sequence seq_loaded; { std::istringstream iss(oss.str()); boost::archive::xml_iarchive iarchive(iss); - iarchive >> boost::serialization::make_nvp("seq", seq_loaded); + iarchive >> boost::serialization::make_nvp("root", seq_loaded); } BOOST_CHECK_EQUAL(seq_loaded, seq); } -*/ + +BOOST_AUTO_TEST_CASE( serialize_xml_two ) +{ + std::string seq_string = "AAGGCCTT"; + Sequence seq1(seq_string); + Sequence seq2(seq1); + + std::ostringstream oss; + // allocate/deallocate serialization components + { + boost::archive::xml_oarchive oarchive(oss); + const Sequence& const_seq1(seq1); + const Sequence& const_seq2(seq2); + oarchive << boost::serialization::make_nvp("seq1", const_seq1); + oarchive << boost::serialization::make_nvp("seq2", const_seq2); + } + //std::cout << "xml: " << oss.str() << std::endl; + Sequence seq1_loaded; + Sequence seq2_loaded; + { + std::istringstream iss(oss.str()); + boost::archive::xml_iarchive iarchive(iss); + iarchive >> boost::serialization::make_nvp("seq1", seq1_loaded); + iarchive >> boost::serialization::make_nvp("seq2", seq2_loaded); + } + BOOST_CHECK_EQUAL(seq1_loaded, seq1); + BOOST_CHECK_EQUAL(seq2_loaded, seq2); + // test if our pointers are the same + BOOST_CHECK_EQUAL(seq1_loaded.c_str(), seq2_loaded.c_str()); +}