Pointer class for primitive type pointer.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed, 09 Apr 2008 11:46:04 -0700
changeset 2926 96d1fc816681
parent 2901 81ac5e25e8c2
child 2927 73b47ce1d805
Pointer class for primitive type pointer.
src/core/attribute-test.cc
src/core/pointer.cc
src/core/pointer.h
src/core/wscript
--- a/src/core/attribute-test.cc	Wed Apr 09 10:04:16 2008 -0700
+++ b/src/core/attribute-test.cc	Wed Apr 09 11:46:04 2008 -0700
@@ -30,6 +30,7 @@
 #include "object-vector.h"
 #include "traced-value.h"
 #include "trace-source-accessor.h"
+#include "pointer.h"
 
 namespace ns3 {
 
@@ -171,6 +172,10 @@
 		       MakeTraceSourceAccessor (&AttributeObjectTest::m_cb))
       .AddTraceSource ("ValueSource", "help text",
 		       MakeTraceSourceAccessor (&AttributeObjectTest::m_valueSrc))
+      .AddAttribute ("Pointer", "XXX",
+                     Pointer (),
+                     MakePointerAccessor (&AttributeObjectTest::m_ptr),
+                     MakePointerChecker<Derived> ())
       ;
         
     return tid;
@@ -228,6 +233,7 @@
   TracedValue<int8_t> m_intSrc2;
   TracedCallback<double, int, float> m_cb;
   TracedValue<ValueClassTest> m_valueSrc;
+  Ptr<Derived> m_ptr;
 };
 
 
@@ -481,6 +487,24 @@
   NS_TEST_ASSERT_EQUAL (m_got2, 1.0);
 
   NS_TEST_ASSERT (p->TraceConnectWithoutContext ("ValueSource", MakeCallback (&AttributeTest::NotifySourceValue, this)));
+
+
+  derived = Pointer (p->GetAttribute ("Pointer"));
+  NS_TEST_ASSERT (derived == 0);
+  derived = Create<Derived> ();
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("Pointer", Pointer (derived)));
+  stored = Pointer (p->GetAttribute ("Pointer"));
+  NS_TEST_ASSERT (stored == derived);
+  storedBase = Pointer (p->GetAttribute ("Pointer"));
+  NS_TEST_ASSERT (stored == storedBase);
+  x = Pointer (p->GetAttribute ("Pointer"));
+  NS_TEST_ASSERT (x == 0);
+
+  p = CreateObject<AttributeObjectTest> ("Pointer", Pointer (Create<Derived> ()));
+  NS_TEST_ASSERT (p != 0);
+  derived = 0;
+  derived = Pointer (p->GetAttribute ("Pointer"));
+  NS_TEST_ASSERT (derived != 0);
   
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/pointer.cc	Wed Apr 09 11:46:04 2008 -0700
@@ -0,0 +1,59 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "pointer.h"
+
+namespace ns3 {
+
+Pointer::Pointer ()
+  : m_value ()
+{}
+
+Pointer::Pointer (Ptr<Object> object)
+  : m_value (object)
+{}
+
+void 
+Pointer::SetObject (Ptr<Object> object)
+{
+  m_value = object;
+}
+
+Ptr<Object> 
+Pointer::GetObject (void) const
+{
+  return m_value;
+}
+
+ATTRIBUTE_VALUE_IMPLEMENT (Pointer);
+ATTRIBUTE_CONVERTER_IMPLEMENT (Pointer);
+
+std::ostream & operator << (std::ostream &os, const Pointer &pointer)
+{
+  os << pointer.GetObject ();
+  return os;
+}
+std::istream & operator >> (std::istream &is, Pointer &pointer)
+{
+  // XXX: This cannot work;
+  return is;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/pointer.h	Wed Apr 09 11:46:04 2008 -0700
@@ -0,0 +1,297 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef NS_POINTER_H
+#define NS_POINTER_H
+
+#include "attribute.h"
+#include "object.h"
+
+namespace ns3 {
+
+class Pointer
+{
+public:
+  Pointer ();
+
+  Pointer (Ptr<Object> object);
+
+  void SetObject (Ptr<Object> object);
+
+  Ptr<Object> GetObject (void) const;
+
+  template <typename T>
+  Pointer (const Ptr<T> &object);
+
+  template <typename T>
+  void Set (const Ptr<T> &object);
+
+  template <typename T>
+  Ptr<T> Get (void) const;
+
+  template <typename T>
+  operator Ptr<T> () const;
+
+  ATTRIBUTE_CONVERTER_DEFINE (Pointer);
+private:
+  Ptr<Object> m_value;
+};
+
+std::ostream & operator << (std::ostream &os, const Pointer &pointer);
+std::istream & operator >> (std::istream &is, Pointer &pointer);
+
+ATTRIBUTE_VALUE_DEFINE (Pointer);
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> T::*memberVariable);
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>));
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const);
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>),
+		     Ptr<U> (T::*getter) (void) const);
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
+		     void (T::*setter) (Ptr<U>));
+
+class PointerChecker : public AttributeChecker {};
+template <typename T>
+Ptr<AttributeChecker> MakePointerChecker (void);
+
+} // namespace ns3
+
+namespace ns3 {
+
+
+namespace internal {
+
+template <typename T>
+class APointerChecker : public PtrChecker
+{
+  virtual bool Check (Attribute val) const {
+    const PointerValue *value = val.DynCast<const PointerValue *> ();
+    if (value == 0)
+      {
+	return false;
+      }
+    if (value->Get ().GetObject () == 0)
+      {
+	return true;
+      }
+    T *ptr = dynamic_cast<T*> (PeekPointer (value->Get ().GetObject ()));
+    if (ptr == 0)
+      {
+	return false;
+      }
+    return true;
+  }
+  virtual std::string GetType (void) const {
+    // XXX: we should be able to return better information
+    TypeId tid = T::GetTypeId ();
+    return "Ptr<" + tid.GetName () + ">";
+  }
+  virtual bool HasTypeConstraints (void) const {
+    return false;
+  }
+  virtual std::string GetTypeConstraints (void) const {
+    return "";
+  }
+  virtual Attribute Create (void) const {
+    return Attribute::Create<PointerValue> ();
+  }
+};
+
+/********************************************************
+ *              The Accessor associated to 
+ *               PointerValue
+ ********************************************************/
+
+template <typename T, typename U>
+class PointerAccessor : public AttributeAccessor
+{
+public:
+  virtual ~PointerAccessor () {}
+  virtual bool Set (ObjectBase * object, Attribute val) const {
+      T *obj = dynamic_cast<T *> (object);
+      if (obj == 0)
+        {
+          return false;
+        }
+      const PointerValue *value = val.DynCast<const PointerValue *> ();
+      if (value == 0)
+        {
+          return false;
+        }
+      Ptr<U> ptr = dynamic_cast<U*> (PeekPointer (value->Get ().GetObject ()));
+      if (ptr == 0)
+        {
+          return false;
+        }
+      DoSet (obj, ptr);
+      return true;
+    }
+  virtual bool Get (const ObjectBase * object, Attribute val) const {
+      const T *obj = dynamic_cast<const T *> (object);
+      if (obj == 0)
+        {
+          return false;
+        }
+      PointerValue *value = val.DynCast<PointerValue *> ();
+      if (value == 0)
+        {
+          return false;
+        }
+      value->Set (Pointer (DoGet (obj)));
+      return true;
+    }
+private:
+  virtual void DoSet (T *object, Ptr<U> value) const = 0;
+  virtual Ptr<U> DoGet (const T *object) const = 0;
+};
+
+} // namespace internal
+
+
+template <typename T>
+Pointer::Pointer (const Ptr<T> &object)
+{
+  m_value = object;
+}
+
+template <typename T>
+void 
+Pointer::Set (const Ptr<T> &object)
+{
+  m_value = object;
+}
+
+template <typename T>
+Ptr<T> 
+Pointer::Get (void) const
+{
+  T *v = dynamic_cast<T *> (PeekPointer (m_value));
+  return v;
+}
+
+template <typename T>
+Pointer::operator Ptr<T> () const
+{
+  return Get<T> ();
+}
+
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> T::*memberVariable)
+{
+  struct MemberVariable : public internal::PointerAccessor<T,U>
+  {
+    Ptr<U> T::*m_memberVariable;
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      (object->*m_memberVariable) = value;
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return object->*m_memberVariable;
+    }
+  } *spec = new MemberVariable ();
+  spec->m_memberVariable = memberVariable;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>))
+{
+  struct MemberMethod : public internal::PointerAccessor<T,U>
+  {
+    void (T::*m_setter) (Ptr<U>);
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      (object->*m_setter) (value);
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return 0;
+      //return (object->*m_getter) ();
+    }
+  } *spec = new MemberMethod ();
+  spec->m_setter = setter;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const)
+{
+  struct MemberMethod : public internal::PointerAccessor<T,U>
+  {
+    Ptr<U> (T::*m_getter) (void) const;
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      //(object->*m_setter) (value);
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return (object->*m_getter) ();
+    }
+  } *spec = new MemberMethod ();
+  spec->m_getter = getter;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>),
+		     Ptr<U> (T::*getter) (void) const)
+{
+  return MakePointerAccessor (getter, setter);
+}
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
+		     void (T::*setter) (Ptr<U>))
+{
+  struct MemberMethod : public internal::PointerAccessor<T,U>
+  {
+    void (T::*m_setter) (Ptr<U>);
+    Ptr<U> (T::*m_getter) (void) const;
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      (object->*m_setter) (value);
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return (object->*m_getter) ();
+    }
+  } *spec = new MemberMethod ();
+  spec->m_setter = setter;
+  spec->m_getter = getter;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+
+template <typename T>
+Ptr<AttributeChecker>
+MakePointerChecker (void)
+{
+  return Create<internal::APointerChecker<T> > ();
+}
+
+
+} // namespace ns3
+
+#endif /* NS_POINTER_H */
--- a/src/core/wscript	Wed Apr 09 10:04:16 2008 -0700
+++ b/src/core/wscript	Wed Apr 09 11:46:04 2008 -0700
@@ -52,6 +52,7 @@
         'enum.cc',
         'double.cc',
         'string.cc',
+        'pointer.cc',
         'object-factory.cc',
         'object-vector.cc',
         'global-value.cc',
@@ -100,6 +101,7 @@
         'double.h',
         'enum.h',
         'string.h',
+        'pointer.h',
         'object-factory.h',
         'attribute-helper.h',
         'global-value.h',