[Avida-SVN] r1173 - in development: Avida.xcodeproj source/main source/tools

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Sun Jan 7 17:31:06 PST 2007


Author: brysonda
Date: 2007-01-07 20:31:06 -0500 (Sun, 07 Jan 2007)
New Revision: 1173

Added:
   development/source/main/cTaskState.h
Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/source/main/SConscript
   development/source/main/cEnvironment.cc
   development/source/main/cPhenotype.cc
   development/source/main/cPhenotype.h
   development/source/main/cTaskContext.h
   development/source/main/cTaskEntry.h
   development/source/main/cTaskLib.cc
   development/source/main/cTaskLib.h
   development/source/tools/tHashTable.h
Log:
COMPATIBILITY NOTE: I have changed the syntax for task arguments in order to more closely match the syntax for the rest of the environment file.
Old Syntax: taskname=arg1:value,arg2:value
New Syntax: taskname:arg1=value,arg2=value


Added support for collecting and printing error messages generated by argumented tasks.

Implemented 9 new math tasks, all of which support value close exponential rewards (implemented as a half-life decay away from the actual value and reward, like the match number task).

Reworked cTaskState storage and retrieval so that it is actually a per-organism (stored in cPhenotype) resource, as opposed to the incorrect per-world implementation.  This will make a big difference in the fibonacci sequence task.

Added void* HashKey function to tHashTable.  This is used by the cTaskState storage mechanism that keys storage based on the cTaskEntry with which they are bound.

Also added two implementations of GetValues (one tList based, and one tArray based) to tHashTable.  These methods quickly iterate over stored values.  Value order is not guaranteed.

Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/Avida.xcodeproj/project.pbxproj	2007-01-08 01:31:06 UTC (rev 1173)
@@ -9,9 +9,7 @@
 /* Begin PBXBuildFile section */
 		1097463F0AE9606E00929ED6 /* cDeme.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1097463D0AE9606E00929ED6 /* cDeme.cc */; };
 		109746410AE9606E00929ED6 /* cDeme.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1097463D0AE9606E00929ED6 /* cDeme.cc */; };
-		109746420AE9606E00929ED6 /* cDeme.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1097463E0AE9606E00929ED6 /* cDeme.h */; };
 		109746430AE9606E00929ED6 /* cDeme.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1097463D0AE9606E00929ED6 /* cDeme.cc */; };
-		109746440AE9606E00929ED6 /* cDeme.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1097463E0AE9606E00929ED6 /* cDeme.h */; };
 		7005A70409BA0FA90007E16E /* cTestCPUInterface.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7005A70209BA0FA90007E16E /* cTestCPUInterface.cc */; };
 		7005A70609BA0FA90007E16E /* cTestCPUInterface.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7005A70209BA0FA90007E16E /* cTestCPUInterface.cc */; };
 		7005A70809BA0FA90007E16E /* cTestCPUInterface.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7005A70209BA0FA90007E16E /* cTestCPUInterface.cc */; };
@@ -108,8 +106,6 @@
 		708BF2FE0AB65DC700A923BF /* cEventList.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708BF2FD0AB65DC700A923BF /* cEventList.cc */; };
 		708BF2FF0AB65DC700A923BF /* cEventList.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708BF2FD0AB65DC700A923BF /* cEventList.cc */; };
 		708BF3000AB65DC700A923BF /* cEventList.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708BF2FD0AB65DC700A923BF /* cEventList.cc */; };
-		7099EEC00B2F9D2A001269F6 /* cEnvReqs.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7099EEBF0B2F9D2A001269F6 /* cEnvReqs.h */; };
-		7099EEC10B2F9D2A001269F6 /* cEnvReqs.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7099EEBF0B2F9D2A001269F6 /* cEnvReqs.h */; };
 		7099EF510B2FBC85001269F6 /* cAnalyzeScreen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7099EF470B2FBC85001269F6 /* cAnalyzeScreen.cc */; };
 		7099EF530B2FBC85001269F6 /* cAnalyzeView.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7099EF490B2FBC85001269F6 /* cAnalyzeView.cc */; };
 		7099EF560B2FBC86001269F6 /* cTextViewerAnalyzeDriver.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7099EF4C0B2FBC85001269F6 /* cTextViewerAnalyzeDriver.cc */; };
@@ -403,8 +399,6 @@
 			dstSubfolderSpec = 16;
 			files = (
 				700E2B87085DE54400CF158A /* avida-viewer in CopyFiles */,
-				109746440AE9606E00929ED6 /* cDeme.h in CopyFiles */,
-				7099EEC10B2F9D2A001269F6 /* cEnvReqs.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -437,8 +431,6 @@
 			dstSubfolderSpec = 16;
 			files = (
 				702F532F0993060A00B2B507 /* avida-s in CopyFiles */,
-				109746420AE9606E00929ED6 /* cDeme.h in CopyFiles */,
-				7099EEC00B2F9D2A001269F6 /* cEnvReqs.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -459,6 +451,7 @@
 		7013845F09028B3E0087ED2E /* cAvidaConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cAvidaConfig.h; sourceTree = "<group>"; };
 		7013846009028B3E0087ED2E /* cAvidaConfig.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cAvidaConfig.cc; sourceTree = "<group>"; };
 		701384A10902A16F0087ED2E /* defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = defs.h; sourceTree = "<group>"; };
+		70166B8D0B519CFE009533A5 /* cTaskState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cTaskState.h; sourceTree = "<group>"; };
 		701D51CB09C645F50009B4F8 /* cAvidaContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cAvidaContext.h; sourceTree = "<group>"; };
 		701D9116094B773E008B845F /* cWorldDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cWorldDriver.h; sourceTree = "<group>"; };
 		701D912B094B7AC1008B845F /* cAvidaDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cAvidaDriver.h; sourceTree = "<group>"; };
@@ -1502,6 +1495,7 @@
 				70DA5E9D09DA1A8D00FFF42B /* cOrgSeqMessage.h */,
 				700AE91B09DB65F200A073FD /* cTaskContext.h */,
 				7099EEBF0B2F9D2A001269F6 /* cEnvReqs.h */,
+				70166B8D0B519CFE009533A5 /* cTaskState.h */,
 			);
 			path = main;
 			sourceTree = "<group>";

Modified: development/source/main/SConscript
===================================================================
--- development/source/main/SConscript	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/SConscript	2007-01-08 01:31:06 UTC (rev 1173)
@@ -47,6 +47,7 @@
   'cTaskContext.h',
   'cTaskEntry.h',
   'cTaskLib.h',
+  'cTaskState.h',
   'cWorld.h',
   'MyCodeArrayLessThan.h',
   'nGeometry.h',

Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cEnvironment.cc	2007-01-08 01:31:06 UTC (rev 1173)
@@ -500,13 +500,18 @@
   
   // Finish loading in this reaction.
   cString trigger_info = desc.PopWord();
-	cString trigger = trigger_info.Pop('=');
+	cString trigger = trigger_info.Pop(':');
   
   // Load the task trigger
   cEnvReqs envreqs;
-  cTaskEntry* cur_task = m_tasklib.AddTask(trigger, trigger_info, envreqs);
-  if (cur_task == NULL) {
-    cerr << "...failed to find task in cTaskLib..." << endl;
+  tList<cString> errors;
+  cTaskEntry* cur_task = m_tasklib.AddTask(trigger, trigger_info, envreqs, &errors);
+  if (cur_task == NULL || errors.GetSize() > 0) {
+    cString* err_str;
+    while ((err_str = errors.Pop()) != NULL) {
+      cerr << *err_str << endl;
+      delete err_str;
+    }
     return false;
   }
   new_reaction->SetTask(cur_task);      // Attack task to reaction.

Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cPhenotype.cc	2007-01-08 01:31:06 UTC (rev 1173)
@@ -13,6 +13,7 @@
 #include "cEnvironment.h"
 #include "cHardwareManager.h"
 #include "cReactionResult.h"
+#include "cTaskState.h"
 #include "cTools.h"
 #include "cWorld.h"
 
@@ -40,6 +41,10 @@
 
 cPhenotype::~cPhenotype()
 {
+  // Remove Task States
+  tArray<cTaskState*> task_states(0);
+  m_task_states.GetValues(task_states);
+  for (int i = 0; i < task_states.GetSize(); i++) delete task_states[i];
 }
 
 bool cPhenotype::OK()
@@ -335,6 +340,12 @@
   }
 
   if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
+  
+  // Reset Task States
+  tArray<cTaskState*> task_states(0);
+  m_task_states.GetValues(task_states);
+  for (int i = 0; i < task_states.GetSize(); i++) delete task_states[i];
+  m_task_states.ClearAll();
 }
 
 
@@ -523,6 +534,8 @@
 			    tArray<int>& insts_triggered)
 {
   assert(initialized == true);
+  
+  taskctx.SetTaskStates(&m_task_states);
 
   const cEnvironment& env = m_world->GetEnvironment();
   const int num_resources = env.GetResourceLib().GetSize();

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cPhenotype.h	2007-01-08 01:31:06 UTC (rev 1173)
@@ -25,6 +25,9 @@
 #ifndef cCodeLabel_h
 #include "cCodeLabel.h"
 #endif
+#ifndef tHashTable_h
+#include "tHashTable.h"
+#endif
 
 
 /*************************************************************************
@@ -58,6 +61,7 @@
 template <class T> class tBuffer;
 template <class T> class tList;
 class cTaskContext;
+class cTaskState;
 class cWorld;
 
 class cPhenotype
@@ -87,6 +91,7 @@
   tArray<int> cur_sense_count;     // Total times resource combinations have been sensed; JEB 10-22-06 
   tArray<double> sensed_resources; // Resources of which the organism is explictly aware
   tArray<cCodeLabel> active_transposons; // Transposons that are active
+  tHashTable<void*, cTaskState*> m_task_states;
   
   // 3. These mark the status of "in progess" variables at the last divide.
   double last_merit_base;         // Either constant or based on genome length.

Modified: development/source/main/cTaskContext.h
===================================================================
--- development/source/main/cTaskContext.h	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cTaskContext.h	2007-01-08 01:31:06 UTC (rev 1173)
@@ -19,25 +19,30 @@
 #ifndef tList_h
 #include "tList.h"
 #endif
+#ifndef tHashTable_h
+#include "tHashTable.h"
+#endif
 
 class cTaskEntry;
+class cTaskState;
 
 
 class cTaskContext
 {
 private:
   cOrgInterface* m_interface;
-  const tBuffer<int>& input_buffer;
-  const tBuffer<int>& output_buffer;
-  const tList<tBuffer<int> >& other_input_buffers;
-  const tList<tBuffer<int> >& other_output_buffers;
-  bool net_valid;
-  int net_completed;
-  tBuffer<int>* received_messages;
-  int logic_id;
-  bool on_divide;
+  const tBuffer<int>& m_input_buffer;
+  const tBuffer<int>& m_output_buffer;
+  const tList<tBuffer<int> >& m_other_input_buffers;
+  const tList<tBuffer<int> >& m_other_output_buffers;
+  bool m_net_valid;
+  int m_net_completed;
+  tBuffer<int>* m_received_messages;
+  int m_logic_id;
+  bool m_on_divide;
   
-  cTaskEntry* task_entry;
+  cTaskEntry* m_task_entry;
+  tHashTable<void*, cTaskState*>* m_task_states;
 
 public:
   cTaskContext(cOrgInterface* interface, const tBuffer<int>& inputs, const tBuffer<int>& outputs,
@@ -45,33 +50,44 @@
                bool in_net_valid, int in_net_completed, bool in_on_divide = false,
                tBuffer<int>* in_received_messages = NULL)
     : m_interface(interface)
-    , input_buffer(inputs)
-    , output_buffer(outputs)
-    , other_input_buffers(other_inputs)
-    , other_output_buffers(other_outputs)
-    , net_valid(in_net_valid)
-    , net_completed(in_net_completed)
-    , received_messages(in_received_messages)
-    , logic_id(0)
-    , on_divide(in_on_divide)
-    , task_entry(NULL)
+    , m_input_buffer(inputs)
+    , m_output_buffer(outputs)
+    , m_other_input_buffers(other_inputs)
+    , m_other_output_buffers(other_outputs)
+    , m_net_valid(in_net_valid)
+    , m_net_completed(in_net_completed)
+    , m_received_messages(in_received_messages)
+    , m_logic_id(0)
+    , m_on_divide(in_on_divide)
+    , m_task_entry(NULL)
+    , m_task_states(NULL)
   {
   }
   
   inline int GetInputAt(int index) { return m_interface->GetInputAt(index); }
-  inline const tBuffer<int>& GetInputBuffer() { return input_buffer; }
-  inline const tBuffer<int>& GetOutputBuffer() { return output_buffer; }
-  inline const tList<tBuffer<int> >& GetNeighborhoodInputBuffers() { return other_input_buffers; }
-  inline const tList<tBuffer<int> >& GetNeighborhoodOutputBuffers() { return other_output_buffers; }
-  inline bool NetIsValid() { return net_valid; }
-  inline int GetNetCompleted() { return net_completed; }
-  inline tBuffer<int>* GetReceivedMessages() { return received_messages; }
-  inline int GetLogicId() { return logic_id; }
-  inline void SetLogicId(int v) { logic_id = v; }
-  inline bool GetOnDivide() { return on_divide; }
+  inline const tBuffer<int>& GetInputBuffer() { return m_input_buffer; }
+  inline const tBuffer<int>& GetOutputBuffer() { return m_output_buffer; }
+  inline const tList<tBuffer<int> >& GetNeighborhoodInputBuffers() { return m_other_input_buffers; }
+  inline const tList<tBuffer<int> >& GetNeighborhoodOutputBuffers() { return m_other_output_buffers; }
+  inline bool NetIsValid() { return m_net_valid; }
+  inline int GetNetCompleted() { return m_net_completed; }
+  inline tBuffer<int>* GetReceivedMessages() { return m_received_messages; }
+  inline int GetLogicId() { return m_logic_id; }
+  inline void SetLogicId(int v) { m_logic_id = v; }
+  inline bool GetOnDivide() { return m_on_divide; }
   
-  void SetTaskEntry(cTaskEntry* in_entry) { task_entry = in_entry; }
-  cTaskEntry* GetTaskEntry() { return task_entry; }
+  inline void SetTaskEntry(cTaskEntry* in_entry) { m_task_entry = in_entry; }
+  inline cTaskEntry* GetTaskEntry() { return m_task_entry; }
+  
+  inline void SetTaskStates(tHashTable<void*, cTaskState*>* states) { m_task_states = states; }
+  
+  inline cTaskState* GetTaskState()
+  {
+    cTaskState* ret = NULL;
+    m_task_states->Find(m_task_entry, ret);
+    return ret;
+  }
+  inline cTaskState* AddTaskState(cTaskState* value) { m_task_states->Add(m_task_entry, value); }
 };
 
 

Modified: development/source/main/cTaskEntry.h
===================================================================
--- development/source/main/cTaskEntry.h	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cTaskEntry.h	2007-01-08 01:31:06 UTC (rev 1173)
@@ -23,16 +23,7 @@
 
 typedef double (cTaskLib::*tTaskTest)(cTaskContext&) const;
 
-class cTaskState
-{
-protected:
-  cTaskState() { ; }
-  
-public:
-  virtual ~cTaskState() { ; }
-};
 
-
 class cTaskEntry
 {
 private:
@@ -41,17 +32,15 @@
   int m_id;
   tTaskTest m_test_fun;
   cArgContainer* m_args;
-  cTaskState* m_state;
 
 public:
-  cTaskEntry(const cString& name, const cString& desc, int in_id, tTaskTest fun, cArgContainer* args, cTaskState* state = NULL)
-    : m_name(name), m_desc(desc), m_id(in_id), m_test_fun(fun), m_args(args), m_state(state)
+  cTaskEntry(const cString& name, const cString& desc, int in_id, tTaskTest fun, cArgContainer* args)
+    : m_name(name), m_desc(desc), m_id(in_id), m_test_fun(fun), m_args(args)
   {
   }
   ~cTaskEntry()
   {
     delete m_args;
-    delete m_state;
   }
 
   const cString& GetName() const { return m_name; }
@@ -61,7 +50,6 @@
   
   bool HasArguments() const { return (m_args != NULL); }
   const cArgContainer& GetArguments() const { return *m_args; }
-  cTaskState* GetState() { return m_state; }
 };
 
 

Modified: development/source/main/cTaskLib.cc
===================================================================
--- development/source/main/cTaskLib.cc	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cTaskLib.cc	2007-01-08 01:31:06 UTC (rev 1173)
@@ -13,6 +13,7 @@
 #include "cArgSchema.h"
 #include "cEnvReqs.h"
 #include "tHashTable.h"
+#include "cTaskState.h"
 
 #include <stdlib.h>
 extern "C" {
@@ -20,9 +21,10 @@
 #include <limits.h>
 }
 
-using namespace std;
 
+static const float fCastPrecision = 10000.0f;
 
+
 cTaskLib::~cTaskLib()
 {
   for (int i = 0; i < task_array.GetSize(); i++) delete task_array[i];
@@ -37,7 +39,7 @@
   return static_cast<double>(32 - bit_diff) / 32.0; 
 }
 
-cTaskEntry* cTaskLib::AddTask(const cString& name, const cString& info, cEnvReqs& envreqs)
+cTaskEntry* cTaskLib::AddTask(const cString& name, const cString& info, cEnvReqs& envreqs, tList<cString>* errors)
 {
   // Determine if this task is already in the active library.
   for (int i = 0; i < task_array.GetSize(); i++) {
@@ -314,16 +316,37 @@
   
   // Matching Tasks
   if (name == "matchstr") 
-    Load_MatchStr(name, info, envreqs);
+    Load_MatchStr(name, info, envreqs, errors);
   else if (name == "match_number")
-    Load_MatchNumber(name, info, envreqs);
+    Load_MatchNumber(name, info, envreqs, errors);
 
   if (name == "sort_inputs")
-    Load_SortInputs(name, info, envreqs);
+    Load_SortInputs(name, info, envreqs, errors);
   else if (name == "fibonacci_seq")
-    Load_FibonacciSequence(name, info, envreqs);
+    Load_FibonacciSequence(name, info, envreqs, errors);
 
-	// Communication Tasks
+
+  if (name == "mult")
+    Load_Mult(name, info, envreqs, errors);
+  else if (name == "div")
+    Load_Div(name, info, envreqs, errors);
+  else if (name == "log")
+    Load_Log(name, info, envreqs, errors);
+  else if (name == "log2")
+    Load_Log2(name, info, envreqs, errors);
+  else if (name == "log10")
+    Load_Log10(name, info, envreqs, errors);
+  else if (name == "sqrt")
+    Load_Sqrt(name, info, envreqs, errors);
+  else if (name == "sine")
+    Load_Sine(name, info, envreqs, errors);
+  else if (name == "cosine")
+    Load_Cosine(name, info, envreqs, errors);
+  else if (name == "tangent")
+    Load_Tangent(name, info, envreqs, errors);
+
+  
+  // Communication Tasks
   if (name == "comm_echo")
     NewTask(name, "Echo of Neighbor's Input", &cTaskLib::Task_CommEcho, REQ_NEIGHBOR_INPUT);
   else if (name == "comm_not")
@@ -339,7 +362,11 @@
   
   // Make sure we have actually found a task  
   if (task_array.GetSize() == start_size) {
-    cerr << "Unknown task entry '" << name << "'." << endl;
+    if (errors != NULL && errors->GetSize() == 0) {
+      cString* err_str = new cString();
+      err_str->Set("Unknown task entry '%s'.", static_cast<const char*>(name));
+      errors->PushRear(err_str);
+    }
     return NULL;
   }
   
@@ -348,14 +375,14 @@
 }
 
 void cTaskLib::NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs,
-                       cArgContainer* args, cTaskState* state)
+                       cArgContainer* args)
 {
   if (reqs & REQ_NEIGHBOR_INPUT == true) use_neighbor_input = true;
   if (reqs & REQ_NEIGHBOR_OUTPUT == true) use_neighbor_output = true;
   
   const int id = task_array.GetSize();
   task_array.Resize(id + 1);
-  task_array[id] = new cTaskEntry(name, desc, id, task_fun, args, state);
+  task_array[id] = new cTaskEntry(name, desc, id, task_fun, args);
 }
 
 
@@ -1787,11 +1814,11 @@
 }
 
 
-void cTaskLib::Load_MatchStr(const cString& name, const cString& argstr, cEnvReqs& envreqs)
+void cTaskLib::Load_MatchStr(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
 {
-  cArgSchema schema(',',':');
+  cArgSchema schema;
   schema.AddEntry("string", 0, cArgSchema::SCHEMA_STRING);
-  cArgContainer* args = cArgContainer::Load(argstr, schema);
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
   if (args) NewTask(name, "MatchStr", &cTaskLib::Task_MatchStr, 0, args);
 }
 
@@ -1856,9 +1883,9 @@
 }
 
 
-void cTaskLib::Load_MatchNumber(const cString& name, const cString& argstr, cEnvReqs& envreqs)
+void cTaskLib::Load_MatchNumber(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
 {
-  cArgSchema schema(',',':');
+  cArgSchema schema;
   
   // Integer Arguments
   schema.AddEntry("target", 0, cArgSchema::SCHEMA_INT);
@@ -1866,7 +1893,7 @@
   // Double Arguments
   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
   
-  cArgContainer* args = cArgContainer::Load(argstr, schema);
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
   if (args) NewTask(name, "Match Number", &cTaskLib::Task_MatchNumber, 0, args);
 }
 
@@ -1888,9 +1915,9 @@
 }
 
 
-void cTaskLib::Load_SortInputs(const cString& name, const cString& argstr, cEnvReqs& envreqs)
+void cTaskLib::Load_SortInputs(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
 {
-  cArgSchema schema(',',':');
+  cArgSchema schema;
   
   // Integer Arguments
   schema.AddEntry("size", 0, cArgSchema::SCHEMA_INT); // Number of items to sort
@@ -1899,7 +1926,7 @@
   // Double Arguments
   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
   
-  cArgContainer* args = cArgContainer::Load(argstr, schema);
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
   if (args) {
     envreqs.SetMinInputs(args->GetInt(0));
     envreqs.SetMinOutputs(args->GetInt(0) * 2);
@@ -2028,26 +2055,29 @@
   cFibSeqState() : count(0) { seq[0] = 1; seq[1] = 0; }
 };
 
-void cTaskLib::Load_FibonacciSequence(const cString& name, const cString& argstr, cEnvReqs& envreqs)
+void cTaskLib::Load_FibonacciSequence(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
 {
-  cArgSchema schema(',',':');
+  cArgSchema schema;
   
   // Integer Arguments
   schema.AddEntry("target", 0, cArgSchema::SCHEMA_INT);
   // Double Arguments
   schema.AddEntry("penalty", 0, 0.0);
   
-  cArgContainer* args = cArgContainer::Load(argstr, schema);
-  cFibSeqState* state = new cFibSeqState();
-  
-  if (args) NewTask(name, "Fibonacci Sequence", &cTaskLib::Task_FibonacciSequence, 0, args, state);
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+
+  if (args) NewTask(name, "Fibonacci Sequence", &cTaskLib::Task_FibonacciSequence, 0, args);
 }
 
 double cTaskLib::Task_FibonacciSequence(cTaskContext& ctx) const
 {
   double quality = 0.0;
   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
-  cFibSeqState* state = static_cast<cFibSeqState*>(ctx.GetTaskEntry()->GetState());
+  cFibSeqState* state = static_cast<cFibSeqState*>(ctx.GetTaskState());
+  if (state == NULL) {
+    state = new cFibSeqState();
+    ctx.AddTaskState(state);
+  }
 
   const int next = state->seq[0] + state->seq[1];
   
@@ -2068,6 +2098,387 @@
 
 
 
+void cTaskLib::Load_Mult(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Multiplication", &cTaskLib::Task_Mult, 0, args);
+}
+
+double cTaskLib::Task_Mult(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+
+  int diff = abs((input_buffer[0] * input_buffer[0]) - test_output);
+
+  for (int i = 0; i < input_size; i ++) {
+    for (int j = 0; j < input_size; j ++) {
+      int cur_diff = abs((input_buffer[i] * input_buffer[j]) - test_output);
+      if (cur_diff < diff) diff = cur_diff;
+    }
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+void cTaskLib::Load_Div(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Division", &cTaskLib::Task_Div, 0, args);
+}
+
+double cTaskLib::Task_Div(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs((input_buffer[0] / input_buffer[0]) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    for (int j = 0; j < input_size; j ++) {
+      int cur_diff = abs((input_buffer[i] / input_buffer[j]) - test_output);
+      if (cur_diff < diff) diff = cur_diff;
+    }
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+void cTaskLib::Load_Log(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Logarithm (natural)", &cTaskLib::Task_Log, 0, args);
+}
+
+double cTaskLib::Task_Log(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(log(static_cast<double>(abs(input_buffer[0] ? input_buffer[0] : 1)))) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(log(static_cast<double>(abs(input_buffer[i] ? input_buffer[i] : 1)))) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+
+void cTaskLib::Load_Log2(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Logarithm (base-2)", &cTaskLib::Task_Log2, 0, args);
+}
+
+double cTaskLib::Task_Log2(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(log2(static_cast<double>(abs(input_buffer[0] ? input_buffer[0] : 1)))) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(log2(static_cast<double>(abs(input_buffer[i] ? input_buffer[i] : 1)))) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+
+void cTaskLib::Load_Log10(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Logarithm (base-10)", &cTaskLib::Task_Log10, 0, args);
+}
+
+double cTaskLib::Task_Log10(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(log10(static_cast<double>(abs(input_buffer[0] ? input_buffer[0] : 1)))) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(log10(static_cast<double>(abs(input_buffer[i] ? input_buffer[i] : 1)))) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+
+void cTaskLib::Load_Sqrt(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Square Root", &cTaskLib::Task_Sqrt, 0, args);
+}
+
+double cTaskLib::Task_Sqrt(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(sqrt(static_cast<double>(abs(input_buffer[0])))) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(sqrt(static_cast<double>(abs(input_buffer[i])))) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+
+void cTaskLib::Load_Sine(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Sine", &cTaskLib::Task_Sine, 0, args);
+}
+
+double cTaskLib::Task_Sine(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(sinf(static_cast<float>(input_buffer[0]) / fCastPrecision) * fCastPrecision) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(sinf(static_cast<float>(input_buffer[0]) / fCastPrecision) * fCastPrecision) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+void cTaskLib::Load_Cosine(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Cosine", &cTaskLib::Task_Cosine, 0, args);
+}
+
+double cTaskLib::Task_Cosine(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(cosf(static_cast<float>(input_buffer[0]) / fCastPrecision) * fCastPrecision) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(cosf(static_cast<float>(input_buffer[0]) / fCastPrecision) * fCastPrecision) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+void cTaskLib::Load_Tangent(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+  cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("threshold", 0, -1);
+  // Double Arguments
+  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "Tangent", &cTaskLib::Task_Tangent, 0, args);
+}
+
+double cTaskLib::Task_Tangent(cTaskContext& ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+  
+  const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
+  const int test_output = ctx.GetOutputBuffer()[0];
+  const int input_size = input_buffer.GetNumStored();
+  
+  int diff = abs(static_cast<int>(tanf(static_cast<float>(input_buffer[0]) / fCastPrecision) * fCastPrecision) - test_output);
+  
+  for (int i = 0; i < input_size; i ++) {
+    int cur_diff = abs(static_cast<int>(tanf(static_cast<float>(input_buffer[0]) / fCastPrecision) * fCastPrecision) - test_output);
+    if (cur_diff < diff) diff = cur_diff;
+  }
+  
+  int threshold = args.GetInt(0);
+  
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+                                                 // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+  
+  return quality;
+}
+
+
+
+
+
+
 double cTaskLib::Task_CommEcho(cTaskContext& ctx) const
 {
   const int test_output = ctx.GetOutputBuffer()[0];

Modified: development/source/main/cTaskLib.h
===================================================================
--- development/source/main/cTaskLib.h	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cTaskLib.h	2007-01-08 01:31:06 UTC (rev 1173)
@@ -62,7 +62,7 @@
 
   int GetSize() const { return task_array.GetSize(); }
 
-  cTaskEntry* AddTask(const cString& name, const cString& info, cEnvReqs& envreqs);
+  cTaskEntry* AddTask(const cString& name, const cString& info, cEnvReqs& envreqs, tList<cString>* errors);
   const cTaskEntry& GetTask(int id) const { return *(task_array[id]); }
   
   void SetupTests(cTaskContext& ctx) const;
@@ -74,7 +74,7 @@
   
 private:  // Direct task related methods
   void NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs = 0,
-               cArgContainer* args = NULL, cTaskState* state = NULL);
+               cArgContainer* args = NULL);
 
   inline double FractionalReward(unsigned int supplied, unsigned int correct);  
 
@@ -221,16 +221,36 @@
   double Task_Math3in_AM(cTaskContext& ctx) const;
   
   // Matching Tasks
-  void Load_MatchStr(const cString& name, const cString& argstr, cEnvReqs& envreqs);
+  void Load_MatchStr(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
   double Task_MatchStr(cTaskContext& ctx) const;
-  void Load_MatchNumber(const cString& name, const cString& argstr, cEnvReqs& envreqs);
+  void Load_MatchNumber(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
   double Task_MatchNumber(cTaskContext& ctx) const;
 
-  void Load_SortInputs(const cString& name, const cString& argstr, cEnvReqs& envreqs);
+  void Load_SortInputs(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
   double Task_SortInputs(cTaskContext& ctx) const;
-  void Load_FibonacciSequence(const cString& name, const cString& argstr, cEnvReqs& envreqs);
+  void Load_FibonacciSequence(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
   double Task_FibonacciSequence(cTaskContext& ctx) const;
+  
+  void Load_Mult(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Mult(cTaskContext& ctx) const;
+  void Load_Div(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Div(cTaskContext& ctx) const;
+  void Load_Log(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Log(cTaskContext& ctx) const;
+  void Load_Log2(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Log2(cTaskContext& ctx) const;
+  void Load_Log10(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Log10(cTaskContext& ctx) const;
+  void Load_Sqrt(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Sqrt(cTaskContext& ctx) const;
+  void Load_Sine(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Sine(cTaskContext& ctx) const;
+  void Load_Cosine(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Cosine(cTaskContext& ctx) const;
+  void Load_Tangent(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+  double Task_Tangent(cTaskContext& ctx) const;
 
+
   // Communication Tasks
   double Task_CommEcho(cTaskContext& ctx) const;
   double Task_CommNot(cTaskContext& ctx) const;

Added: development/source/main/cTaskState.h
===================================================================
--- development/source/main/cTaskState.h	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/main/cTaskState.h	2007-01-08 01:31:06 UTC (rev 1173)
@@ -0,0 +1,23 @@
+/*
+ *  cTaskState.h
+ *  Avida
+ *
+ *  Created by David Bryson on 1/7/07.
+ *  Copyright 2007 Michigan State University. All rights reserved.
+ *
+ */
+
+#ifndef cTaskState_h
+#define cTaskState_h
+
+
+class cTaskState
+{
+protected:
+  cTaskState() { ; }
+  
+public:
+  virtual ~cTaskState() { ; }
+};
+
+#endif

Modified: development/source/tools/tHashTable.h
===================================================================
--- development/source/tools/tHashTable.h	2007-01-08 00:59:24 UTC (rev 1172)
+++ development/source/tools/tHashTable.h	2007-01-08 01:31:06 UTC (rev 1173)
@@ -120,6 +120,17 @@
   {
     return abs(key % table_size);
   }
+
+  // HASH_TYPE = void*
+  // Casts the pointer to an int, shift right last two bit positions, mod by
+  // the size of the hash table and hope for the best.  The shift is to account
+  // for typical 4-byte alignment of pointer values.  Depending on architecture
+  // this may not be true and could result in suboptimal hashing at higher
+  // order alignments.
+  int HashKey(const void* const& key) const
+  {
+    return abs(((int)key >> 2) % table_size);
+  }
   
   // HASH_TYPE = cString
   // We hash a string simply by adding up the individual character values in
@@ -326,7 +337,8 @@
   // The following method allows the user to convert the dictionary contents
   // into lists.  Empty lists show be passed in as arguments and the method
   // will fill in their contents.
-  void AsLists(tList<HASH_TYPE> & key_list, tList<DATA_TYPE> & value_list) const {
+  void AsLists(tList<HASH_TYPE>& key_list, tList<DATA_TYPE>& value_list) const
+  {
     // Setup the lists to fill in.
     assert(key_list.GetSize() == 0);
     assert(value_list.GetSize() == 0);
@@ -338,8 +350,8 @@
     list_it.Reset();
     while (list_it.Next() != NULL) {
       // Grab the info about the current entry.
-      HASH_TYPE & cur_key = list_it.Get()->key;
-      DATA_TYPE & cur_value = list_it.Get()->data;
+      HASH_TYPE& cur_key = list_it.Get()->key;
+      DATA_TYPE& cur_value = list_it.Get()->data;
       
       // Find the position to place this in the lists.
       key_it.Reset();
@@ -352,6 +364,24 @@
       value_list.Insert(value_it, &cur_value);
     }
   }
+  
+  void GetValues(tList<DATA_TYPE>& value_list) const
+  {
+    list_it.Reset();
+    while (list_it.Next() != NULL) value_list.Push(&list_it.Get()->data);
+  }
+
+  void GetValues(tArray<DATA_TYPE>& value_array) const
+  {
+    value_array.Resize(entry_count);
+    int idx = 0;
+
+    list_it.Reset();
+    while (list_it.Next() != NULL) value_array[idx++] = list_it.Get()->data;
+  }
+  
+  
+  
   template<class Archive> 
   void serialize(Archive & a, const unsigned int version){
     a.ArkvObj("entry_count", entry_count);




More information about the Avida-cvs mailing list