use shared_ptr to store the sequence string
[mussa.git] / alg / sequence.cpp
index f6065971eec8ace25f503554670d0828722d0d90..550d7477b2cc3af7ae96a2a8056275d4bed37ba5 100644 (file)
@@ -83,9 +83,6 @@ const std::string Sequence::nucleic_iupac_alphabet("AaCcGgTtUuRrYyMmKkSsWwBbDdHh
 const std::string Sequence::protein_alphabet("AaCcDdEeFfGgHhIiKkLlMmNnPpQqRrSsTtVvWwYy\012\015");
 
 Sequence::Sequence()
-  :  seq(""),
-     header(""),
-     species("")
 {
 }
 
@@ -257,8 +254,8 @@ void Sequence::set_filtered_sequence(const std::string &old_seq,
 
   if ( count == 0)
     count = old_seq.size() - start;
-  seq.clear();
-  seq.reserve(count);
+  boost::shared_ptr<std::string> new_seq(new std::string);
+  new_seq->reserve(count);
 
   // Make a conversion table
 
@@ -284,8 +281,9 @@ void Sequence::set_filtered_sequence(const std::string &old_seq,
   // finally, the actual conversion loop
   for(std::string::size_type seq_index = 0; seq_index < count; seq_index++)
   {
-    seq.append(1, conversionTable[ (int)old_seq[seq_index+start]]);
+    new_seq->append(1, conversionTable[ (int)old_seq[seq_index+start]]);
   }
+  seq = new_seq;
 }
 
 void
@@ -473,7 +471,7 @@ Sequence::subseq(int start, int count) const
   if ( count == npos || start+count > size()) {
     count = size()-start;
   }
-  Sequence new_seq(seq.substr(start, count));
+  Sequence new_seq(seq->substr(start, count));
   new_seq.set_fasta_header(get_fasta_header());
   new_seq.set_species(get_species());
 
@@ -542,7 +540,7 @@ Sequence::rev_comp() const
   // finally, the actual conversion loop
   for(seq_i = len - 1; seq_i >= 0; seq_i--)
   {
-    table_i = (int) seq.at(seq_i);
+    table_i = (int) seq->at(seq_i);
     rev_comp += conversionTable[table_i];
   }
 
@@ -589,57 +587,60 @@ void Sequence::set_sequence(const std::string& s)
 
 std::string Sequence::get_sequence() const
 {
-  return seq;
+  return *seq;
 }
 
 Sequence::const_reference Sequence::operator[](Sequence::size_type i) const
 {
-  return seq[i];
+  return seq->at(i);
 }
 
-Sequence::const_reference Sequence::at(Sequence::size_type n) const
+Sequence::const_reference Sequence::at(Sequence::size_type i) const
 {
-  return seq[n];
+  return seq->at(i);
 }
 
 void
 Sequence::clear()
 {
-  seq.clear();
+  seq.reset();
   header.clear();
   species.clear();
   annots.clear();
   motif_list.clear();
 }
 
-Sequence::iterator Sequence::begin()
-{
-  return seq.begin();
-}
 
 Sequence::const_iterator Sequence::begin() const
 {
-  return seq.begin();
-}
-
-Sequence::iterator Sequence::end()
-{
-  return seq.end();
+  if (seq)
+    return seq->begin();
+  else 
+    return Sequence::const_iterator(0);
 }
 
 Sequence::const_iterator Sequence::end() const
 {
-  return seq.end();
+  if (seq)
+    return seq->end();
+  else
+    return Sequence::const_iterator(0);
 }
 
 bool Sequence::empty() const
 {
-  return seq.empty();
+  if (seq)
+    return seq->empty();
+  else
+    return true;
 }
 
 Sequence::size_type Sequence::size() const
 {
-  return seq.size();
+  if (seq)
+    return seq->size();
+  else
+    return 0;
 }
 
 Sequence::size_type Sequence::length() const
@@ -695,7 +696,8 @@ Sequence::load_museq(fs::path load_file_path, int seq_num)
       seq_counter++;
   }
   getline(load_file, file_data_line);
-  seq.assign(file_data_line);
+  // looks like the sequence is written as a single line
+  set_filtered_sequence(file_data_line);
   getline(load_file, file_data_line);
   getline(load_file, file_data_line);
   if (file_data_line == "<Annotations>")
@@ -911,7 +913,7 @@ Sequence::find_motif(const Sequence& a_motif) const
 void
 Sequence::motif_scan(std::string a_motif, std::vector<int> * motif_match_starts) const
 {
-  std::string::const_iterator seq_c = seq.begin();
+  std::string::const_iterator seq_c = seq->begin();
   std::string::size_type seq_i;
   int motif_i, motif_len;
 
@@ -1053,7 +1055,16 @@ bool operator<(const Sequence& x, const Sequence& y)
 
 bool operator==(const Sequence& x, const Sequence& y) 
 {
-  if (x.seq == y.seq and x.annots == y.annots and x.motif_list == y.motif_list) {
+  if (x.empty() and y.empty()) {
+    // if there's no sequence in either sequence structure, they're equal
+    return true;
+  } else if (x.empty() or y.empty()) {
+    // if we fail the first test, and we discover one is empty,
+    // we know they can't be equal. (and we need to do this
+    // to prevent dereferencing an empty pointer)
+    return false;
+  } else if ( *(x.seq) == *(y.seq)) { 
+    // and x.annots == y.annots and x.motif_list == y.motif_list) {
     return true;
   } else {
     return false;