Figured out how to serialize a shared_ptr<string>
authorDiane Trout <diane@caltech.edu>
Thu, 7 Sep 2006 00:34:30 +0000 (00:34 +0000)
committerDiane Trout <diane@caltech.edu>
Thu, 7 Sep 2006 00:34:30 +0000 (00:34 +0000)
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.

alg/sequence.cpp
alg/sequence.hpp
alg/test/test_sequence.cpp

index b2fa0114a3676f5dbf0e7a9b9d336449d1485548..e318207e93b06c31e6d86ca6095dd5b66b0724f1 100644 (file)
@@ -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<std::string> new_seq(new std::string);
+  boost::shared_ptr<seq_string> new_seq(new seq_string);
   new_seq->reserve(count);
 
   // Make a conversion table
index 34c28b69b26972dc9b64db3afc06eee7c1c5c06a..6c5b3b62018ce87f100c0a66ee78d80922f4b6ff 100644 (file)
 #include <boost/filesystem/fstream.hpp>
 
 #include <boost/serialization/base_object.hpp>
+#include <boost/serialization/export.hpp>
 #include <boost/serialization/list.hpp>
 #include <boost/serialization/nvp.hpp>
 #include <boost/serialization/string.hpp>
 #include <boost/serialization/shared_ptr.hpp>
 #include <boost/serialization/utility.hpp>
-#include <boost/serialization/export.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/vector.hpp>
 
 #include <boost/shared_ptr.hpp>
 
-#include <list>
-#include <string>
-#include <vector>
 #include <iostream>
 
 // 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<class Archive>
+  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<std::string>(*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<const std::string> seq;
+  boost::shared_ptr<seq_string> 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
index 350deed58d440465b9c3954096c0ae0fad12d9c8..c6a4ca6346afdefec6eedf926b22e31c00dc4e2e 100644 (file)
@@ -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());
+}