author | Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
Thu, 24 May 2007 15:23:11 +0200 | |
changeset 687 | 36e034af3dc1 |
parent 686 | b5afbfc7f512 |
child 688 | 59a865eeeb93 |
child 689 | 49bccd847179 |
SConstruct | file | annotate | diff | comparison | revisions | |
src/core/callback.h | file | annotate | diff | comparison | revisions | |
src/core/reference-list-test.cc | file | annotate | diff | comparison | revisions | |
src/core/reference-list.h | file | annotate | diff | comparison | revisions |
--- a/SConstruct Thu May 24 14:58:24 2007 +0200 +++ b/SConstruct Thu May 24 15:23:11 2007 +0200 @@ -31,7 +31,6 @@ core = build.Ns3Module('core', 'src/core') ns3.add(core) core.add_sources([ - 'reference-list-test.cc', 'callback-test.cc', 'debug.cc', 'assert.cc', @@ -63,7 +62,6 @@ ]) core.add_inst_headers([ 'system-wall-clock-ms.h', - 'reference-list.h', 'callback.h', 'ptr.h', 'object.h',
--- a/src/core/callback.h Thu May 24 14:58:24 2007 +0200 +++ b/src/core/callback.h Thu May 24 15:23:11 2007 +0200 @@ -22,7 +22,7 @@ #ifndef CALLBACK_H #define CALLBACK_H -#include "reference-list.h" +#include "ptr.h" #include "fatal-error.h" namespace ns3 { @@ -72,8 +72,21 @@ class CallbackImplBase { public: + CallbackImplBase () + : m_count (1) {} virtual ~CallbackImplBase () {} + void Ref (void) { + m_count++; + } + void Unref (void) { + m_count--; + if (m_count == 0) { + delete this; + } + } virtual bool IsEqual (CallbackImplBase const *other) const = 0; +private: + uint32_t m_count; }; // declare the CallbackImpl class @@ -128,7 +141,7 @@ class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> { public: FunctorCallbackImpl (T const &functor) - : m_functor (functor) {} + : m_functor (functor) {} virtual ~FunctorCallbackImpl () {} R operator() (void) { return m_functor (); @@ -170,7 +183,7 @@ class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> { public: MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr) - : m_objPtr (objPtr), m_memPtr (mem_ptr) {} + : m_objPtr (objPtr), m_memPtr (mem_ptr) {} virtual ~MemPtrCallbackImpl () {} R operator() (void) { return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (); @@ -254,20 +267,20 @@ // always properly disambiguited by the c++ compiler template <typename FUNCTOR> Callback (FUNCTOR const &functor, bool, bool) - : m_impl (new FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> (functor)) + : m_impl (MakeNewObject<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> > (functor)) {} template <typename OBJ_PTR, typename MEM_PTR> Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr) - : m_impl (new MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> (objPtr, mem_ptr)) + : m_impl (MakeNewObject<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> > (objPtr, mem_ptr)) {} - Callback (ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5> *> const &impl) + Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > const &impl) : m_impl (impl) {} bool IsNull (void) { - return (m_impl.Get () == 0)?true:false; + return (PeekImpl () == 0)?true:false; } void Nullify (void) { m_impl = 0; @@ -275,22 +288,22 @@ Callback () : m_impl () {} R operator() (void) const { - return (*(m_impl.Get ())) (); + return (*(PeekImpl ())) (); } R operator() (T1 a1) const { - return (*(m_impl.Get ())) (a1); + return (*(PeekImpl ())) (a1); } R operator() (T1 a1, T2 a2) const { - return (*(m_impl).Get ()) (a1,a2); + return (*(PeekImpl ())) (a1,a2); } R operator() (T1 a1, T2 a2, T3 a3) const { - return (*(m_impl).Get ()) (a1,a2,a3); + return (*(PeekImpl ())) (a1,a2,a3); } R operator() (T1 a1, T2 a2, T3 a3, T4 a4) const { - return (*(m_impl).Get ()) (a1,a2,a3,a4); + return (*(PeekImpl ())) (a1,a2,a3,a4); } R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const { - return (*(m_impl).Get ()) (a1,a2,a3,a4,a5); + return (*(PeekImpl ())) (a1,a2,a3,a4,a5); } bool IsEqual (CallbackBase const &other) { @@ -319,10 +332,10 @@ *this = *goodType; } private: - virtual CallbackImplBase *PeekImpl (void) const { - return m_impl.Get (); + virtual CallbackImpl<R,T1,T2,T3,T4,T5> *PeekImpl (void) const { + return PeekPointer (m_impl); } - ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> m_impl; + Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > m_impl; }; /** @@ -614,44 +627,34 @@ template <typename R, typename TX> Callback<R> MakeBoundCallback (R (*fnPtr) (TX), TX a) { - ReferenceList<CallbackImpl<R,empty,empty,empty,empty,empty>*> impl = - ReferenceList<CallbackImpl<R,empty,empty,empty,empty,empty>*> ( - new BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> (fnPtr, a) - ); + Ptr<CallbackImpl<R,empty,empty,empty,empty,empty> > impl = + MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> >(fnPtr, a); return Callback<R> (impl); } template <typename R, typename TX, typename T1> Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) { - ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> impl = - ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> ( - new BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> (fnPtr, a) - ); + Ptr<CallbackImpl<R,T1,empty,empty,empty,empty> > impl = + MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> > (fnPtr, a); return Callback<R,T1> (impl); } template <typename R, typename TX, typename T1, typename T2> Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) { - ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> impl = - ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> ( - new BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> (fnPtr, a) - ); + Ptr<CallbackImpl<R,T1,T2,empty,empty,empty> > impl = + MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> > (fnPtr, a); return Callback<R,T1,T2> (impl); } template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4> Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) { - ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> impl = - ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> ( - new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> (fnPtr, a) - ); + Ptr<CallbackImpl<R,T1,T2,T3,T4,empty> > impl = + MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> > (fnPtr, a); return Callback<R,T1,T2,T3,T4> (impl); } template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5> Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) { - ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> impl = - ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> ( - new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> (fnPtr, a) - ); + Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > impl = + MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a); return Callback<R,T1,T2,T3,T4,T5> (impl); }
--- a/src/core/reference-list-test.cc Thu May 24 14:58:24 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * All rights reserved. - * - * 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 - * - * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> - */ -#include "reference-list.h" -#include "test.h" - -#ifdef RUN_SELF_TESTS - -#define noREFTEST_DEBUG 1 - -#ifdef REFTEST_DEBUG -#include <iostream> -#define TRACE(x) \ - std::cout << x << std::endl; -#else -#define TRACE(x) -#endif - -namespace { - -class A { -public: - A () { - TRACE ("constructor"); - } - ~A () { - TRACE ("destructor"); - } - void Trace (void) { - TRACE ("trace"); - } -}; - -class RefTest : public ns3::Test { -public: - RefTest (); - virtual bool RunTests (void); -private: - void OneTest (ns3::ReferenceList<A *>); -}; - -RefTest::RefTest () - : ns3::Test ("ReferenceList") -{} - -void -RefTest::OneTest (ns3::ReferenceList<A *> a) -{ - a->Trace (); -} - -bool -RefTest::RunTests (void) -{ - bool ok = true; - - { - ns3::ReferenceList<A *> tmp; - { - ns3::ReferenceList<A *> a (new A ()); - - OneTest (a); - tmp = a; - OneTest (tmp); - a = tmp; - OneTest (a); - TRACE ("leave inner scope"); - } - OneTest (tmp); - TRACE ("leave outer scope"); - } - - { - ns3::ReferenceList<A *> tmp; - } - - { - ns3::ReferenceList<A *> tmp (new A ()); - } - - { - ns3::ReferenceList<A *> tmp; - tmp.Set (new A ()); - } - - { - TRACE ("test assignement"); - ns3::ReferenceList<A *> a0 (new A ()); - ns3::ReferenceList<A *> a1 (new A ()); - a0 = a1; - } - - - - return ok; -} - - -static RefTest gRefTest = RefTest (); - -}; // namespace - -#endif /* RUN_SELF_TESTS */
--- a/src/core/reference-list.h Thu May 24 14:58:24 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * All rights reserved. - * - * 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 - * - * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> - */ -#ifndef REFERENCE_LIST_H -#define REFERENCE_LIST_H - -/* This is a reference list implementation. The technique underlying - * this code was first described in 1995 by Risto Lankinen on Usenet - * but I have never been able to find his original posting. Instead, - * this code is based on the description of the technique found in - * "Modern C++ design" by Andrei Alexandrescu in chapter 7. - */ - - -namespace ns3 { - -template <typename OBJ_PTR> -class ReferenceList; - -template <typename OBJ_PTR> -class ReferenceList { -public: - ReferenceList () - : m_objPtr (), - m_prev (), - m_next () - { - m_prev = this; - m_next = this; - } - ReferenceList (ReferenceList &o) - : m_objPtr (), - m_prev (), - m_next () - { - m_prev = this; - m_next = this; - InsertSelfInOther (o); - } - ReferenceList (ReferenceList const&o) - : m_objPtr (), - m_prev (), - m_next () - { - m_prev = this; - m_next = this; - InsertSelfInOther (o); - } - ReferenceList (OBJ_PTR const &objPtr) - : m_objPtr (objPtr), - m_prev (), - m_next () - { - m_prev = this; - m_next = this; - } - ~ReferenceList () { - RemoveFromList (); - } - ReferenceList & operator= (ReferenceList const&o) { - RemoveFromList (); - InsertSelfInOther (o); - return *this; - } - OBJ_PTR operator-> () const { - return m_objPtr; - } - void Set (OBJ_PTR objPtr) { - RemoveFromList (); - m_objPtr = objPtr; - } - OBJ_PTR Get (void) const { - // explicit conversion to raw pointer type. - return m_objPtr; - } -private: - void InsertSelfInOther (ReferenceList const&o) { - m_prev = &o; - m_next = o.m_next; - m_next->m_prev = this; - o.m_next = this; - m_objPtr = o.m_objPtr; - } - void RemoveFromList (void) { - if (m_prev == this) - { - //NS_ASSERT (m_next == this); - delete m_objPtr; - m_objPtr = OBJ_PTR (); - } - m_prev->m_next = m_next; - m_next->m_prev = m_prev; - } - OBJ_PTR m_objPtr; - mutable ReferenceList const*m_prev; - mutable ReferenceList const*m_next; -}; - -}; // namespace ns3 - -#endif /* REFERENCE_LIST_H */