diff options
Diffstat (limited to '')
-rw-r--r-- | vmime/body.hpp | 2 | ||||
-rw-r--r-- | vmime/bodyPart.hpp | 9 | ||||
-rw-r--r-- | vmime/net/folder.hpp | 4 | ||||
-rw-r--r-- | vmime/net/imap/IMAPConnection.hpp | 6 | ||||
-rw-r--r-- | vmime/net/imap/IMAPFolder.hpp | 8 | ||||
-rw-r--r-- | vmime/net/imap/IMAPMessage.hpp | 6 | ||||
-rw-r--r-- | vmime/net/imap/IMAPParser.hpp | 40 | ||||
-rw-r--r-- | vmime/net/maildir/maildirFolder.hpp | 6 | ||||
-rw-r--r-- | vmime/net/maildir/maildirMessage.hpp | 4 | ||||
-rw-r--r-- | vmime/net/maildir/maildirUtils.hpp | 2 | ||||
-rw-r--r-- | vmime/net/pop3/POP3Folder.hpp | 8 | ||||
-rw-r--r-- | vmime/net/pop3/POP3Message.hpp | 6 | ||||
-rw-r--r-- | vmime/object.hpp | 48 | ||||
-rw-r--r-- | vmime/platformDependant.hpp | 9 | ||||
-rw-r--r-- | vmime/utility/smartPtr.hpp | 392 |
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; }; |