diff --git a/src/core/attribute-accessor-helper.h b/src/core/attribute-accessor-helper.h index fefce3a3e..cee4bae86 100644 --- a/src/core/attribute-accessor-helper.h +++ b/src/core/attribute-accessor-helper.h @@ -48,6 +48,12 @@ MakeAccessorHelper (T1 a1, T2 a2); namespace ns3 { +template +struct AccessorTrait +{ + typedef typename TypeTraits::ReferencedType>::NonConstType Result; +}; + template class AccessorHelper : public AttributeAccessor { @@ -100,7 +106,13 @@ DoMakeAccessorHelperOne (U T::*memberVariable) {} private: virtual bool DoSet (T *object, const V *v) const { - (object->*m_memberVariable) = U (v->Get ()); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (object->*m_memberVariable) = tmp; return true; } virtual bool DoGet (const T *object, V *v) const { @@ -163,7 +175,13 @@ DoMakeAccessorHelperOne (void (T::*setter) (U)) {} private: virtual bool DoSet (T *object, const V *v) const { - (object->*m_setter) (U (v->Get ())); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (object->*m_setter) (tmp); return true; } virtual bool DoGet (const T *object, V *v) const { @@ -196,7 +214,13 @@ DoMakeAccessorHelperTwo (void (T::*setter) (U), {} private: virtual bool DoSet (T *object, const W *v) const { - (object->*m_setter) (v->Get ()); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (object->*m_setter) (tmp); return true; } virtual bool DoGet (const T *object, W *v) const { @@ -239,7 +263,13 @@ DoMakeAccessorHelperTwo (bool (T::*setter) (U), {} private: virtual bool DoSet (T *object, const W *v) const { - bool ok = (object->*m_setter) (v->Get ()); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + ok = (object->*m_setter) (tmp); return ok; } virtual bool DoGet (const T *object, W *v) const { diff --git a/src/core/attribute-helper.h b/src/core/attribute-helper.h index 7e86578a5..8637e6776 100644 --- a/src/core/attribute-helper.h +++ b/src/core/attribute-helper.h @@ -117,6 +117,11 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying) name##Value (const type &value); \ void Set (const type &value); \ type Get (void) const; \ + template \ + bool GetAccessor (T &value) const { \ + value = T (m_value); \ + return true; \ + } \ virtual Ptr Copy (void) const; \ virtual std::string SerializeToString (Ptr checker) const; \ virtual bool DeserializeFromString (std::string value, Ptr checker); \ @@ -220,17 +225,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying) return MakeSimpleAttributeChecker (#type "Value", name); \ } \ - -/** - * \ingroup AttributeHelper - * \param type the name of the class - * - * This macro implements the conversion operators to and from - * instances of type Attribute. Typically invoked from xxx.cc. - */ -#define ATTRIBUTE_CONVERTER_IMPLEMENT(type) - - /** * \ingroup AttributeHelper * \param type the name of the class @@ -251,7 +245,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying) */ #define ATTRIBUTE_HELPER_CPP(type) \ ATTRIBUTE_CHECKER_IMPLEMENT (type); \ - ATTRIBUTE_CONVERTER_IMPLEMENT (type); \ ATTRIBUTE_VALUE_IMPLEMENT (type); diff --git a/src/core/attribute-test.cc b/src/core/attribute-test.cc index 8b31ca954..b0c3bf74f 100644 --- a/src/core/attribute-test.cc +++ b/src/core/attribute-test.cc @@ -29,6 +29,7 @@ #include "double.h" #include "object-vector.h" #include "traced-value.h" +#include "callback.h" #include "trace-source-accessor.h" #include "pointer.h" @@ -71,9 +72,13 @@ private: void NotifySourceValue (ValueClassTest old, ValueClassTest n) { m_gotValue = n; } + void NotifyCallbackValue (int8_t a) { + m_gotCbValue = a; + } int64_t m_got1; double m_got2; ValueClassTest m_gotValue; + int16_t m_gotCbValue; }; class Derived : public Object @@ -171,6 +176,10 @@ public: PointerValue (), MakePointerAccessor (&AttributeObjectTest::m_ptr), MakePointerChecker ()) + .AddAttribute ("Callback", "help text", + CallbackValue (), + MakeCallbackAccessor (&AttributeObjectTest::m_cbValue), + MakeCallbackChecker ()) ; return tid; @@ -187,6 +196,13 @@ public: m_cb (a,b,c); } + void InvokeCbValue (int8_t a) { + if (!m_cbValue.IsNull ()) + { + m_cbValue (a); + } + } + private: void DoSetTestB (bool v) { m_boolTestA = v; @@ -224,6 +240,7 @@ private: RandomVariable m_random; std::vector > m_vector1; std::vector > m_vector2; + Callback m_cbValue; TracedValue m_intSrc1; TracedValue m_intSrc2; TracedCallback m_cb; @@ -492,6 +509,21 @@ AttributeTest::RunTests (void) derived = ptr.Get (); NS_TEST_ASSERT (derived != 0); + p = CreateObject (); + NS_TEST_ASSERT (p != 0); + m_gotCbValue = 1; + p->InvokeCbValue (2); + CallbackValue cbValue = MakeCallback (&AttributeTest::NotifyCallbackValue, this); + NS_TEST_ASSERT_EQUAL (m_gotCbValue, 1); + NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback", + cbValue)); + p->InvokeCbValue (2); + NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2); + NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback", + CallbackValue (MakeNullCallback ()))); + p->InvokeCbValue (3); + NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2); + return result; } diff --git a/src/core/boolean.h b/src/core/boolean.h index eb15d9506..3fb6096a9 100644 --- a/src/core/boolean.h +++ b/src/core/boolean.h @@ -42,6 +42,8 @@ public: BooleanValue (bool value); void Set (bool value); bool Get (void) const; + template + bool GetAccessor (T &v) const; operator bool () const; @@ -52,6 +54,13 @@ private: bool m_value; }; +template +bool BooleanValue::GetAccessor (T &v) const +{ + v = T (m_value); + return true; +} + std::ostream & operator << (std::ostream &os, const BooleanValue &value); ATTRIBUTE_CHECKER_DEFINE (Boolean); diff --git a/src/core/callback.cc b/src/core/callback.cc new file mode 100644 index 000000000..bc5223cd8 --- /dev/null +++ b/src/core/callback.cc @@ -0,0 +1,38 @@ +#include "callback.h" + +namespace ns3 { + +CallbackValue::CallbackValue () + : m_value () +{} +CallbackValue::CallbackValue (const CallbackBase &base) + : m_value (base) +{} +CallbackValue::~CallbackValue () +{} +void +CallbackValue::Set (CallbackBase base) +{ + m_value = base; +} +Ptr +CallbackValue::Copy (void) const +{ + return Create (m_value); +} +std::string +CallbackValue::SerializeToString (Ptr checker) const +{ + std::ostringstream oss; + oss << PeekPointer (m_value.GetImpl ()); + return oss.str (); +} +bool +CallbackValue::DeserializeFromString (std::string value, Ptr checker) +{ + return false; +} + +ATTRIBUTE_CHECKER_IMPLEMENT (Callback); + +} // namespace ns3 diff --git a/src/core/callback.h b/src/core/callback.h index 30e278478..4a8b15bcb 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -25,6 +25,8 @@ #include "fatal-error.h" #include "empty.h" #include "type-traits.h" +#include "attribute.h" +#include "attribute-helper.h" #include namespace ns3 { @@ -399,7 +401,11 @@ private: return static_cast *> (PeekPointer (m_impl)); } bool DoCheckType (Ptr other) const { - if (dynamic_cast *> (PeekPointer (other)) != 0) + if (other != 0 && dynamic_cast *> (PeekPointer (other)) != 0) + { + return true; + } + else if (other == 0) { return true; } @@ -753,9 +759,45 @@ Callback MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), AR Create > (fnPtr, a); return Callback (impl); } +} // namespace ns3 +namespace ns3 { -}; // namespace ns3 +class CallbackValue : public AttributeValue +{ +public: + CallbackValue (); + CallbackValue (const CallbackBase &base); + virtual ~CallbackValue (); + void Set (CallbackBase base); + template + bool GetAccessor (T &value) const; + virtual Ptr Copy (void) const; + virtual std::string SerializeToString (Ptr checker) const; + virtual bool DeserializeFromString (std::string value, Ptr checker); +private: + CallbackBase m_value; +}; + +ATTRIBUTE_ACCESSOR_DEFINE(Callback); +ATTRIBUTE_CHECKER_DEFINE (Callback); + +} // namespace ns3 + +namespace ns3 { + +template +bool CallbackValue::GetAccessor (T &value) const +{ + if (value.CheckType (m_value)) + { + value.Assign (m_value); + return true; + } + return false; +} + +} // namespace ns3 #endif /* CALLBACK_H */ diff --git a/src/core/config.h b/src/core/config.h index 49b823a69..256b491ef 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -17,8 +17,8 @@ * * Authors: Mathieu Lacage */ -#ifndef NS3_CONFIG_H -#define NS3_CONFIG_H +#ifndef CONFIG_H +#define CONFIG_H #include "ptr.h" #include @@ -139,4 +139,4 @@ Ptr GetRootNamespaceObject (uint32_t i); } // namespace ns3 -#endif /* NS3_CONFIG_H */ +#endif /* CONFIG_H */ diff --git a/src/core/enum.cc b/src/core/enum.cc index 58cc9fcc8..0e1d7812d 100644 --- a/src/core/enum.cc +++ b/src/core/enum.cc @@ -39,7 +39,6 @@ EnumValue::Get (void) const { return m_v; } - Ptr EnumValue::Copy (void) const { diff --git a/src/core/enum.h b/src/core/enum.h index d9eeb521f..b3baf2cd7 100644 --- a/src/core/enum.h +++ b/src/core/enum.h @@ -41,6 +41,8 @@ public: EnumValue (int v); void Set (int v); int Get (void) const; + template + bool GetAccessor (T &v) const; virtual Ptr Copy (void) const; virtual std::string SerializeToString (Ptr checker) const; @@ -50,6 +52,13 @@ private: int m_v; }; +template +bool EnumValue::GetAccessor (T &v) const +{ + v = T (m_v); + return true; +} + class EnumChecker : public AttributeChecker { public: diff --git a/src/core/pointer.h b/src/core/pointer.h index 5fcb28718..4b0e4d671 100644 --- a/src/core/pointer.h +++ b/src/core/pointer.h @@ -50,6 +50,9 @@ public: template Ptr Get (void) const; + template + bool GetAccessor (Ptr &v) const; + template operator Ptr () const; @@ -61,23 +64,6 @@ private: Ptr m_value; }; -template -Ptr -MakePointerAccessor (Ptr T::*memberVariable); -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr)); -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const); -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr), - Ptr (T::*getter) (void) const); -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const, - void (T::*setter) (Ptr)); class PointerChecker : public AttributeChecker { @@ -142,57 +128,8 @@ class APointerChecker : public PointerChecker } }; -/******************************************************** - * The Accessor associated to - * PointerValue - ********************************************************/ - -template -class PointerAccessor : public AttributeAccessor -{ -public: - virtual ~PointerAccessor () {} - virtual bool Set (ObjectBase * object, const AttributeValue &val) const { - T *obj = dynamic_cast (object); - if (obj == 0) - { - return false; - } - const PointerValue *value = dynamic_cast (&val); - if (value == 0) - { - return false; - } - Ptr ptr = dynamic_cast (PeekPointer (value->GetObject ())); - if (ptr == 0) - { - return false; - } - DoSet (obj, ptr); - return true; - } - virtual bool Get (const ObjectBase * object, AttributeValue &val) const { - const T *obj = dynamic_cast (object); - if (obj == 0) - { - return false; - } - PointerValue *value = dynamic_cast (&val); - if (value == 0) - { - return false; - } - value->Set (DoGet (obj)); - return true; - } -private: - virtual void DoSet (T *object, Ptr value) const = 0; - virtual Ptr DoGet (const T *object) const = 0; -}; - } // namespace internal - template PointerValue::PointerValue (const Ptr &object) { @@ -220,112 +157,21 @@ PointerValue::operator Ptr () const return Get (); } - -template -Ptr -MakePointerAccessor (Ptr T::*memberVariable) +template +bool +PointerValue::GetAccessor (Ptr &v) const { - struct MemberVariable : public internal::PointerAccessor - { - Ptr T::*m_memberVariable; - virtual void DoSet (T *object, Ptr value) const { - (object->*m_memberVariable) = value; - } - virtual Ptr DoGet (const T *object) const { - return object->*m_memberVariable; - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return true; - } - } *spec = new MemberVariable (); - spec->m_memberVariable = memberVariable; - return Ptr (spec, false); -} - -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr)) -{ - struct MemberMethod : public internal::PointerAccessor - { - void (T::*m_setter) (Ptr); - virtual void DoSet (T *object, Ptr value) const { - (object->*m_setter) (value); - } - virtual Ptr DoGet (const T *object) const { - return 0; - //return (object->*m_getter) (); - } - virtual bool HasGetter (void) const { + Ptr ptr = dynamic_cast (PeekPointer (m_value)); + if (ptr == 0) + { return false; } - virtual bool HasSetter (void) const { - return true; - } - } *spec = new MemberMethod (); - spec->m_setter = setter; - return Ptr (spec, false); + v = ptr; + return true; } -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const) -{ - struct MemberMethod : public internal::PointerAccessor - { - Ptr (T::*m_getter) (void) const; - virtual void DoSet (T *object, Ptr value) const { - //(object->*m_setter) (value); - } - virtual Ptr DoGet (const T *object) const { - return (object->*m_getter) (); - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return false; - } - } *spec = new MemberMethod (); - spec->m_getter = getter; - return Ptr (spec, false); -} -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr), - Ptr (T::*getter) (void) const) -{ - return MakePointerAccessor (getter, setter); -} -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const, - void (T::*setter) (Ptr)) -{ - struct MemberMethod : public internal::PointerAccessor - { - void (T::*m_setter) (Ptr); - Ptr (T::*m_getter) (void) const; - virtual void DoSet (T *object, Ptr value) const { - (object->*m_setter) (value); - } - virtual Ptr DoGet (const T *object) const { - return (object->*m_getter) (); - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return true; - } - } *spec = new MemberMethod (); - spec->m_setter = setter; - spec->m_getter = getter; - return Ptr (spec, false); -} + +ATTRIBUTE_ACCESSOR_DEFINE (Pointer); template Ptr diff --git a/src/core/string.cc b/src/core/string.cc index fbd70e2be..ae5619244 100644 --- a/src/core/string.cc +++ b/src/core/string.cc @@ -3,7 +3,6 @@ namespace ns3 { ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME (String, "std::string"); -ATTRIBUTE_CONVERTER_IMPLEMENT (String); ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (std::string, String); } // namespace ns3 diff --git a/src/core/wscript b/src/core/wscript index 39b7846e9..de13762a6 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -72,6 +72,7 @@ def build(bld): 'traced-callback.cc', 'trace-source-accessor.cc', 'config.cc', + 'callback.cc', ] core.uselib = 'RT'