Update of /cvsroot/mahogany/M/include
In directory sc8-pr-cvs1:/tmp/cvs-serv2378/include

Modified Files:
        MObject.h MailFolderCmn.h pointers.h 
Log Message:
Cleaned up RefCounter and WeakRef interfaces

Index: MObject.h
===================================================================
RCS file: /cvsroot/mahogany/M/include/MObject.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -b -u -2 -r1.31 -r1.32
--- MObject.h   16 Oct 2003 10:29:22 -0000      1.31
+++ MObject.h   16 Oct 2003 12:17:09 -0000      1.32
@@ -28,5 +28,5 @@
 extern void WeakRefDecrement(MObjectRC *pointer);
 extern void WeakRefAssign(MObjectRC *target,MObjectRC *source);
-extern bool WeakRefExpired(const MObjectRC *pointer);
+extern void *WeakRefConvert(MObjectRC *pointer);
 
 // ----------------------------------------------------------------------------
@@ -209,5 +209,5 @@
    friend void WeakRefDecrement(MObjectRC *pointer);
    friend void WeakRefAssign(MObjectRC *target,MObjectRC *source);
-   friend bool WeakRefExpired(const MObjectRC *pointer);
+   friend void *WeakRefConvert(MObjectRC *pointer);
    
    size_t m_weakRef; // Delay call to ::operator delete() while > 0

Index: MailFolderCmn.h
===================================================================
RCS file: /cvsroot/mahogany/M/include/MailFolderCmn.h,v
retrieving revision 1.85
retrieving revision 1.86
diff -b -u -2 -r1.85 -r1.86
--- MailFolderCmn.h     12 Oct 2003 15:14:01 -0000      1.85
+++ MailFolderCmn.h     16 Oct 2003 12:17:10 -0000      1.86
@@ -39,5 +39,4 @@
 #define TRACE_MF_EVENTS _T("mfevent")
 
-class FilterRule;
 DECLARE_REF_COUNTER(FilterRule)
 
@@ -351,10 +350,10 @@
 {
 public:
-   FilterNewMailContext(FilterRule *rule)
+   FilterNewMailContext(RefCounter<FilterRule> rule)
    {
       if( !m_instance )
       {
          m_instance = this;
-         m_rule.AttachAndIncRef(rule);
+         m_rule = rule;
       }
    }
@@ -362,5 +361,8 @@
    {
       if( m_instance == this )
+      {
          m_instance = NULL;
+         m_rule.reset();
+      }
    }
 

Index: pointers.h
===================================================================
RCS file: /cvsroot/mahogany/M/include/pointers.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -b -u -2 -r1.6 -r1.7
--- pointers.h  16 Oct 2003 10:29:22 -0000      1.6
+++ pointers.h  16 Oct 2003 12:17:10 -0000      1.7
@@ -23,5 +23,42 @@
    ref counting.
 
-   @todo To be extended...
+
+   Rules:
+   
+   All newly allocated objects are passed to RefCounter constructor,
+   for example:
+   
+      RefCounter<MyClass> ref(new MyClass(x,y));
+   
+   Pointer to "this" or any other raw pointer can be converted to
+   RefCounter using Convert member, for example:
+   
+      RefCounter<MyClass> ref(RefCounter<MyClass>::convert(this));
+
+   RefCounter members must not form cycles. It should be possible to create
+   graph of classes where arrows go from classes containing RefCounter to
+   classes used as template parameter to such RefCounter. Cases, where
+   backreference to parent is needed, can be resolved using WeakRef to
+   parent. Recurrent structures should be modelled using tree container.
+
+
+   Compatibility with legacy raw pointer interfaces:
+   
+   Raw pointers are converted in one of two ways depending on
+   whether they are already IncRef-ed or not:
+   
+      // IncRef in GetProfile
+      ref.attach(x->GetProfile());
+   
+      // IncRef in Convert
+      ref.attach(RefCounter<MyClass>::convert(x->GetProfile()));
+   
+   Local RefCounter can be returned IncRef-ed using Release:
+   
+      return x.release();
+
+   Raw pointer parameters are not IncRef-ed. They are passed using Get:
+   
+      SomeFunc(x.get());
  */
 template <class T>
@@ -43,11 +80,10 @@
 
    /**
-      Default constructor creates an uninitialized pointer.
-
+      Default constructor creates NULL pointer.
     */
-   RefCounter() { m_pointer = NULL; }
+   RefCounter() : m_pointer(NULL) {}
 
    /**
-      Constructor from a rawp ointer.
+      Constructor from a raw pointer.
 
       We take the ownership of the pointer here, i.e. we will call DecRef() on
@@ -56,5 +92,5 @@
       @param pointer the pointer to take ownership of, may be NULL
     */
-   explicit RefCounter(T *pointer) { m_pointer = pointer; }
+   explicit RefCounter(T *pointer) : m_pointer(pointer) {}
 
    /**
@@ -62,6 +98,6 @@
     */
    RefCounter(const RefCounter<T>& copy)
+      : m_pointer(copy.m_pointer)
    {
-      m_pointer = copy.m_pointer;
       RefCounterIncrement(m_pointer);
    }
@@ -74,5 +110,9 @@
     */
    RefCounter<T>& operator=(const RefCounter<T> &copy)
-      { AttachAndIncRef(copy.m_pointer); return *this; }
+   {
+      RefCounterAssign(m_pointer,copy.m_pointer);
+      m_pointer = copy.m_pointer;
+      return *this;
+   }
 
    /**
@@ -84,11 +124,11 @@
 
    /// returns the stored pointer, may be @c NULL
-   T *Get() const { return m_pointer; }
+   T *get() const { return m_pointer; }
 
    /// allows use of this class as a pointer, must be non @c NULL
-   T& operator*() const { return *Get(); }
+   T& operator*() const { return *get(); }
 
    /// allows use of this class as a pointer, must be non @c NULL
-   T *operator->() const { return Get(); }
+   T *operator->() const { return get(); }
 
    /**
@@ -102,8 +142,25 @@
    operator unspecified_bool_type() const // never throws
    {
-       return m_pointer ? &RefCounter<T>::Get : NULL;
+       return m_pointer ? &RefCounter<T>::get : NULL;
    }
 
-   void Attach(T *pointer)
+   /**
+      Reset to @c NULL.
+      
+      It looks better than @c NULL assignment and it saves some cycles.
+    */
+   void reset()
+   {
+      RefCounterDecrement(m_pointer);
+      m_pointer = NULL;
+   }
+   
+   /**
+      Takes ownership of pointer.
+      
+      The caller has already called IncRef() on the pointer if it is not
+      @c NULL.
+    */
+   void attach(T *pointer)
    {
       RefCounterDecrement(m_pointer);
@@ -117,5 +174,5 @@
       it is not @c NULL.
     */
-   T *Release()
+   T *release()
    {
       T *pointer = m_pointer;
@@ -125,16 +182,14 @@
    }
 
-   static RefCounter<T> Convert(T *pointer)
-   {
-      RefCounter<T> result;
-      result.AttachAndIncRef(pointer);
-      return result;
-   }
+   /**
+      Converts raw pointer to smart pointer.
 
-   /// Expects object that has not been IncRef-ed yet, don't use if possible
-   void AttachAndIncRef(T *pointer)
+      The pointer is not manipulated in any way. Returned RefCounter
+      calls IncRef() for its own copy of the pointer.
+    */
+   static RefCounter<T> convert(T *pointer)
    {
-      RefCounterAssign(m_pointer,pointer);
-      m_pointer = pointer;
+      RefCounterIncrement(pointer);
+      return RefCounter<T>(pointer);
    }
 
@@ -144,23 +199,48 @@
 
 
-// Used to resolve cyclic references. RefCounter goes in one direction
-// and WeakRef goes in the opposite direction. WeakRef (seems that it)
-// contains NULL if all RefCounter instances are gone (and the object
-// is deleted). WeakRef is a bit inefficient. That's why you should
-// always convert it to RefCounter when you want to use object it points to.
+/**
+   Weak pointer complementary to RefCounter.
+   
+   WeakRef (seems that it) contains NULL if all RefCounter instances
+   are gone. WeakRef cannot be used directly. It must be converted to
+   RefCounter first.
+   
+   WeakRef is used to resolve cyclic references. See RefCounter for details.
+   
+   WeakRef is intrusively counted weak pointer. This means that MObjectRC
+   holds not only count of RefCounter instances, but also count of WeakRef
+   instances. When all RefCounter instances are destroyed, MObjectRC
+   destructor is called, but memory is not freed. When all WeakRef instances
+   are destroyed, operator delete is called and the object finally
+   disappears. This means that memory occupied by an object is held allocated
+   until all WeakRef instances, that point to it, are destroyed or
+   overwritten. It is not wasteful, because most uses of WeakRef are for
+   parent backlinks and these should never become NULL.
+ */
 template <class T>
 class WeakRef
 {
 public:
+   /// Default constructor creates NULL pointer.
    WeakRef() : m_pointer(NULL) {}
+   
+   /// Copy constructor.
    WeakRef(const WeakRef<T> &copy)
       : m_pointer(copy.m_pointer)
-      { WeakRefIncrement(m_pointer); }
+   {
+      WeakRefIncrement(m_pointer);
+   }
+   
+   /// Destructor
    ~WeakRef() { WeakRefDecrement(m_pointer); }
 
+   /// Conversion from RefCounter to WeakRef.
    WeakRef(RefCounter<T> pointer)
       : m_pointer(pointer.Get())
-      { WeakRefIncrement(m_pointer); }
+   {
+      WeakRefIncrement(m_pointer);
+   }
 
+   /// Assignment operator.
    WeakRef<T>& operator=(const WeakRef<T> &copy)
    {
@@ -170,21 +250,20 @@
    }
 
+   /// Conversion from RefCounter to already constructed WeakRef.
    WeakRef<T>& operator=(RefCounter<T> pointer)
    {
-      m_pointer = pointer.Get();
+      m_pointer = pointer.get();
       WeakRefIncrement(m_pointer);
       return *this;
    }
 
-   bool Expired() const { return WeakRefExpired(m_pointer); }
-   
-   RefCounter<T> Get() const
+   /// Conversion from WeakRef to RefCounter.
+   RefCounter<T> lock() const
    {
-      RefCounter<T> result;
-      result.AttachAndIncRef(Expired() ? NULL : m_pointer);
-      return result;
+      return RefCounter<T>(WeakRefConvert(m_pointer));
    }
    
-   operator RefCounter<T>() const { return Get(); }
+   /// Implicit conversion from WeakRef to RefCounter.
+   operator RefCounter<T>() const { return lock(); }
    
 private:
@@ -225,6 +304,8 @@
 
 
-// Use instead of forward declaration to make RefCounter and WeakRef
-// instantiable without knowledge that T derives from MObjectRC.
+/**
+   Use instead of forward declaration to make RefCounter and WeakRef
+   instantiable without knowledge that T derives from MObjectRC.
+ */
 #define DECLARE_REF_COUNTER(T) \
    class T; \
@@ -235,9 +316,11 @@
    extern void WeakRefDecrement(T *pointer); \
    extern void WeakRefAssign(T *target,T *source); \
-   extern bool WeakRefExpired(const T *pointer);
+   extern T *WeakRefConvert(T *pointer);
 
 
-// If DECLARE_REF_COUNTER is used anywhere, DEFINE_REF_COUNTER must be
-// put it some *.cpp file that #includes ClassName's header.
+/**
+   If DECLARE_REF_COUNTER is used anywhere, DEFINE_REF_COUNTER must be
+   put it some *.cpp file that #includes ClassName's header.
+ */
 #define DEFINE_REF_COUNTER(T) \
    extern void RefCounterIncrement(T *pointer) \
@@ -259,6 +342,6 @@
          static_cast<MObjectRC *>(source)); \
    } \
-   extern bool WeakRefExpired(const T *pointer) \
-      { return WeakRefExpired(static_cast<const MObjectRC *>(pointer)); } \
+   extern T *WeakRefConvert(T *pointer) \
+      { return (T *)WeakRefConvert(static_cast<MObjectRC *>(pointer)); }
 
 



-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to