Pointer class for primitive type pointer.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed Apr 09 11:46:04 2008 -0700 (22 months ago)
changeset 292696d1fc816681
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
     1.1 --- a/src/core/attribute-test.cc	Wed Apr 09 10:04:16 2008 -0700
     1.2 +++ b/src/core/attribute-test.cc	Wed Apr 09 11:46:04 2008 -0700
     1.3 @@ -30,6 +30,7 @@
     1.4  #include "object-vector.h"
     1.5  #include "traced-value.h"
     1.6  #include "trace-source-accessor.h"
     1.7 +#include "pointer.h"
     1.8  
     1.9  namespace ns3 {
    1.10  
    1.11 @@ -171,6 +172,10 @@
    1.12  		       MakeTraceSourceAccessor (&AttributeObjectTest::m_cb))
    1.13        .AddTraceSource ("ValueSource", "help text",
    1.14  		       MakeTraceSourceAccessor (&AttributeObjectTest::m_valueSrc))
    1.15 +      .AddAttribute ("Pointer", "XXX",
    1.16 +                     Pointer (),
    1.17 +                     MakePointerAccessor (&AttributeObjectTest::m_ptr),
    1.18 +                     MakePointerChecker<Derived> ())
    1.19        ;
    1.20          
    1.21      return tid;
    1.22 @@ -228,6 +233,7 @@
    1.23    TracedValue<int8_t> m_intSrc2;
    1.24    TracedCallback<double, int, float> m_cb;
    1.25    TracedValue<ValueClassTest> m_valueSrc;
    1.26 +  Ptr<Derived> m_ptr;
    1.27  };
    1.28  
    1.29  
    1.30 @@ -481,6 +487,24 @@
    1.31    NS_TEST_ASSERT_EQUAL (m_got2, 1.0);
    1.32  
    1.33    NS_TEST_ASSERT (p->TraceConnectWithoutContext ("ValueSource", MakeCallback (&AttributeTest::NotifySourceValue, this)));
    1.34 +
    1.35 +
    1.36 +  derived = Pointer (p->GetAttribute ("Pointer"));
    1.37 +  NS_TEST_ASSERT (derived == 0);
    1.38 +  derived = Create<Derived> ();
    1.39 +  NS_TEST_ASSERT (p->SetAttributeFailSafe("Pointer", Pointer (derived)));
    1.40 +  stored = Pointer (p->GetAttribute ("Pointer"));
    1.41 +  NS_TEST_ASSERT (stored == derived);
    1.42 +  storedBase = Pointer (p->GetAttribute ("Pointer"));
    1.43 +  NS_TEST_ASSERT (stored == storedBase);
    1.44 +  x = Pointer (p->GetAttribute ("Pointer"));
    1.45 +  NS_TEST_ASSERT (x == 0);
    1.46 +
    1.47 +  p = CreateObject<AttributeObjectTest> ("Pointer", Pointer (Create<Derived> ()));
    1.48 +  NS_TEST_ASSERT (p != 0);
    1.49 +  derived = 0;
    1.50 +  derived = Pointer (p->GetAttribute ("Pointer"));
    1.51 +  NS_TEST_ASSERT (derived != 0);
    1.52    
    1.53  
    1.54  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/core/pointer.cc	Wed Apr 09 11:46:04 2008 -0700
     2.3 @@ -0,0 +1,59 @@
     2.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2.5 +/*
     2.6 + * Copyright (c) 2008 INRIA
     2.7 + *
     2.8 + * This program is free software; you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License version 2 as
    2.10 + * published by the Free Software Foundation;
    2.11 + *
    2.12 + * This program is distributed in the hope that it will be useful,
    2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.15 + * GNU General Public License for more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License
    2.18 + * along with this program; if not, write to the Free Software
    2.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.20 + *
    2.21 + * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    2.22 + */
    2.23 +#include "pointer.h"
    2.24 +
    2.25 +namespace ns3 {
    2.26 +
    2.27 +Pointer::Pointer ()
    2.28 +  : m_value ()
    2.29 +{}
    2.30 +
    2.31 +Pointer::Pointer (Ptr<Object> object)
    2.32 +  : m_value (object)
    2.33 +{}
    2.34 +
    2.35 +void 
    2.36 +Pointer::SetObject (Ptr<Object> object)
    2.37 +{
    2.38 +  m_value = object;
    2.39 +}
    2.40 +
    2.41 +Ptr<Object> 
    2.42 +Pointer::GetObject (void) const
    2.43 +{
    2.44 +  return m_value;
    2.45 +}
    2.46 +
    2.47 +ATTRIBUTE_VALUE_IMPLEMENT (Pointer);
    2.48 +ATTRIBUTE_CONVERTER_IMPLEMENT (Pointer);
    2.49 +
    2.50 +std::ostream & operator << (std::ostream &os, const Pointer &pointer)
    2.51 +{
    2.52 +  os << pointer.GetObject ();
    2.53 +  return os;
    2.54 +}
    2.55 +std::istream & operator >> (std::istream &is, Pointer &pointer)
    2.56 +{
    2.57 +  // XXX: This cannot work;
    2.58 +  return is;
    2.59 +}
    2.60 +
    2.61 +
    2.62 +} // namespace ns3
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/core/pointer.h	Wed Apr 09 11:46:04 2008 -0700
     3.3 @@ -0,0 +1,297 @@
     3.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     3.5 +/*
     3.6 + * Copyright (c) 2008 INRIA
     3.7 + *
     3.8 + * This program is free software; you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License version 2 as
    3.10 + * published by the Free Software Foundation;
    3.11 + *
    3.12 + * This program is distributed in the hope that it will be useful,
    3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.15 + * GNU General Public License for more details.
    3.16 + *
    3.17 + * You should have received a copy of the GNU General Public License
    3.18 + * along with this program; if not, write to the Free Software
    3.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.20 + *
    3.21 + * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    3.22 + */
    3.23 +#ifndef NS_POINTER_H
    3.24 +#define NS_POINTER_H
    3.25 +
    3.26 +#include "attribute.h"
    3.27 +#include "object.h"
    3.28 +
    3.29 +namespace ns3 {
    3.30 +
    3.31 +class Pointer
    3.32 +{
    3.33 +public:
    3.34 +  Pointer ();
    3.35 +
    3.36 +  Pointer (Ptr<Object> object);
    3.37 +
    3.38 +  void SetObject (Ptr<Object> object);
    3.39 +
    3.40 +  Ptr<Object> GetObject (void) const;
    3.41 +
    3.42 +  template <typename T>
    3.43 +  Pointer (const Ptr<T> &object);
    3.44 +
    3.45 +  template <typename T>
    3.46 +  void Set (const Ptr<T> &object);
    3.47 +
    3.48 +  template <typename T>
    3.49 +  Ptr<T> Get (void) const;
    3.50 +
    3.51 +  template <typename T>
    3.52 +  operator Ptr<T> () const;
    3.53 +
    3.54 +  ATTRIBUTE_CONVERTER_DEFINE (Pointer);
    3.55 +private:
    3.56 +  Ptr<Object> m_value;
    3.57 +};
    3.58 +
    3.59 +std::ostream & operator << (std::ostream &os, const Pointer &pointer);
    3.60 +std::istream & operator >> (std::istream &is, Pointer &pointer);
    3.61 +
    3.62 +ATTRIBUTE_VALUE_DEFINE (Pointer);
    3.63 +
    3.64 +template <typename T, typename U>
    3.65 +Ptr<const AttributeAccessor>
    3.66 +MakePointerAccessor (Ptr<U> T::*memberVariable);
    3.67 +template <typename T, typename U>
    3.68 +Ptr<const AttributeAccessor>
    3.69 +MakePointerAccessor (void (T::*setter) (Ptr<U>));
    3.70 +template <typename T, typename U>
    3.71 +Ptr<const AttributeAccessor>
    3.72 +MakePointerAccessor (Ptr<U> (T::*getter) (void) const);
    3.73 +template <typename T, typename U>
    3.74 +Ptr<const AttributeAccessor>
    3.75 +MakePointerAccessor (void (T::*setter) (Ptr<U>),
    3.76 +		     Ptr<U> (T::*getter) (void) const);
    3.77 +template <typename T, typename U>
    3.78 +Ptr<const AttributeAccessor>
    3.79 +MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
    3.80 +		     void (T::*setter) (Ptr<U>));
    3.81 +
    3.82 +class PointerChecker : public AttributeChecker {};
    3.83 +template <typename T>
    3.84 +Ptr<AttributeChecker> MakePointerChecker (void);
    3.85 +
    3.86 +} // namespace ns3
    3.87 +
    3.88 +namespace ns3 {
    3.89 +
    3.90 +
    3.91 +namespace internal {
    3.92 +
    3.93 +template <typename T>
    3.94 +class APointerChecker : public PtrChecker
    3.95 +{
    3.96 +  virtual bool Check (Attribute val) const {
    3.97 +    const PointerValue *value = val.DynCast<const PointerValue *> ();
    3.98 +    if (value == 0)
    3.99 +      {
   3.100 +	return false;
   3.101 +      }
   3.102 +    if (value->Get ().GetObject () == 0)
   3.103 +      {
   3.104 +	return true;
   3.105 +      }
   3.106 +    T *ptr = dynamic_cast<T*> (PeekPointer (value->Get ().GetObject ()));
   3.107 +    if (ptr == 0)
   3.108 +      {
   3.109 +	return false;
   3.110 +      }
   3.111 +    return true;
   3.112 +  }
   3.113 +  virtual std::string GetType (void) const {
   3.114 +    // XXX: we should be able to return better information
   3.115 +    TypeId tid = T::GetTypeId ();
   3.116 +    return "Ptr<" + tid.GetName () + ">";
   3.117 +  }
   3.118 +  virtual bool HasTypeConstraints (void) const {
   3.119 +    return false;
   3.120 +  }
   3.121 +  virtual std::string GetTypeConstraints (void) const {
   3.122 +    return "";
   3.123 +  }
   3.124 +  virtual Attribute Create (void) const {
   3.125 +    return Attribute::Create<PointerValue> ();
   3.126 +  }
   3.127 +};
   3.128 +
   3.129 +/********************************************************
   3.130 + *              The Accessor associated to 
   3.131 + *               PointerValue
   3.132 + ********************************************************/
   3.133 +
   3.134 +template <typename T, typename U>
   3.135 +class PointerAccessor : public AttributeAccessor
   3.136 +{
   3.137 +public:
   3.138 +  virtual ~PointerAccessor () {}
   3.139 +  virtual bool Set (ObjectBase * object, Attribute val) const {
   3.140 +      T *obj = dynamic_cast<T *> (object);
   3.141 +      if (obj == 0)
   3.142 +        {
   3.143 +          return false;
   3.144 +        }
   3.145 +      const PointerValue *value = val.DynCast<const PointerValue *> ();
   3.146 +      if (value == 0)
   3.147 +        {
   3.148 +          return false;
   3.149 +        }
   3.150 +      Ptr<U> ptr = dynamic_cast<U*> (PeekPointer (value->Get ().GetObject ()));
   3.151 +      if (ptr == 0)
   3.152 +        {
   3.153 +          return false;
   3.154 +        }
   3.155 +      DoSet (obj, ptr);
   3.156 +      return true;
   3.157 +    }
   3.158 +  virtual bool Get (const ObjectBase * object, Attribute val) const {
   3.159 +      const T *obj = dynamic_cast<const T *> (object);
   3.160 +      if (obj == 0)
   3.161 +        {
   3.162 +          return false;
   3.163 +        }
   3.164 +      PointerValue *value = val.DynCast<PointerValue *> ();
   3.165 +      if (value == 0)
   3.166 +        {
   3.167 +          return false;
   3.168 +        }
   3.169 +      value->Set (Pointer (DoGet (obj)));
   3.170 +      return true;
   3.171 +    }
   3.172 +private:
   3.173 +  virtual void DoSet (T *object, Ptr<U> value) const = 0;
   3.174 +  virtual Ptr<U> DoGet (const T *object) const = 0;
   3.175 +};
   3.176 +
   3.177 +} // namespace internal
   3.178 +
   3.179 +
   3.180 +template <typename T>
   3.181 +Pointer::Pointer (const Ptr<T> &object)
   3.182 +{
   3.183 +  m_value = object;
   3.184 +}
   3.185 +
   3.186 +template <typename T>
   3.187 +void 
   3.188 +Pointer::Set (const Ptr<T> &object)
   3.189 +{
   3.190 +  m_value = object;
   3.191 +}
   3.192 +
   3.193 +template <typename T>
   3.194 +Ptr<T> 
   3.195 +Pointer::Get (void) const
   3.196 +{
   3.197 +  T *v = dynamic_cast<T *> (PeekPointer (m_value));
   3.198 +  return v;
   3.199 +}
   3.200 +
   3.201 +template <typename T>
   3.202 +Pointer::operator Ptr<T> () const
   3.203 +{
   3.204 +  return Get<T> ();
   3.205 +}
   3.206 +
   3.207 +
   3.208 +template <typename T, typename U>
   3.209 +Ptr<const AttributeAccessor>
   3.210 +MakePointerAccessor (Ptr<U> T::*memberVariable)
   3.211 +{
   3.212 +  struct MemberVariable : public internal::PointerAccessor<T,U>
   3.213 +  {
   3.214 +    Ptr<U> T::*m_memberVariable;
   3.215 +    virtual void DoSet (T *object, Ptr<U> value) const {
   3.216 +      (object->*m_memberVariable) = value;
   3.217 +    }
   3.218 +    virtual Ptr<U> DoGet (const T *object) const {
   3.219 +      return object->*m_memberVariable;
   3.220 +    }
   3.221 +  } *spec = new MemberVariable ();
   3.222 +  spec->m_memberVariable = memberVariable;
   3.223 +  return Ptr<const AttributeAccessor> (spec, false);
   3.224 +}
   3.225 +
   3.226 +template <typename T, typename U>
   3.227 +Ptr<const AttributeAccessor>
   3.228 +MakePointerAccessor (void (T::*setter) (Ptr<U>))
   3.229 +{
   3.230 +  struct MemberMethod : public internal::PointerAccessor<T,U>
   3.231 +  {
   3.232 +    void (T::*m_setter) (Ptr<U>);
   3.233 +    virtual void DoSet (T *object, Ptr<U> value) const {
   3.234 +      (object->*m_setter) (value);
   3.235 +    }
   3.236 +    virtual Ptr<U> DoGet (const T *object) const {
   3.237 +      return 0;
   3.238 +      //return (object->*m_getter) ();
   3.239 +    }
   3.240 +  } *spec = new MemberMethod ();
   3.241 +  spec->m_setter = setter;
   3.242 +  return Ptr<const AttributeAccessor> (spec, false);
   3.243 +}
   3.244 +
   3.245 +template <typename T, typename U>
   3.246 +Ptr<const AttributeAccessor>
   3.247 +MakePointerAccessor (Ptr<U> (T::*getter) (void) const)
   3.248 +{
   3.249 +  struct MemberMethod : public internal::PointerAccessor<T,U>
   3.250 +  {
   3.251 +    Ptr<U> (T::*m_getter) (void) const;
   3.252 +    virtual void DoSet (T *object, Ptr<U> value) const {
   3.253 +      //(object->*m_setter) (value);
   3.254 +    }
   3.255 +    virtual Ptr<U> DoGet (const T *object) const {
   3.256 +      return (object->*m_getter) ();
   3.257 +    }
   3.258 +  } *spec = new MemberMethod ();
   3.259 +  spec->m_getter = getter;
   3.260 +  return Ptr<const AttributeAccessor> (spec, false);
   3.261 +}
   3.262 +template <typename T, typename U>
   3.263 +Ptr<const AttributeAccessor>
   3.264 +MakePointerAccessor (void (T::*setter) (Ptr<U>),
   3.265 +		     Ptr<U> (T::*getter) (void) const)
   3.266 +{
   3.267 +  return MakePointerAccessor (getter, setter);
   3.268 +}
   3.269 +template <typename T, typename U>
   3.270 +Ptr<const AttributeAccessor>
   3.271 +MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
   3.272 +		     void (T::*setter) (Ptr<U>))
   3.273 +{
   3.274 +  struct MemberMethod : public internal::PointerAccessor<T,U>
   3.275 +  {
   3.276 +    void (T::*m_setter) (Ptr<U>);
   3.277 +    Ptr<U> (T::*m_getter) (void) const;
   3.278 +    virtual void DoSet (T *object, Ptr<U> value) const {
   3.279 +      (object->*m_setter) (value);
   3.280 +    }
   3.281 +    virtual Ptr<U> DoGet (const T *object) const {
   3.282 +      return (object->*m_getter) ();
   3.283 +    }
   3.284 +  } *spec = new MemberMethod ();
   3.285 +  spec->m_setter = setter;
   3.286 +  spec->m_getter = getter;
   3.287 +  return Ptr<const AttributeAccessor> (spec, false);
   3.288 +}
   3.289 +
   3.290 +template <typename T>
   3.291 +Ptr<AttributeChecker>
   3.292 +MakePointerChecker (void)
   3.293 +{
   3.294 +  return Create<internal::APointerChecker<T> > ();
   3.295 +}
   3.296 +
   3.297 +
   3.298 +} // namespace ns3
   3.299 +
   3.300 +#endif /* NS_POINTER_H */
     4.1 --- a/src/core/wscript	Wed Apr 09 10:04:16 2008 -0700
     4.2 +++ b/src/core/wscript	Wed Apr 09 11:46:04 2008 -0700
     4.3 @@ -52,6 +52,7 @@
     4.4          'enum.cc',
     4.5          'double.cc',
     4.6          'string.cc',
     4.7 +        'pointer.cc',
     4.8          'object-factory.cc',
     4.9          'object-vector.cc',
    4.10          'global-value.cc',
    4.11 @@ -100,6 +101,7 @@
    4.12          'double.h',
    4.13          'enum.h',
    4.14          'string.h',
    4.15 +        'pointer.h',
    4.16          'object-factory.h',
    4.17          'attribute-helper.h',
    4.18          'global-value.h',