[Avida-SVN] r3264 - in development/source: actions drivers main targets/avida-viewer tools

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Wed May 27 10:30:41 PDT 2009


Author: brysonda
Date: 2009-05-27 13:30:41 -0400 (Wed, 27 May 2009)
New Revision: 3264

Modified:
   development/source/actions/DriverActions.cc
   development/source/actions/SaveLoadActions.cc
   development/source/drivers/cDefaultAnalyzeDriver.h
   development/source/drivers/cDefaultRunDriver.h
   development/source/drivers/cFallbackWorldDriver.h
   development/source/drivers/cWorldDriver.h
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
   development/source/targets/avida-viewer/cTextViewerAnalyzeDriver.h
   development/source/targets/avida-viewer/cTextViewerDriver.cc
   development/source/targets/avida-viewer/cTextViewerDriver.h
   development/source/targets/avida-viewer/cTextViewerDriver_Base.h
   development/source/tools/tArray.h
   development/source/tools/tArrayUtils.h
   development/source/tools/tManagedPointerArray.h
   development/source/tools/tSmartArray.h
Log:
Implement loading structured population saves.  

Also implement support for pausing the viewer via the new 'Pause' action (perhaps I should say 're-implement' since this used to exist).   The action does nothing when executed outside the viewer.

Modified: development/source/actions/DriverActions.cc
===================================================================
--- development/source/actions/DriverActions.cc	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/actions/DriverActions.cc	2009-05-27 17:30:41 UTC (rev 3264)
@@ -40,6 +40,14 @@
   void Process(cAvidaContext& ctx) { m_world->GetDriver().SetDone(); }
 };
 
+class cActionPause : public cAction
+{
+public:
+  cActionPause(cWorld* world, const cString& args) : cAction(world, args) { ; }
+  static const cString GetDescription() { return "No Arguments"; }
+  void Process(cAvidaContext& ctx) { m_world->GetDriver().SetPause(); }
+};
+
 class cActionExitAveLineageLabelGreater : public cAction
 {
 private:
@@ -197,6 +205,7 @@
   action_lib->Register<cActionExitAveGeneration>("ExitAveGeneration");
   action_lib->Register<cActionExitElapsedTime>("ExitElapsedTime");
   action_lib->Register<cActionStopFastForward>("StopFastForward");
+  action_lib->Register<cActionPause>("Pause");
 
   // @DMB - The following actions are DEPRECATED aliases - These will be removed in 2.7.
   action_lib->Register<cActionExit>("exit");

Modified: development/source/actions/SaveLoadActions.cc
===================================================================
--- development/source/actions/SaveLoadActions.cc	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/actions/SaveLoadActions.cc	2009-05-27 17:30:41 UTC (rev 3264)
@@ -161,7 +161,9 @@
     // set the update if requested
     if (m_update >= 0) m_world->GetStats().SetCurrentUpdate(m_update);
     
-    m_world->GetPopulation().LoadStructuredPopulation(m_filename);
+    if (!m_world->GetPopulation().LoadStructuredPopulation(m_filename)) {
+      m_world->GetDriver().RaiseFatalException(-1, "failed to load structured population");
+    }
   }
 };
 

Modified: development/source/drivers/cDefaultAnalyzeDriver.h
===================================================================
--- development/source/drivers/cDefaultAnalyzeDriver.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/drivers/cDefaultAnalyzeDriver.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -61,6 +61,7 @@
   // Driver Actions
   void SignalBreakpoint() { return; }
   void SetDone() { return; }
+  void SetPause() { return; }
   
   void RaiseException(const cString& in_string);
   void RaiseFatalException(int exit_code, const cString& in_string);

Modified: development/source/drivers/cDefaultRunDriver.h
===================================================================
--- development/source/drivers/cDefaultRunDriver.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/drivers/cDefaultRunDriver.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -57,6 +57,7 @@
   // Driver Actions
   void SignalBreakpoint() { return; }
   void SetDone() { m_done = true; }
+  void SetPause() { return; }
   
   void RaiseException(const cString& in_string);
   void RaiseFatalException(int exit_code, const cString& in_string);

Modified: development/source/drivers/cFallbackWorldDriver.h
===================================================================
--- development/source/drivers/cFallbackWorldDriver.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/drivers/cFallbackWorldDriver.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -42,6 +42,7 @@
   // Driver Actions
   void SignalBreakpoint() { return; }
   void SetDone() { return; }
+  void SetPause() { return; }
   
   void RaiseException(const cString& in_string);
   void RaiseFatalException(int exit_code, const cString& in_string);

Modified: development/source/drivers/cWorldDriver.h
===================================================================
--- development/source/drivers/cWorldDriver.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/drivers/cWorldDriver.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -49,6 +49,7 @@
   // Driver Actions
   virtual void SignalBreakpoint() = 0;
   virtual void SetDone() = 0;
+  virtual void SetPause() = 0;
 
   virtual void RaiseException(const cString& in_string) = 0;
   virtual void RaiseFatalException(int exit_code, const cString& in_string) = 0;

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/main/cPopulation.cc	2009-05-27 17:30:41 UTC (rev 3264)
@@ -61,8 +61,10 @@
 #include "cTestCPU.h"
 #include "cCPUTestInfo.h"
 
+#include "tArrayUtils.h"
 #include "tKVPair.h"
 #include "tHashTable.h"
+#include "tManagedPointerArray.h"
 
 
 #include <fstream>
@@ -4297,24 +4299,7 @@
   return true;
 }
 
-// This class is needed for the next function
-class cTmpGenotype {
-public:
-  int id_num;
-  int parent_id;
-  int num_cpus;
-  int total_cpus;
-  double merit;
-  int update_born;
-  int update_dead;
-  
-  cGenotype *genotype;
-  
-  bool operator<( const cTmpGenotype rhs ) const {
-    return id_num < rhs.id_num; }
-};	
 
-
 bool cPopulation::LoadDumpFile(cString filename, int update)
 {
   // set the update if requested
@@ -4336,13 +4321,13 @@
   
   // First, we read in all the genotypes and store them in a list
   
-  vector<cTmpGenotype> genotype_vect;
+  vector<sTmpGenotype> genotype_vect;
   
   for (int line_id = 0; line_id < input_file.GetNumLines(); line_id++) {
     cString cur_line = input_file.GetLine(line_id);
     
     // Setup the genotype for this line...
-    cTmpGenotype tmp;
+    sTmpGenotype tmp;
     tmp.id_num      = cur_line.PopWord().AsInt();
     tmp.parent_id   = cur_line.PopWord().AsInt();
     /*parent_dist =*/          cur_line.PopWord().AsInt();
@@ -4374,9 +4359,9 @@
   sort( genotype_vect.begin(), genotype_vect.end() );
   // set the parents correctly
   
-  vector<cTmpGenotype>::const_iterator it = genotype_vect.begin();
+  vector<sTmpGenotype>::const_iterator it = genotype_vect.begin();
   for ( ; it != genotype_vect.end(); it++ ){
-    vector<cTmpGenotype>::const_iterator it2 = it;
+    vector<sTmpGenotype>::const_iterator it2 = it;
     cGenotype *parent = 0;
     // search backwards till we find the parent
     if ( it2 != genotype_vect.begin() )
@@ -4508,11 +4493,123 @@
 
 bool cPopulation::LoadStructuredPopulation(const cString& filename)
 {
-  // @TODO - implement structured population dump loading
-  return false;
+  // @TODO - build in support for verifying population dimensions
+  
+  cInitFile input_file(filename);
+  if (!input_file.WasOpened()) {
+    tConstListIterator<cString> err_it(input_file.GetErrors());
+    const cString* errstr = NULL;
+    while ((errstr = err_it.Next())) m_world->GetDriver().RaiseException(*errstr);
+    return false;
+  }
+  
+  // Clear out the population
+  for (int i = 0; i < cell_array.GetSize(); i++) KillOrganism(cell_array[i]);
+
+  // First, we read in all the genotypes and store them in an array
+  tManagedPointerArray<sTmpGenotype> genotypes(input_file.GetNumLines());
+  const int update = m_world->GetStats().GetUpdate();
+  
+  for (int line_id = 0; line_id < input_file.GetNumLines(); line_id++) {
+    cString cur_line = input_file.GetLine(line_id);
+    
+    // Setup the genotype for this line...
+    sTmpGenotype& tmp = genotypes[line_id];
+    tmp.id_num      = cur_line.PopWord().AsInt();
+    tmp.parent_id   = cur_line.PopWord().AsInt();
+    tmp.parent_id2  = cur_line.PopWord().AsInt();    
+    /* parent_dist */ cur_line.PopWord();
+    tmp.num_cpus    = cur_line.PopWord().AsInt();
+    tmp.total_cpus  = cur_line.PopWord().AsInt();
+    /* length */      cur_line.PopWord();
+    tmp.merit 	    = cur_line.PopWord().AsDouble();
+    /* gest_time */   cur_line.PopWord();
+    /* fitness */     cur_line.PopWord();
+    tmp.update_born = cur_line.PopWord().AsInt();
+    tmp.update_dead = cur_line.PopWord().AsInt();
+    /* depth */       cur_line.PopWord();
+    cString name = cStringUtil::Stringf("org-%d", tmp.id_num);
+    cGenome genome(cur_line.PopWord());
+    
+    // Process resident cell ids
+    cString cellstr(cur_line.PopWord());
+    while (cellstr.GetSize()) tmp.cells.Push(cellstr.Pop(',').AsInt());
+    assert(tmp.cells.GetSize() == tmp.num_cpus);
+    
+    // Don't allow birth or death times larger than the current update
+    if (update > tmp.update_born) tmp.update_born = update;
+    if (update > tmp.update_dead) tmp.update_dead = update;
+    
+    tmp.genotype = m_world->GetClassificationManager().GetGenotypeLoaded(genome, tmp.update_born, tmp.id_num);
+    tmp.genotype->SetName(name);
+  }
+  
+  // Sort genotypes in ascending order according to their id_num
+  tArrayUtils::QSort(genotypes);
+  
+  
+  // Set parents correctly
+  for (int gen_i = genotypes.GetSize() - 1; gen_i > 0; gen_i--) {
+    cGenotype* parent1 = NULL;
+    cGenotype* parent2 = NULL;
+    
+    int pid = genotypes[gen_i].parent_id;
+    if (pid != -1) {
+      for (int p_i = gen_i + 1; p_i < genotypes.GetSize(); p_i++) {
+        if (genotypes[p_i].id_num == pid) {
+          parent1 = genotypes[p_i].genotype;
+          break;
+        }
+      }
+    }
+    
+    pid = genotypes[gen_i].parent_id2;
+    if (pid != -1) {
+      for (int p_i = gen_i + 1; p_i < genotypes.GetSize(); p_i++) {
+        if (genotypes[p_i].id_num == pid) {
+          parent2 = genotypes[p_i].genotype;
+          break;
+        }
+      }
+    }    
+    
+    genotypes[gen_i].genotype->SetParent(parent1, parent2);
+  }
+  
+
+  // Process genotypes, inject into organisms as necessary
+  for (int gen_i = genotypes.GetSize() - 1; gen_i > 0; gen_i--) {
+    sTmpGenotype& tmp = genotypes[gen_i];
+    if (tmp.num_cpus == 0) {
+      // historic organism - remove immediately, so that it gets transferred into
+      // the historic database. We change the update temporarily to the
+      // true death time of this organism, so that all stats are correct
+      m_world->GetStats().SetCurrentUpdate(tmp.update_dead);
+      m_world->GetClassificationManager().RemoveGenotype(*tmp.genotype);
+      m_world->GetStats().SetCurrentUpdate(update);
+    } else {
+      // otherwise, we insert as many organisms as we need
+      for (int cell_i = 0; cell_i < tmp.num_cpus; cell_i++) {
+        int cell_id = tmp.cells[cell_i];
+        
+        InjectGenotype(cell_id, tmp.genotype);
+        
+        cPhenotype& phenotype = GetCell(cell_id).GetOrganism()->GetPhenotype();
+        if (tmp.merit > 0) phenotype.SetMerit(cMerit(tmp.merit));
+        AdjustSchedule(GetCell(cell_id), phenotype.GetMerit());
+        
+        LineageSetupOrganism(GetCell(cell_id).GetOrganism(), NULL, 0, tmp.genotype->GetParentGenotype());
+      }
+    }
+  }
+  sync_events = true;
+  
+  return true;
 }
 
 
+
+
 bool cPopulation::DumpMemorySummary(ofstream& fp)
 {
   if (fp.good() == false) return false;

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/main/cPopulation.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -326,6 +326,30 @@
   
   // Let users change environmental variables durning the run @BDB 22-Feb-2008
   void UpdateResourceCount(const int Verbosity);
+  
+private:
+  struct sTmpGenotype
+  {
+  public:
+    int id_num;
+    int parent_id;
+    int parent_id2;
+    int num_cpus;
+    int total_cpus;
+    double merit;
+    int update_born;
+    int update_dead;
+    tArray<int> cells;
+    
+    cGenotype *genotype;
+    
+    inline sTmpGenotype() : id_num(-1) { ; }
+    inline bool operator<(const sTmpGenotype& rhs) const { return id_num < rhs.id_num; }
+    inline bool operator>(const sTmpGenotype& rhs) const { return id_num > rhs.id_num; }
+    inline bool operator<=(const sTmpGenotype& rhs) const { return id_num <= rhs.id_num; }
+    inline bool operator>=(const sTmpGenotype& rhs) const { return id_num >= rhs.id_num; }
+  };  
+  
 };
 
 

Modified: development/source/targets/avida-viewer/cTextViewerAnalyzeDriver.h
===================================================================
--- development/source/targets/avida-viewer/cTextViewerAnalyzeDriver.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/targets/avida-viewer/cTextViewerAnalyzeDriver.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -49,6 +49,7 @@
   // Driver Actions
   void SignalBreakpoint() { return; }
   void SetDone() { m_done = true; }
+  void SetPause() { return; }
   
   void RaiseException(const cString& in_string);
   void RaiseFatalException(int exit_code, const cString& in_string);

Modified: development/source/targets/avida-viewer/cTextViewerDriver.cc
===================================================================
--- development/source/targets/avida-viewer/cTextViewerDriver.cc	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/targets/avida-viewer/cTextViewerDriver.cc	2009-05-27 17:30:41 UTC (rev 3264)
@@ -43,7 +43,7 @@
 
 
 cTextViewerDriver::cTextViewerDriver(cWorld* world)
-  : cTextViewerDriver_Base(world)
+  : cTextViewerDriver_Base(world), m_pause(false), m_firstupdate(true)
 {
   m_view = new cView(world);
   m_view->SetViewMode(world->GetConfig().VIEW_MODE.Get());
@@ -100,7 +100,17 @@
     const int UD_size = ave_time_slice * population.GetNumOrganisms();
     const double step_size = 1.0 / (double) UD_size;
     
-
+    if (m_pause) {
+      m_view->Pause();
+      m_pause = false;
+      
+      // This is needed to have the top bar drawn properly; I'm not sure why...
+      if (m_firstupdate) {
+        m_view->Refresh();
+        m_firstupdate = false;
+      }
+    }
+    
     // Are we stepping through an organism?
     if (m_view->GetStepOrganism() != -1) {  // Yes we are!
                                             // Keep the viewer informed about the organism we are stepping through...
@@ -111,10 +121,9 @@
           m_view->NewUpdate();
           
           // This is needed to have the top bar drawn properly; I'm not sure why...
-          static bool first_update = true;
-          if (first_update) {
+          if (m_firstupdate) {
             m_view->Refresh();
-            first_update = false;
+            m_firstupdate = false;
           }
         }
         population.ProcessStep(ctx, step_size, next_id);
@@ -133,10 +142,9 @@
       m_view->NewUpdate();
  
       // This is needed to have the top bar drawn properly; I'm not sure why...
-      static bool first_update = true;
-      if (first_update) {
+      if (m_firstupdate) {
         m_view->Refresh();
-        first_update = false;
+        m_firstupdate = false;
       }
     }
     

Modified: development/source/targets/avida-viewer/cTextViewerDriver.h
===================================================================
--- development/source/targets/avida-viewer/cTextViewerDriver.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/targets/avida-viewer/cTextViewerDriver.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -32,6 +32,9 @@
 class cTextViewerDriver : public cTextViewerDriver_Base
 {
 private:
+  bool m_pause;
+  bool m_firstupdate;
+  
   cTextViewerDriver();  // not implemented
   
 public:
@@ -40,6 +43,8 @@
   
   void Run();
   
+  void SetPause() { m_pause = true; }
+
   // Driver Actions
   void SignalBreakpoint();
   void SetDone() { m_done = true; }

Modified: development/source/targets/avida-viewer/cTextViewerDriver_Base.h
===================================================================
--- development/source/targets/avida-viewer/cTextViewerDriver_Base.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/targets/avida-viewer/cTextViewerDriver_Base.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -43,6 +43,7 @@
   cWorld* m_world;
   cView_Base* m_view;
   bool m_done;  // This is set to true when run should finish.
+  bool m_pause;
 
   std::stringstream out_stream;
   std::stringstream err_stream;

Modified: development/source/tools/tArray.h
===================================================================
--- development/source/tools/tArray.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/tools/tArray.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -167,7 +167,19 @@
     m_data[new_pos] = value;
     return new_pos;
   }
+  
+  void Swap(int idx1, int idx2)
+  {
+    assert(idx1 >= 0);     // Lower Bounds Error
+    assert(idx1 < m_size); // Upper Bounds Error
+    assert(idx2 >= 0);     // Lower Bounds Error
+    assert(idx2 < m_size); // Upper Bounds Error
 
+    T v = m_data[idx1];
+    m_data[idx1] = m_data[idx2];
+    m_data[idx2] = v;
+  }
+
   void SetAll(const T& value)
   {
     for (int i = 0; i < m_size; i++) m_data[i] = value;

Modified: development/source/tools/tArrayUtils.h
===================================================================
--- development/source/tools/tArrayUtils.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/tools/tArrayUtils.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -25,7 +25,9 @@
 #ifndef tArrayUtils_h
 #define tArrayUtils_h
 
-#include "tArray.h"
+template<typename T> class tArray;
+template<typename T> class tManagedPointerArray;
+template<typename T> class tSmartArray;
 
 
 class tArrayUtils
@@ -39,7 +41,7 @@
 
 
 public:
-    
+  
   template<typename T> inline static void QSort(tArray<T>& array) { QSort(array, 0, array.GetSize() - 1); }
   template<typename T> static void QSort(tArray<T>& array, int begin, int end)
   {
@@ -58,7 +60,7 @@
       if (array[l] > pivot)
         l++;
       else
-        swap(array, l, r--);
+        array.Swap(l, r--);
     }
     
     if (array[l] > pivot && array[r] > pivot) {
@@ -66,18 +68,91 @@
     } else if (array[l] > pivot && array[r] <= pivot) {
       l++; r--;
     } else if (array[l] <= pivot && array[r] > pivot) {
-      swap(array, l++, r--);
+      array.Swap(l++, r--);
     } else {
       r = l - 1;
     }
     
-    swap(array, r--, begin);
+    array.Swap(r--, begin);
     QSort(array, begin, r);
     QSort(array, l, end);
   }
+  
+  template<typename T> inline static void QSort(tManagedPointerArray<T>& array) { QSort(array, 0, array.GetSize() - 1); }
+  template<typename T> static void QSort(tManagedPointerArray<T>& array, int begin, int end)
+  {
+    if (end < begin) return;
     
+    if (begin - end <= QUICKSORT_THRESHOLD) {
+      ISort(array, begin, end);
+      return;
+    }
     
-  template<typename T> inline static void ISort(tArray<T>& array) { isort(array, 0, array.GetSize() - 1); }
+    T& pivot = array[begin];
+    int l = begin + 1;
+    int r = end;
+    
+    while (l != r - 1) {
+      if (array[l] > pivot)
+        l++;
+      else
+        array.Swap(l, r--);
+    }
+    
+    if (array[l] > pivot && array[r] > pivot) {
+      l = r + 1;
+    } else if (array[l] > pivot && array[r] <= pivot) {
+      l++; r--;
+    } else if (array[l] <= pivot && array[r] > pivot) {
+      array.Swap(l++, r--);
+    } else {
+      r = l - 1;
+    }
+    
+    array.Swap(r--, begin);
+    QSort(array, begin, r);
+    QSort(array, l, end);
+  }
+  
+  template<typename T> inline static void QSort(tSmartArray<T>& array) { QSort(array, 0, array.GetSize() - 1); }
+  template<typename T> static void QSort(tSmartArray<T>& array, int begin, int end)
+  {
+    if (end < begin) return;
+    
+    if (begin - end <= QUICKSORT_THRESHOLD) {
+      ISort(array, begin, end);
+      return;
+    }
+    
+    T pivot = array[begin];
+    int l = begin + 1;
+    int r = end;
+    
+    while (l != r - 1) {
+      if (array[l] > pivot)
+        l++;
+      else
+        array.Swap(l, r--);
+    }
+    
+    if (array[l] > pivot && array[r] > pivot) {
+      l = r + 1;
+    } else if (array[l] > pivot && array[r] <= pivot) {
+      l++; r--;
+    } else if (array[l] <= pivot && array[r] > pivot) {
+      array.Swap(l++, r--);
+    } else {
+      r = l - 1;
+    }
+    
+    array.Swap(r--, begin);
+    QSort(array, begin, r);
+    QSort(array, l, end);
+  }
+  
+  
+    
+  template<typename T> inline static void ISort(tArray<T>& array) { ISort(array, 0, array.GetSize() - 1); }
   template<typename T> static void ISort(tArray<T>& array, int begin, int end)
   {
     T value;
@@ -95,16 +170,43 @@
       array[j + 1] = value;
     }
   }
-  
-  
-private:
-  
-  template<typename T> inline static void swap(tArray<T>& array, int i, int j)
+
+  template<typename T> inline static void ISort(tManagedPointerArray<T>& array) { ISort(array, 0, array.GetSize() - 1); }
+  template<typename T> static void ISort(tManagedPointerArray<T>& array, int begin, int end)
   {
-    T v = array[i];
-    array[i] = array[j];
-    array[j] = v;
+    T value;
+    int j;
+    
+    // for each entry
+    for (int i = begin + 1; i <= end; i++) {
+      // insert into array starting from the end of our sub-array
+      value = array[i];
+      j = i - 1;
+      while (j >= begin && array[j] < array[j + 1]) {
+        array.Swap(j, j + 1);
+        j--;
+      }
+    }
   }
+
+  template<typename T> inline static void ISort(tSmartArray<T>& array) { ISort(array, 0, array.GetSize() - 1); }
+  template<typename T> static void ISort(tSmartArray<T>& array, int begin, int end)
+  {
+    T value;
+    int j;
+    
+    // for each entry
+    for (int i = begin + 1; i <= end; i++) {
+      // insert into array starting from the end of our sub-array
+      value = array[i];
+      j = i - 1;
+      while (j >= begin && array[j] < value) {
+        array[j + 1] = array[j];
+        j--;
+      }
+      array[j + 1] = value;
+    }
+  }
 };
 
 #endif

Modified: development/source/tools/tManagedPointerArray.h
===================================================================
--- development/source/tools/tManagedPointerArray.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/tools/tManagedPointerArray.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -38,7 +38,7 @@
 #include <cassert>
 
 template <class T> class tManagedPointerArray
-{  
+{
 #if USE_tMemTrack
   tMemTrack<tManagedPointerArray<T> > mt;
 #endif
@@ -185,6 +185,21 @@
     *m_data[m_size - 1] = value;
   }
   
+  void Swap(int idx1, int idx2)
+  {
+    // Simple pointer swap, rather than deep copy
+    
+    assert(idx1 >= 0);     // Lower Bounds Error
+    assert(idx1 < m_size); // Upper Bounds Error
+    assert(idx2 >= 0);     // Lower Bounds Error
+    assert(idx2 < m_size); // Upper Bounds Error
+    
+    T* v = m_data[idx1];
+    m_data[idx1] = m_data[idx2];
+    m_data[idx2] = v;
+  }
+  
+  
   void SetAll(const T& value)
   {
     for (int i = 0; i < m_size; i++) *m_data[i] = value;

Modified: development/source/tools/tSmartArray.h
===================================================================
--- development/source/tools/tSmartArray.h	2009-05-27 15:53:29 UTC (rev 3263)
+++ development/source/tools/tSmartArray.h	2009-05-27 17:30:41 UTC (rev 3264)
@@ -171,7 +171,19 @@
   }
   
   
+  void Swap(int idx1, int idx2)
+  {
+    assert(idx1 >= 0);     // Lower Bounds Error
+    assert(idx1 < m_active); // Upper Bounds Error
+    assert(idx2 >= 0);     // Lower Bounds Error
+    assert(idx2 < m_active); // Upper Bounds Error
+    
+    T v = m_data[idx1];
+    m_data[idx1] = m_data[idx2];
+    m_data[idx2] = v;
+  }  
   
+  
   void SetAll(const T& value)
   {
     for (int i = 0; i < m_active; i++) m_data[i] = value;




More information about the Avida-cvs mailing list