aboutsummaryrefslogtreecommitdiffstats
path: root/vmime
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vmime/body.hpp2
-rw-r--r--vmime/bodyPart.hpp9
-rw-r--r--vmime/net/folder.hpp4
-rw-r--r--vmime/net/imap/IMAPConnection.hpp6
-rw-r--r--vmime/net/imap/IMAPFolder.hpp8
-rw-r--r--vmime/net/imap/IMAPMessage.hpp6
-rw-r--r--vmime/net/imap/IMAPParser.hpp40
-rw-r--r--vmime/net/maildir/maildirFolder.hpp6
-rw-r--r--vmime/net/maildir/maildirMessage.hpp4
-rw-r--r--vmime/net/maildir/maildirUtils.hpp2
-rw-r--r--vmime/net/pop3/POP3Folder.hpp8
-rw-r--r--vmime/net/pop3/POP3Message.hpp6
-rw-r--r--vmime/object.hpp48
-rw-r--r--vmime/platformDependant.hpp9
-rw-r--r--vmime/utility/smartPtr.hpp392
15 files changed, 257 insertions, 293 deletions
diff --git a/vmime/body.hpp b/vmime/body.hpp
index 90522779..f913e347 100644
--- a/vmime/body.hpp
+++ b/vmime/body.hpp
@@ -229,7 +229,7 @@ public:
private:
- void setParentPart(weak_ref <bodyPart> parent);
+ void setParentPart(ref <bodyPart> parent);
string m_prologText;
diff --git a/vmime/bodyPart.hpp b/vmime/bodyPart.hpp
index c53ad33a..8bb7fdb4 100644
--- a/vmime/bodyPart.hpp
+++ b/vmime/bodyPart.hpp
@@ -75,7 +75,14 @@ public:
*
* @return parent part or NULL if not known
*/
- weak_ref <bodyPart> getParentPart() const;
+ ref <bodyPart> getParentPart();
+
+ /** Return the parent part of this part (const version).
+ *
+ * @return parent part or NULL if not known
+ */
+ ref <const bodyPart> getParentPart() const;
+
ref <component> clone() const;
void copyFrom(const component& other);
diff --git a/vmime/net/folder.hpp b/vmime/net/folder.hpp
index 3dd72ed3..5edba493 100644
--- a/vmime/net/folder.hpp
+++ b/vmime/net/folder.hpp
@@ -306,13 +306,13 @@ public:
*
* @return the store object to which this folder is attached
*/
- virtual weak_ref <const store> getStore() const = 0;
+ virtual ref <const store> getStore() const = 0;
/** Return a reference to the store to which this folder belongs.
*
* @return the store object to which this folder is attached
*/
- virtual weak_ref <store> getStore() = 0;
+ virtual ref <store> getStore() = 0;
/** Fetchable objects.
*/
diff --git a/vmime/net/imap/IMAPConnection.hpp b/vmime/net/imap/IMAPConnection.hpp
index 19c1193a..765937ec 100644
--- a/vmime/net/imap/IMAPConnection.hpp
+++ b/vmime/net/imap/IMAPConnection.hpp
@@ -50,7 +50,7 @@ class IMAPConnection : public object
{
public:
- IMAPConnection(weak_ref <IMAPStore> store, ref <security::authenticator> auth);
+ IMAPConnection(ref <IMAPStore> store, ref <security::authenticator> auth);
~IMAPConnection();
@@ -84,8 +84,8 @@ public:
ref <const IMAPTag> getTag() const;
ref <const IMAPParser> getParser() const;
- weak_ref <const IMAPStore> getStore() const;
- weak_ref <IMAPStore> getStore();
+ ref <const IMAPStore> getStore() const;
+ ref <IMAPStore> getStore();
ref <session> getSession();
diff --git a/vmime/net/imap/IMAPFolder.hpp b/vmime/net/imap/IMAPFolder.hpp
index 089c28dd..5662c349 100644
--- a/vmime/net/imap/IMAPFolder.hpp
+++ b/vmime/net/imap/IMAPFolder.hpp
@@ -55,7 +55,7 @@ private:
friend class vmime::creator; // vmime::create <IMAPFolder>
- IMAPFolder(const folder::path& path, IMAPStore* store, const int type = TYPE_UNDEFINED, const int flags = FLAG_UNDEFINED);
+ IMAPFolder(const folder::path& path, ref <IMAPStore> store, const int type = TYPE_UNDEFINED, const int flags = FLAG_UNDEFINED);
IMAPFolder(const IMAPFolder&) : folder() { }
~IMAPFolder();
@@ -109,8 +109,8 @@ public:
ref <folder> getParent();
- weak_ref <const store> getStore() const;
- weak_ref <store> getStore();
+ ref <const store> getStore() const;
+ ref <store> getStore();
void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress = NULL);
@@ -134,7 +134,7 @@ private:
void copyMessages(const string& set, const folder::path& dest);
- IMAPStore* m_store;
+ weak_ref <IMAPStore> m_store;
ref <IMAPConnection> m_connection;
folder::path m_path;
diff --git a/vmime/net/imap/IMAPMessage.hpp b/vmime/net/imap/IMAPMessage.hpp
index a7f53a1e..7e8c6b07 100644
--- a/vmime/net/imap/IMAPMessage.hpp
+++ b/vmime/net/imap/IMAPMessage.hpp
@@ -49,7 +49,7 @@ private:
friend class IMAPFolder;
friend class vmime::creator; // vmime::create <IMAPMessage>
- IMAPMessage(IMAPFolder* folder, const int num);
+ IMAPMessage(ref <IMAPFolder> folder, const int num);
IMAPMessage(const IMAPMessage&) : message() { }
~IMAPMessage();
@@ -79,7 +79,7 @@ public:
private:
- void fetch(IMAPFolder* folder, const int options);
+ void fetch(ref <IMAPFolder> folder, const int options);
void processFetchResponse(const int options, const IMAPParser::msg_att* msgAtt);
@@ -94,7 +94,7 @@ private:
void onFolderClosed();
- IMAPFolder* m_folder;
+ weak_ref <IMAPFolder> m_folder;
int m_num;
int m_size;
diff --git a/vmime/net/imap/IMAPParser.hpp b/vmime/net/imap/IMAPParser.hpp
index ac6310b2..1a6913dd 100644
--- a/vmime/net/imap/IMAPParser.hpp
+++ b/vmime/net/imap/IMAPParser.hpp
@@ -140,12 +140,12 @@ public:
}
- weak_ref <const IMAPTag> tag() const
+ ref <const IMAPTag> getTag() const
{
- return (m_tag);
+ return m_tag.acquire();
}
- void setSocket(weak_ref <socket> sok)
+ void setSocket(ref <socket> sok)
{
m_socket = sok;
}
@@ -474,7 +474,7 @@ public:
}
}
- if (tagString == string(*(parser.tag())))
+ if (tagString == string(*parser.getTag()))
{
*currentPos = pos;
}
@@ -5072,17 +5072,20 @@ public:
{
string receiveBuffer;
+ ref <timeoutHandler> toh = m_timeoutHandler.acquire();
+ ref <socket> sok = m_socket.acquire();
+
while (receiveBuffer.empty())
{
// Check whether the time-out delay is elapsed
- if (m_timeoutHandler && m_timeoutHandler->isTimeOut())
+ if (toh && toh->isTimeOut())
{
- if (!m_timeoutHandler->handleTimeOut())
+ if (!toh->handleTimeOut())
throw exceptions::operation_timed_out();
}
// We have received data: reset the time-out counter
- m_socket->receive(receiveBuffer);
+ sok->receive(receiveBuffer);
if (receiveBuffer.empty()) // buffer is empty
{
@@ -5091,8 +5094,8 @@ public:
}
// We have received data ...
- if (m_timeoutHandler)
- m_timeoutHandler->resetTimeOut();
+ if (toh)
+ toh->resetTimeOut();
}
m_buffer += receiveBuffer;
@@ -5104,11 +5107,14 @@ public:
string::size_type len = 0;
string receiveBuffer;
+ ref <timeoutHandler> toh = m_timeoutHandler.acquire();
+ ref <socket> sok = m_socket.acquire();
+
if (m_progress)
m_progress->start(count);
- if (m_timeoutHandler)
- m_timeoutHandler->resetTimeOut();
+ if (toh)
+ toh->resetTimeOut();
if (!m_buffer.empty())
{
@@ -5129,16 +5135,16 @@ public:
while (len < count)
{
// Check whether the time-out delay is elapsed
- if (m_timeoutHandler && m_timeoutHandler->isTimeOut())
+ if (toh && toh->isTimeOut())
{
- if (!m_timeoutHandler->handleTimeOut())
+ if (!toh->handleTimeOut())
throw exceptions::operation_timed_out();
- m_timeoutHandler->resetTimeOut();
+ toh->resetTimeOut();
}
// Receive data from the socket
- m_socket->receive(receiveBuffer);
+ sok->receive(receiveBuffer);
if (receiveBuffer.empty()) // buffer is empty
{
@@ -5147,8 +5153,8 @@ public:
}
// We have received data: reset the time-out counter
- if (m_timeoutHandler)
- m_timeoutHandler->resetTimeOut();
+ if (toh)
+ toh->resetTimeOut();
if (len + receiveBuffer.length() > count)
{
diff --git a/vmime/net/maildir/maildirFolder.hpp b/vmime/net/maildir/maildirFolder.hpp
index 3207c807..1e073b47 100644
--- a/vmime/net/maildir/maildirFolder.hpp
+++ b/vmime/net/maildir/maildirFolder.hpp
@@ -56,7 +56,7 @@ private:
friend class vmime::creator; // vmime::create <maildirFolder>
- maildirFolder(const folder::path& path, weak_ref <maildirStore> store);
+ maildirFolder(const folder::path& path, ref <maildirStore> store);
maildirFolder(const maildirFolder&) : folder() { }
~maildirFolder();
@@ -110,8 +110,8 @@ public:
ref <folder> getParent();
- weak_ref <const store> getStore() const;
- weak_ref <store> getStore();
+ ref <const store> getStore() const;
+ ref <store> getStore();
void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress = NULL);
diff --git a/vmime/net/maildir/maildirMessage.hpp b/vmime/net/maildir/maildirMessage.hpp
index b6fccad6..28f668e6 100644
--- a/vmime/net/maildir/maildirMessage.hpp
+++ b/vmime/net/maildir/maildirMessage.hpp
@@ -47,7 +47,7 @@ class maildirMessage : public message
private:
- maildirMessage(weak_ref <maildirFolder> folder, const int num);
+ maildirMessage(ref <maildirFolder> folder, const int num);
maildirMessage(const maildirMessage&) : message() { }
~maildirMessage();
@@ -77,7 +77,7 @@ public:
private:
- void fetch(weak_ref <maildirFolder> folder, const int options);
+ void fetch(ref <maildirFolder> folder, const int options);
void onFolderClosed();
diff --git a/vmime/net/maildir/maildirUtils.hpp b/vmime/net/maildir/maildirUtils.hpp
index a56a0adc..94484bd5 100644
--- a/vmime/net/maildir/maildirUtils.hpp
+++ b/vmime/net/maildir/maildirUtils.hpp
@@ -77,7 +77,7 @@ public:
* @param mode type of path to return (see FolderFSPathMode)
* @return filesystem path for the specified folder
*/
- static const utility::file::path getFolderFSPath(weak_ref <maildirStore> store,
+ static const utility::file::path getFolderFSPath(ref <const maildirStore> store,
const utility::path& folderPath, const FolderFSPathMode mode);
/** Test whether the specified file-system directory corresponds to
diff --git a/vmime/net/pop3/POP3Folder.hpp b/vmime/net/pop3/POP3Folder.hpp
index c0168b13..db4854f2 100644
--- a/vmime/net/pop3/POP3Folder.hpp
+++ b/vmime/net/pop3/POP3Folder.hpp
@@ -54,7 +54,7 @@ private:
friend class POP3Message;
friend class vmime::creator; // vmime::create <POP3Folder>
- POP3Folder(const folder::path& path, POP3Store* store);
+ POP3Folder(const folder::path& path, ref <POP3Store> store);
POP3Folder(const POP3Folder&) : folder() { }
~POP3Folder();
@@ -108,8 +108,8 @@ public:
ref <folder> getParent();
- weak_ref <const store> getStore() const;
- weak_ref <store> getStore();
+ ref <const store> getStore() const;
+ ref <store> getStore();
void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress = NULL);
@@ -129,7 +129,7 @@ private:
void parseMultiListOrUidlResponse(const string& response, std::map <int, string>& result);
- POP3Store* m_store;
+ weak_ref <POP3Store> m_store;
folder::path m_path;
folder::path::component m_name;
diff --git a/vmime/net/pop3/POP3Message.hpp b/vmime/net/pop3/POP3Message.hpp
index e9dfca48..f9e3810c 100644
--- a/vmime/net/pop3/POP3Message.hpp
+++ b/vmime/net/pop3/POP3Message.hpp
@@ -49,7 +49,7 @@ private:
friend class POP3Folder;
friend class vmime::creator; // vmime::create <POP3Message>
- POP3Message(POP3Folder* folder, const int num);
+ POP3Message(ref <POP3Folder> folder, const int num);
POP3Message(const POP3Message&) : message() { }
~POP3Message();
@@ -79,11 +79,11 @@ public:
private:
- void fetch(POP3Folder* folder, const int options);
+ void fetch(ref <POP3Folder> folder, const int options);
void onFolderClosed();
- POP3Folder* m_folder;
+ weak_ref <POP3Folder> m_folder;
int m_num;
uid m_uid;
int m_size;
diff --git a/vmime/object.hpp b/vmime/object.hpp
index b80b6bce..3e2819e2 100644
--- a/vmime/object.hpp
+++ b/vmime/object.hpp
@@ -44,84 +44,52 @@ class object
template <class T> friend class utility::ref;
template <class T> friend class utility::weak_ref;
+ friend class utility::refManager;
+
protected:
object();
object(const object&);
+ object& operator=(const object&);
+
virtual ~object();
#ifndef VMIME_BUILDING_DOC
- /** Add a strong reference to this object. A strong
- * reference ensure the object remains alive.
- */
- void addStrong() const;
-
- /** Add a weak reference to this object. A weak
- * reference helps to resolve circular references.
- */
- void addWeak(utility::weak_ref_base* w) const;
-
- /** Release a strong reference to this object.
- *
- * @return true if the object is not referenced anymore.
- */
- void releaseStrong() const;
-
- /** Release a weak reference to this object.
- *
- * @return true if the object is not referenced anymore.
- */
- void releaseWeak(utility::weak_ref_base* w) const;
-
/** Return a reference to this object.
- * \warning NEVER CALL THIS FROM A CONSTRUCTOR!
*
* @return reference to self
*/
ref <object> thisRef();
/** Return a reference to this object (const version).
- * \warning NEVER CALL THIS FROM A CONSTRUCTOR!
*
* @return reference to self
*/
ref <const object> thisRef() const;
/** Return a weak reference to this object.
- * \warning NEVER CALL THIS FROM A CONSTRUCTOR!
*
* @return weak reference to self
*/
weak_ref <object> thisWeakRef();
/** Return a weak reference to this object (const version).
- * \warning NEVER CALL THIS FROM A CONSTRUCTOR!
*
* @return weak reference to self
*/
weak_ref <const object> thisWeakRef() const;
- /** Return the number of strong refs to this object.
- * For debugging purposes only.
- *
- * @return strong reference count
- */
- const int getStrongRefCount() const;
- /** Return the number of weak refs to this object.
- * For debugging purposes only.
- *
- * @return weak reference count
- */
- const int getWeakRefCount() const;
+ void setRefManager(utility::refManager* mgr);
+ utility::refManager* getRefManager() const;
+
#endif // VMIME_BUILDING_DOC
private:
- mutable int m_strongCount;
- mutable std::vector <utility::weak_ref_base*> m_weakRefs;
+ mutable utility::refManager* m_refMgr;
};
diff --git a/vmime/platformDependant.hpp b/vmime/platformDependant.hpp
index 1818deca..cd8a7ce2 100644
--- a/vmime/platformDependant.hpp
+++ b/vmime/platformDependant.hpp
@@ -56,7 +56,7 @@ public:
* access platform-dependant objects: sockets, date/time, file system, etc.
*/
- class handler
+ class handler : public object
{
public:
@@ -132,11 +132,10 @@ public:
template <class TYPE>
static void setHandler()
{
- delete (sm_handler);
- sm_handler = new TYPE;
+ sm_handler = vmime::create <TYPE>();
}
- static const handler* getHandler()
+ static ref <const handler> getHandler()
{
if (!sm_handler)
throw exceptions::no_platform_dependant_handler();
@@ -146,7 +145,7 @@ public:
private:
- static handler* sm_handler;
+ static ref <handler> sm_handler;
};
diff --git a/vmime/utility/smartPtr.hpp b/vmime/utility/smartPtr.hpp
index 18d443d9..464faf05 100644
--- a/vmime/utility/smartPtr.hpp
+++ b/vmime/utility/smartPtr.hpp
@@ -58,6 +58,89 @@ public:
};
+/** Reference counter for shared pointers.
+ */
+
+class refCounter
+{
+public:
+
+ refCounter(const long initialValue);
+ ~refCounter();
+
+ const long increment();
+ const long decrement();
+ const long compareExchange(const long compare, const long exchangeWith);
+
+ operator long() const;
+
+private:
+
+ long m_value;
+};
+
+
+/** Manage the life cycle of an object.
+ */
+
+class refManager
+{
+public:
+
+ refManager(object* obj);
+ ~refManager();
+
+ /** Add a strong reference to the managed object.
+ */
+ const bool addStrong();
+
+ /** Release a strong reference to the managed object.
+ * If it is the last reference, the object is destroyed.
+ */
+ void releaseStrong();
+
+ /** Add a weak reference to the managed object.
+ */
+ void addWeak();
+
+ /** Release a weak reference to the managed object.
+ * If it is the last weak reference, the manager is destroyed.
+ */
+ void releaseWeak();
+
+ /** Return a raw pointer to the managed object.
+ *
+ * @return pointer to the managed object
+ */
+ object* getObject();
+
+ /** Return the number of strong refs to this object.
+ * For debugging purposes only.
+ *
+ * @return strong reference count
+ */
+ const long getStrongRefCount() const;
+
+ /** Return the number of weak refs to this object.
+ * For debugging purposes only.
+ *
+ * @return weak reference count
+ */
+ const long getWeakRefCount() const;
+
+private:
+
+ void deleteManager();
+ void deleteObject();
+
+
+ object* m_object;
+
+ refCounter m_strongCount;
+ refCounter m_weakCount;
+};
+
+
/** Null reference.
*/
@@ -69,7 +152,11 @@ private:
};
-/** Strong reference (smart pointer).
+template <class T>
+class weak_ref;
+
+
+/** Shared ownership (strong reference to an object).
*/
template <class T>
@@ -85,7 +172,7 @@ public:
ref(const ref& r) : m_ptr(0) { attach(r); }
ref(const null_ref&) : m_ptr(0) { }
- virtual ~ref() { detach(); }
+ virtual ~ref() throw() { detach(); }
// Allow creating NULL ref (NULL casts to anything*)
ref(class null_pointer*) : m_ptr(0) { }
@@ -112,12 +199,10 @@ public:
U* p = dynamic_cast <U*>(const_cast <T*>(m_ptr));
if (!p) return ref <U>();
- p->addStrong();
-
- ref <U> r;
- r.m_ptr = p;
+ if (m_ptr)
+ m_ptr->getRefManager()->addStrong();
- return r;
+ return ref <U>::fromPtrImpl(p);
}
// static_cast
@@ -127,12 +212,10 @@ public:
U* p = static_cast <U*>(const_cast <T*>(m_ptr));
if (!p) return ref <U>();
- p->addStrong();
-
- ref <U> r;
- r.m_ptr = p;
+ if (m_ptr)
+ m_ptr->getRefManager()->addStrong();
- return r;
+ return ref <U>::fromPtrImpl(p);
}
// const_cast
@@ -142,12 +225,10 @@ public:
U* p = const_cast <U*>(m_ptr);
if (!p) return ref <U>();
- m_ptr->addStrong();
-
- ref <U> r;
- r.m_ptr = p;
+ if (m_ptr)
+ m_ptr->getRefManager()->addStrong();
- return r;
+ return ref <U>::fromPtrImpl(p);
}
// Implicit downcast
@@ -155,10 +236,10 @@ public:
operator ref <const U>() const
{
if (m_ptr)
- m_ptr->addStrong();
+ m_ptr->getRefManager()->addStrong();
ref <const U> r;
- r.m_ptr = m_ptr; // will type check at compile-time (prevent from implicit upcast)
+ r.m_ptr = m_ptr; // will type check at compile-time (prevent from implicit upcast)
return r;
}
@@ -167,10 +248,10 @@ public:
operator ref <U>()
{
if (m_ptr)
- m_ptr->addStrong();
+ m_ptr->getRefManager()->addStrong();
ref <U> r;
- r.m_ptr = m_ptr; // will type check at compile-time (prevent from implicit upcast)
+ r.m_ptr = m_ptr; // will type check at compile-time (prevent from implicit upcast)
return r;
}
@@ -181,7 +262,7 @@ public:
U* ptr = other.m_ptr; // will type check at compile-time (prevent from implicit upcast)
if (ptr)
- ptr->addStrong();
+ ptr->getRefManager()->addStrong();
detach();
@@ -194,12 +275,9 @@ public:
operator ref <const T>() const
{
if (m_ptr)
- m_ptr->addStrong();
+ m_ptr->getRefManager()->addStrong();
- ref <const T> r;
- r.m_ptr = m_ptr;
-
- return r;
+ return ref <const T>::fromPtrImpl(m_ptr);
}
// Copy
@@ -230,22 +308,50 @@ public:
*/
static ref <T> fromPtr(T* const ptr)
{
- if (ptr)
- ptr->addStrong();
+ return ref <T>::fromPtrImpl(ptr);
+ }
- ref <T> r;
- r.m_ptr = ptr;
+ static ref <const T> fromPtrConst(const T* const ptr)
+ {
+ return ref <const T>::fromPtrImpl(ptr);
+ }
- return r;
+ static ref <T> fromWeak(weak_ref <T> wr)
+ {
+ refManager* mgr = wr.getManager();
+
+ if (mgr && mgr->addStrong())
+ return ref <T>::fromPtrImpl(dynamic_cast <T*>(mgr->getObject()));
+ else
+ return ref <T>();
+ }
+
+ static ref <const T> fromWeakConst(weak_ref <const T> wr)
+ {
+ refManager* mgr = wr.getManager();
+
+ if (mgr && mgr->addStrong())
+ return ref <const T>::fromPtrImpl(dynamic_cast <const T*>(mgr->getObject()));
+ else
+ return ref <const T>();
}
protected:
+ template <class U>
+ static ref <U> fromPtrImpl(U* ptr)
+ {
+ ref <U> r;
+ r.m_ptr = ptr;
+
+ return r;
+ }
+
void detach()
{
if (m_ptr)
{
- m_ptr->releaseStrong();
+ m_ptr->getRefManager()->releaseStrong();
m_ptr = 0;
}
}
@@ -254,7 +360,7 @@ protected:
void attach(U* const ptr)
{
if (ptr)
- ptr->addStrong();
+ ptr->getRefManager()->addStrong();
detach();
@@ -265,7 +371,7 @@ protected:
void attach(const ref <U>& r)
{
if (r.m_ptr)
- r.m_ptr->addStrong();
+ r.m_ptr->getRefManager()->addStrong();
detach();
@@ -329,169 +435,64 @@ bool operator!=(const null_ref&, const ref <T>& r)
-/** Base class for weak references.
- */
-
-class weak_ref_base
-{
- friend class vmime::object; // calls 'notifyObjectDestroyed'
-
-protected:
-
- weak_ref_base() { }
- weak_ref_base(const weak_ref_base&) { }
- virtual ~weak_ref_base() { }
-
-
- virtual void notifyObjectDestroyed() = 0;
-};
-
-
/** Weak reference.
* Avoid circular references.
*/
template <class T>
-class weak_ref : public weak_ref_base
+class weak_ref
{
public:
template <class U> friend class weak_ref;
- weak_ref() : m_ptr(0) { }
- weak_ref(const ref <T>& r) : m_ptr(0) { attach(r); }
- weak_ref(const weak_ref& r) : weak_ref_base(), m_ptr(0) { attach(r); }
- weak_ref(const null_ref&) : m_ptr(0) { }
- weak_ref(T* const p) : m_ptr(0) { attach(p); }
+ weak_ref() : m_mgr(0) { }
+ weak_ref(const ref <T>& r) : m_mgr(0) { attach(r); }
+ weak_ref(const weak_ref& r) : m_mgr(0) { attach(r); }
+ weak_ref(const null_ref&) : m_mgr(0) { }
+ weak_ref(class null_pointer*) : m_mgr(0) { }
~weak_ref() { detach(); }
-
- // Access to wrapped object
-// operator const T*() const { return m_ptr; }
- operator const void*() const { return m_ptr; }
-
- T& operator *() { return *m_ptr; }
- const T& operator *() const { return *m_ptr; }
-
- T* operator ->() { return m_ptr; }
- const T* operator ->() const { return m_ptr; }
-
- const T* const get() const { return m_ptr; }
- T* const get() { return m_ptr; }
-
- const bool operator !() const { return m_ptr == NULL; }
-
-
- // dynamic_cast
- template <class U>
- weak_ref <U> dynamicCast() const
- {
- U* p = dynamic_cast <U*>(const_cast <T*>(m_ptr));
- if (!p) return weak_ref <U>();
-
- weak_ref <U> r;
-
- p->addWeak(&r);
-
- r.m_ptr = p;
-
- return r;
- }
-
- // static_cast
- template <class U>
- weak_ref <U> staticCast() const
- {
- U* p = static_cast <U*>(const_cast <T*>(m_ptr));
- if (!p) return weak_ref <U>();
-
- weak_ref <U> r;
-
- p->addWeak(&r);
-
- r.m_ptr = p;
-
- return r;
- }
-
- // const_cast
- template <class U>
- weak_ref <U> constCast() const
- {
- U* p = const_cast <U*>(m_ptr);
- if (!p) return weak_ref <U>();
-
- weak_ref <U> r;
-
- p->addWeak(&r);
-
- r.m_ptr = p;
-
- return r;
- }
-
- // Implicit downcast
- template <class U>
- operator weak_ref <const U>()
- {
- weak_ref <const U> r;
-
- if (m_ptr)
- m_ptr->addWeak(&r);
-
- r.m_ptr = m_ptr; // will type check at compile-time (prevent from implicit upcast)
-
- return r;
- }
-
- // Implicit downcast
- template <class U>
- operator weak_ref <U>()
+ /** Return the manager for the object.
+ *
+ * @return pointer to the object which manages the object
+ * or NULL if the weak reference points to nothing
+ */
+ refManager* getManager()
{
- weak_ref <U> r;
-
- if (m_ptr)
- m_ptr->addWeak(&r);
-
- r.m_ptr = m_ptr; // will type check at compile-time (prevent from implicit upcast)
-
- return r;
+ return m_mgr;
}
- template <class U>
- weak_ref <T>& operator=(const weak_ref <U>& other)
+ /** Try to acquire a strong reference to the object (const version).
+ *
+ * @return strong reference or null reference if the
+ * object is not available anymore
+ */
+ ref <const T> acquire() const
{
- U* ptr = other.m_ptr; // will type check at compile-time (prevent from implicit upcast)
-
- if (ptr)
- ptr->addWeak(this);
-
- detach();
-
- m_ptr = ptr;
-
- return *this;
+ return ref <const T>::fromWeakConst(*this);
}
- ref <T> toStrong()
+ /** Try to acquire a strong reference to the object.
+ *
+ * @return strong reference or null reference if the
+ * object is not available anymore
+ */
+ ref <T> acquire()
{
- if (m_ptr == NULL)
- return ref <T>();
-
- return ref <T>::fromPtr(m_ptr);
+ return ref <T>::fromWeak(*this);
}
// Implicit non-const => const conversion
operator weak_ref <const T>() const
{
- weak_ref <const T> r;
-
- if (m_ptr)
- m_ptr->addWeak(&r);
+ if (m_mgr)
+ m_mgr->addWeak();
- r.m_ptr = m_ptr;
+ weak_ref <const T> r;
+ r.m_mgr = m_mgr;
return r;
}
@@ -499,12 +500,11 @@ public:
template <class U>
operator weak_ref <const U>() const
{
- weak_ref <const U> r;
-
- if (m_ptr)
- m_ptr->addWeak(&r);
+ if (m_mgr)
+ m_mgr->addWeak();
- r.m_ptr = m_ptr;
+ weak_ref <const U> r;
+ r.m_mgr = m_mgr;
return r;
}
@@ -516,58 +516,42 @@ public:
return *this;
}
- // NULL-pointer comparison
- bool operator==(const class null_pointer*) const { return m_ptr == 0; }
- bool operator!=(const class null_pointer*) const { return m_ptr != 0; }
-
private:
- void notifyObjectDestroyed()
- {
- m_ptr = 0;
- }
-
void detach()
{
- if (m_ptr)
+ if (m_mgr)
{
- m_ptr->releaseWeak(this);
- m_ptr = 0;
+ m_mgr->releaseWeak();
+ m_mgr = 0;
}
}
void attach(const ref <T>& r)
{
if (r.m_ptr)
- r.m_ptr->addWeak(this);
+ r.m_ptr->getRefManager()->addWeak();
detach();
- m_ptr = r.m_ptr;
- }
-
- void attach(const weak_ref& r)
- {
if (r.m_ptr)
- r.m_ptr->addWeak(this);
-
- detach();
-
- m_ptr = r.m_ptr;
+ m_mgr = r.m_ptr->getRefManager();
+ else
+ m_mgr = 0;
}
- void attach(T* const p)
+ void attach(const weak_ref& r)
{
- if (p)
- p->addWeak(this);
+ if (r.m_mgr)
+ r.m_mgr->addWeak();
detach();
- m_ptr = p;
+ m_mgr = r.m_mgr;
}
- T* m_ptr;
+ refManager* m_mgr;
};