add ObjectVector value support.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 11 Feb 2008 04:26:09 +0100
changeset 2405 17f406c71505
parent 2404 6d2c158547b3
child 2406 c54440da3228
add ObjectVector value support.
src/core/object-vector.cc
src/core/object-vector.h
src/core/value-test.cc
src/core/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/object-vector.cc	Mon Feb 11 04:26:09 2008 +0100
@@ -0,0 +1,115 @@
+#include "object-vector.h"
+
+namespace ns3 {
+
+ObjectVector::ObjectVector ()
+{}
+
+ObjectVector::Iterator 
+ObjectVector::Begin (void) const
+{
+  return m_objects.begin ();
+}
+ObjectVector::Iterator 
+ObjectVector::End (void) const
+{
+  return m_objects.end ();
+}
+uint32_t 
+ObjectVector::GetN (void) const
+{
+  return m_objects.size ();
+}
+Ptr<Object> 
+ObjectVector::Get (uint32_t i) const
+{
+  return m_objects[i];
+}
+
+ObjectVector::ObjectVector (PValue value)
+{
+  const ObjectVectorValue *v = value.DynCast<const ObjectVectorValue *> ();
+  if (v == 0)
+    {
+      NS_FATAL_ERROR ("Expected value of type ObjectVectorValue.");
+    }
+  *this = v->Get ();
+}
+
+ObjectVectorValue::ObjectVectorValue ()
+  : m_vector ()
+{}
+
+ObjectVectorValue::ObjectVectorValue (const ObjectVector &vector)
+  : m_vector (vector)
+{}
+
+ObjectVector 
+ObjectVectorValue::Get (void) const
+{
+  return m_vector;
+}
+
+PValue 
+ObjectVectorValue::Copy (void) const
+{
+  return PValue::Create<ObjectVectorValue> (*this);
+}
+std::string 
+ObjectVectorValue::SerializeToString (Ptr<const ParamSpec> spec) const
+{
+  return "";
+}
+bool 
+ObjectVectorValue::DeserializeFromString (std::string value, Ptr<const ParamSpec> spec)
+{
+  return true;
+}
+
+bool 
+ObjectVectorParamSpec::Set (ObjectBase * object, PValue value) const
+{
+  // not allowed.
+  return false;
+}
+bool 
+ObjectVectorParamSpec::Get (const ObjectBase * object, PValue value) const
+{
+  ObjectVectorValue *v = value.DynCast<ObjectVectorValue *> ();
+  if (v == 0)
+    {
+      return false;
+    }
+  v->m_vector.m_objects.clear ();
+  uint32_t n;
+  bool ok = DoGetN (object, &n);
+  if (!ok)
+    {
+      return false;
+    }
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Ptr<Object> o = DoGet (object, i);
+      v->m_vector.m_objects.push_back (o);
+    }
+  return true;
+}
+bool 
+ObjectVectorParamSpec::Check (PValue value) const
+{
+  const ObjectVectorValue *v = value.DynCast<const ObjectVectorValue *> ();
+  return v != 0;
+}
+PValue 
+ObjectVectorParamSpec::GetInitialValue (void) const
+{
+  return PValue::Create<ObjectVectorValue> ();
+}
+PValue 
+ObjectVectorParamSpec::CreateValue (void) const
+{
+  return PValue::Create<ObjectVectorValue> ();
+}
+
+
+} // name
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/object-vector.h	Mon Feb 11 04:26:09 2008 +0100
@@ -0,0 +1,141 @@
+#ifndef OBJECT_VECTOR_H
+#define OBJECT_VECTOR_H
+
+#include <vector>
+#include "object.h"
+#include "ptr.h"
+#include "value.h"
+
+namespace ns3 {
+
+class ObjectVector
+{
+public:
+  typedef std::vector<Ptr<Object> >::const_iterator Iterator;
+
+  ObjectVector ();
+
+  Iterator Begin (void) const;
+  Iterator End (void) const;
+  uint32_t GetN (void) const;
+  Ptr<Object> Get (uint32_t i) const;
+
+  ObjectVector (PValue value);
+private:
+  friend class ObjectVectorParamSpec;
+  std::vector<Ptr<Object> > m_objects;
+};
+
+template <typename T, typename U>
+Ptr<ParamSpec>
+MakeObjectVectorParamSpec (U T::*memberVector);
+
+template <typename T, typename U, typename INDEX>
+Ptr<ParamSpec>
+MakeObjectVectorParamSpec (Ptr<U> (T::*get) (INDEX) const,
+			   INDEX (T::*getN) (void) const);
+
+template <typename T, typename U, typename INDEX>
+Ptr<ParamSpec>
+MakeObjectVectorParamSpec (INDEX (T::*getN) (void) const,
+			   Ptr<U> (T::*get) (INDEX) const);
+
+
+} // namespace ns3
+
+namespace ns3 {
+
+class ObjectVectorValue : public Value
+{
+public:
+  ObjectVectorValue ();
+  ObjectVectorValue (const ObjectVector &vector);
+
+  ObjectVector Get (void) const;
+
+  virtual PValue Copy (void) const;
+  virtual std::string SerializeToString (Ptr<const ParamSpec> spec) const;
+  virtual bool DeserializeFromString (std::string value, Ptr<const ParamSpec> spec);
+
+private:
+  friend class ObjectVectorParamSpec;
+  ObjectVector m_vector;
+};
+
+class ObjectVectorParamSpec : public ParamSpec
+{
+public:
+  virtual bool Set (ObjectBase * object, PValue value) const;
+  virtual bool Get (const ObjectBase * object, PValue value) const;
+  virtual bool Check (PValue value) const;
+  virtual PValue GetInitialValue (void) const;
+  virtual PValue CreateValue (void) const;
+private:
+  virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const = 0;
+  virtual Ptr<Object> DoGet (const ObjectBase *object, uint32_t i) const = 0;
+};
+
+template <typename T, typename U>
+Ptr<ParamSpec>
+MakeObjectVectorParamSpec (U T::*memberVector)
+{
+  struct MemberStdContainer : public ObjectVectorParamSpec
+  {
+    virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const {
+      const T *obj = dynamic_cast<const T *> (object);
+      if (obj == 0)
+	{
+	  return false;
+	}
+      *n = (obj->*m_memberVector).size ();
+      return true;
+    }
+    virtual Ptr<Object> DoGet (const ObjectBase *object, uint32_t i) const {
+      const T *obj = static_cast<const T *> (object);
+      return (obj->*m_memberVector)[i];
+    }
+    U T::*m_memberVector;
+  } *spec = new MemberStdContainer ();
+  spec->m_memberVector = memberVector;
+  return Ptr<ParamSpec> (spec, false);
+}
+
+template <typename T, typename U, typename INDEX>
+Ptr<ParamSpec>
+MakeObjectVectorParamSpec (Ptr<U> (T::*get) (INDEX) const,
+			   INDEX (T::*getN) (void) const)
+{
+  struct MemberGetters : public ObjectVectorParamSpec
+  {
+    virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const {
+      const T *obj = dynamic_cast<const T *> (object);
+      if (obj == 0)
+	{
+	  return false;
+	}
+      *n = (obj->*m_getN) ();
+      return true;
+    }
+    virtual Ptr<Object> DoGet (const ObjectBase *object, uint32_t i) const {
+      const T *obj = static_cast<const T *> (object);
+      return (obj->*m_get) (i);
+    }
+    Ptr<U> (T::*m_get) (INDEX) const;
+    INDEX (T::*m_getN) (void) const;
+  } *spec = new MemberGetters ();
+  spec->m_get = get;
+  spec->m_getN = getN;
+  return Ptr<ParamSpec> (spec, false);
+}
+
+template <typename T, typename U, typename INDEX>
+Ptr<ParamSpec>
+MakeObjectVectorParamSpec (INDEX (T::*getN) (void) const,
+			   Ptr<U> (T::*get) (INDEX) const)
+{
+  return MakeObjectVectorParamSpec (get, getN);
+}
+
+} // namespace ns3
+
+#endif /* OBJECT_VECTOR_H */
--- a/src/core/value-test.cc	Sat Feb 09 02:35:38 2008 +0100
+++ b/src/core/value-test.cc	Mon Feb 11 04:26:09 2008 +0100
@@ -7,6 +7,8 @@
 #include "enum-value.h"
 #include "random-variable.h"
 #include "fp-value.h"
+#include "object-vector.h"
+
 namespace ns3 {
 
 class ParamSpecTest : public Test
@@ -70,11 +72,23 @@
 						  ConstantVariable (1.0)))
       .AddParameter ("TestFloat", "help text",
 		     MakeFpParamSpec (&ParamSpecObjectTest::m_float, -1.1))
+      .AddParameter ("TestVector1", "help text",
+		     MakeObjectVectorParamSpec (&ParamSpecObjectTest::m_vector1))
+      .AddParameter ("TestVector2", "help text",
+		     MakeObjectVectorParamSpec (&ParamSpecObjectTest::DoGetVectorN,
+						&ParamSpecObjectTest::DoGetVector))
       ;
         
     return tid;
   }
 
+  void AddToVector1 (void) {
+    m_vector1.push_back (CreateObject<Derived> ());
+  }
+  void AddToVector2 (void) {
+    m_vector2.push_back (CreateObject<Derived> ());
+  }
+
 private:
   void DoSetTestB (bool v) {
     m_boolTestA = v;
@@ -88,6 +102,12 @@
   void DoSetInt16 (int16_t v) {
     m_int16SetGet = v;
   }
+  uint32_t DoGetVectorN (void) const {
+    return m_vector2.size ();
+  }
+  Ptr<Derived> DoGetVector (uint32_t i) const {
+    return m_vector2[i];
+  }
   bool m_boolTestA;
   bool m_boolTest;
   Ptr<Derived> m_derived;
@@ -98,6 +118,8 @@
   float m_float;
   enum TestEnum m_enum;
   RandomVariable m_random;
+  std::vector<Ptr<Derived> > m_vector1;
+  std::vector<Ptr<Derived> > m_vector2;
 };
 
 
@@ -119,7 +141,6 @@
     NS_TEST_ASSERT_EQUAL (got.Get (), expected.Get ());	\
   }
 
-
 NS_OBJECT_ENSURE_REGISTERED (ParamSpecObjectTest);
 
 ParamSpecTest::ParamSpecTest ()
@@ -269,21 +290,51 @@
   RandomVariable ran = p->Get ("TestRandom");
   NS_TEST_ASSERT (p->Set ("TestRandom", UniformVariable (0.0, 1.0)));
   NS_TEST_ASSERT (p->Set ("TestRandom", ConstantVariable (10.0)));
+
+  {
+    ObjectVector vector = p->Get ("TestVector1");
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
+    p->AddToVector1 ();
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
+    vector = p->Get ("TestVector1");
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
+    Ptr<Object> a = vector.Get (0);
+    NS_TEST_ASSERT_UNEQUAL (a, 0);
+    p->AddToVector1 ();
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
+    vector = p->Get ("TestVector1");
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 2);
+  }
+
+  {
+    ObjectVector vector = p->Get ("TestVector2");
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
+    p->AddToVector2 ();
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
+    vector = p->Get ("TestVector2");
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
+    Ptr<Object> a = vector.Get (0);
+    NS_TEST_ASSERT_UNEQUAL (a, 0);
+    p->AddToVector2 ();
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
+    vector = p->Get ("TestVector2");
+    NS_TEST_ASSERT_EQUAL (vector.GetN (), 2);
+  }
   
 
 #if 0
-  p->Set ("TestBoolName", "true");
-  NS_TEST_ASSERT_EQUAL (p->Get ("TestBoolName"), "true");
-  p->Set ("TestBoolName", "false");
-  NS_TEST_ASSERT_EQUAL (p->Get ("TestBoolName"), "false");
+  p->Set ("TestBool"TestVector2"", "true");
+  NS_TEST_ASSERT_EQUAL (p->Get ("TestBool"), "true");
+  p->Set ("TestBool", "false");
+  NS_TEST_ASSERT_EQUAL (p->Get ("TestBool"), "false");
 
-  Parameters::GetGlobal ()->Set ("TestBoolName", "true");
+  Parameters::GetGlobal ()->Set ("TestBool", "true");
   p = CreateObjectWith<ParamSpecObjectTest> ();
-  NS_TEST_ASSERT_EQUAL (p->Get ("TestBoolName"), "true");
+  NS_TEST_ASSERT_EQUAL (p->Get ("TestBool"), "true");
 
-  Parameters::GetGlobal ()->Set ("TestBoolName", "false");
+  Parameters::GetGlobal ()->Set ("TestBool", "false");
   p = CreateObjectWith<ParamSpecObjectTest> ();
-  NS_TEST_ASSERT_EQUAL (p->Get ("TestBoolName"), "false");
+  NS_TEST_ASSERT_EQUAL (p->Get ("TestBool"), "false");
 #endif
   return result;
 }
--- a/src/core/wscript	Sat Feb 09 02:35:38 2008 +0100
+++ b/src/core/wscript	Mon Feb 11 04:26:09 2008 +0100
@@ -61,6 +61,7 @@
         'enum-value.cc',
         'fp-value.cc',
         'object-factory.cc',
+        'object-vector.cc',
         ]
 
     if sys.platform == 'win32':