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> ©)
- { 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> ©)
: 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> ©)
{
@@ -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