diff options
Diffstat (limited to 'ACE/contrib/utility/Utility/ReferenceCounting')
12 files changed, 1073 insertions, 0 deletions
diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/DefaultImpl.hpp b/ACE/contrib/utility/Utility/ReferenceCounting/DefaultImpl.hpp new file mode 100644 index 00000000000..43160c09a03 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/DefaultImpl.hpp @@ -0,0 +1,96 @@ +// file : Utility/ReferenceCounting/DefaultImpl.hpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +#ifndef UTILITY_REFERENCE_COUNTING_DEFAULT_IMPL_HPP +#define UTILITY_REFERENCE_COUNTING_DEFAULT_IMPL_HPP + +#include "Utility/ExH/Compound.hpp" +#include "Utility/ExH/Logic/DescriptiveException.hpp" + +#include "Utility/Synch/Policy/Null.hpp" + +#include "Utility/ReferenceCounting/Interface.hpp" + +namespace Utility +{ + namespace ReferenceCounting + { + // Default reference counter implementation with parameterised + // synchronization policy. It is assumed that none of the SynchPolicy + // types throw any logic exceptions. If in fact they do then these + // exceptions won't be handled and will be automatically converted + // to system exceptions. + + template <typename SynchPolicy = Utility::Synch::Policy::Null> + class DefaultImpl : public virtual Interface + { + public: + class InconsistentState_ {}; + typedef + ExH::Compound<InconsistentState_, Exception> + InconsistentState; + + public: + DefaultImpl () throw (SystemException); + + virtual + ~DefaultImpl () throw (); + + public: + virtual void + add_ref () const throw (Exception, SystemException); + + virtual void + remove_ref () const throw (); + + virtual count_t + refcount_value () const throw (Exception, SystemException); + + protected: + virtual void + add_ref_i () const throw (Exception, SystemException); + + virtual bool + remove_ref_i () const throw (Exception, SystemException); + + virtual count_t + refcount_value_i () const throw (Exception, SystemException); + + typename SynchPolicy::Mutex& + lock_i () const throw (); + + protected: + typedef + typename SynchPolicy::Mutex + Mutex_; + + typedef + typename SynchPolicy::ReadGuard + ReadGuard_; + + typedef + typename SynchPolicy::WriteGuard + WriteGuard_; + + protected: + mutable count_t ref_count_; + + private: + mutable Mutex_ lock_; + + private: + // Copy semanic is not supported. + DefaultImpl (DefaultImpl const&) throw (); + DefaultImpl& + operator= (DefaultImpl const&) throw (); + }; + } +} + +#include "Utility/ReferenceCounting/DefaultImpl.ipp" + +#endif // UTILITY_REFERENCE_COUNTING_DEFAULT_IMPL_HPP + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/DefaultImpl.ipp b/ACE/contrib/utility/Utility/ReferenceCounting/DefaultImpl.ipp new file mode 100644 index 00000000000..bac28c77ea2 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/DefaultImpl.ipp @@ -0,0 +1,105 @@ +// file : Utility/ReferenceCounting/DefaultImpl.ipp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +namespace Utility +{ + namespace ReferenceCounting + { + // c-tor & d-tor + + template <typename SynchPolicy> + DefaultImpl<SynchPolicy>:: + DefaultImpl () throw (Interface::SystemException) + : ref_count_ (1), + lock_ () + { + } + + template <typename SynchPolicy> + DefaultImpl<SynchPolicy>:: + ~DefaultImpl () throw () + { + } + + // add_ref, remove_ref and refcount_value member functions + + template <typename SynchPolicy> + void DefaultImpl<SynchPolicy>:: + add_ref () const throw (Exception, SystemException) + { + WriteGuard_ guard (lock_); + add_ref_i (); + } + + template <typename SynchPolicy> + void DefaultImpl<SynchPolicy>:: + remove_ref () const throw () + { + bool destroy (false); + try + { + WriteGuard_ guard (lock_); + destroy = remove_ref_i (); + } + catch (...) + { + // there is nothing we can do + } + + if (destroy) delete this; + } + + template <typename SynchPolicy> + Interface::count_t DefaultImpl<SynchPolicy>:: + refcount_value () const throw (Exception, SystemException) + { + ReadGuard_ guard (lock_); + return refcount_value_i (); + } + + // add_ref_i, remove_ref_i and refcount_value_i member functions + + template <typename SynchPolicy> + void DefaultImpl<SynchPolicy>:: + add_ref_i () const throw (Exception, SystemException) + { + ref_count_++; + } + + template <typename SynchPolicy> + bool DefaultImpl<SynchPolicy>:: + remove_ref_i () const throw (Exception, SystemException) + { + bool destroy (false); + if (ref_count_ > 0) + { + if (--ref_count_ == 0) destroy = true; + } + else + { + throw InconsistentState ( + "Utility::ReferenceCounting::DefaultImpl::_remove_ref_i: " + "reference counter is zero."); + } + return destroy; + + } + + template <typename SynchPolicy> + Interface::count_t DefaultImpl<SynchPolicy>:: + refcount_value_i () const throw (Exception, SystemException) + { + return ref_count_; + } + + template <typename SynchPolicy> + typename SynchPolicy::Mutex& DefaultImpl<SynchPolicy>:: + lock_i() const throw () + { + return lock_; + } + } +} +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/ExternalLockImpl.hpp b/ACE/contrib/utility/Utility/ReferenceCounting/ExternalLockImpl.hpp new file mode 100644 index 00000000000..20346e859b3 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/ExternalLockImpl.hpp @@ -0,0 +1,60 @@ +// file : Utility/ReferenceCounting/ExternalLockImpl.hpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +#ifndef UTILITY_REFERENCE_COUNTING_EXTERNAL_LOCK_IMPL_HPP +#define UTILITY_REFERENCE_COUNTING_EXTERNAL_LOCK_IMPL_HPP + +namespace Utility +{ + namespace ReferenceCounting + { + + /* + + Not ported yet. + + class ExternalLockRefCounter : public virtual Util::RefCountBase + { + public: + ExternalLockRefCounter (ACE_Lock* lock = 0); + virtual ~ExternalLockRefCounter (); + + void init (ACE_Lock* lock); + + public: + + virtual void _add_ref (); + virtual void _remove_ref (); + virtual unsigned long _refcount_value (); + + protected: + + virtual void _add_ref_i (); + virtual bool _remove_ref_i (); + virtual unsigned long _refcount_value_i (); + + ACE_Lock* lock_i (); + + private: + + typedef ACE_Guard <ACE_Lock> Guard_; + + ACE_Lock* lock_; + unsigned long ref_count_; + + private: + ExternalLockRefCounter (const ExternalLockRefCounter& ); + void operator= (const ExternalLockRefCounter& ); + }; + + */ + } +} + +#include "Utility/ReferenceCounting/ExternalLockImpl.ipp" + +#endif // UTILITY_REFERENCE_COUNTING_EXTERNAL_LOCK_IMPL_HPP + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/ExternalLockImpl.ipp b/ACE/contrib/utility/Utility/ReferenceCounting/ExternalLockImpl.ipp new file mode 100644 index 00000000000..7552d411f27 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/ExternalLockImpl.ipp @@ -0,0 +1,122 @@ +// file : Utility/ReferenceCounting/ExternalLockImpl.ipp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +namespace Utility +{ + namespace ReferenceCounting + { + /* + inline + ExternalLockRefCounter::ExternalLockRefCounter (ACE_Lock* lock) + : lock_ (lock), + ref_count_ (1) + { + } + + inline + void + ExternalLockRefCounter::init (ACE_Lock* lock) + { + lock_ = lock; + } + + inline + ExternalLockRefCounter::~ExternalLockRefCounter () + { + } + + inline + ACE_Lock* + ExternalLockRefCounter::lock_i () + { + return lock_; + } + + inline + void + ExternalLockRefCounter::_add_ref () + { + if (lock_) + { + Guard_ guard (*lock_); + _add_ref_i (); + } + else + { + _add_ref_i (); + } + } + + inline + void + ExternalLockRefCounter::_remove_ref () + { + bool destroy = false; + { + if (lock_) + { + Guard_ guard (*lock_); + destroy = _remove_ref_i (); + } + else + { + destroy = _remove_ref_i (); + } + } + if (destroy) delete this; + } + + inline + unsigned long + ExternalLockRefCounter::_refcount_value () + { + if (lock_) + { + Guard_ guard (*lock_); + return _refcount_value_i (); + } + else + { + return _refcount_value_i (); + } + } + + inline + void + ExternalLockRefCounter::_add_ref_i () + { + ref_count_++; + } + + inline + bool + ExternalLockRefCounter::_remove_ref_i () + { + bool destroy = false; + if (ref_count_ > 0) + { + if (--ref_count_ == 0) destroy = true; + } + else + { + ACE_ERROR ((LM_ERROR, + "ExternalLockRefCounter::_remove_ref() " + " _remove_ref() called while ref_coundt == 0\n" + )); + } + return destroy; + } + + inline + unsigned long + ExternalLockRefCounter::_refcount_value_i () + { + return ref_count_; + } + */ + } +} + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/Interface.hpp b/ACE/contrib/utility/Utility/ReferenceCounting/Interface.hpp new file mode 100644 index 00000000000..9231860b84a --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/Interface.hpp @@ -0,0 +1,84 @@ +// file : Utility/ReferenceCounting/Interface.hpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +#ifndef UTILITY_REFERENCE_COUNTING_INTERFACE_HPP +#define UTILITY_REFERENCE_COUNTING_INTERFACE_HPP + +#include "Utility/ExH/Compound.hpp" +#include "Utility/ExH/System/Exception.hpp" +#include "Utility/ExH/Logic/Exception.hpp" +#include "Utility/ExH/Logic/DescriptiveException.hpp" + +namespace Utility +{ + namespace ReferenceCounting + { + // Interface to a reference-countable object. Note that _remove_ref () + // member function has a no-throw semantic. Even though it can lead to + // a diagnostic loss it was made no-throw because it has a destructor + // semantic. + + class Interface + { + public: + typedef + unsigned long + count_t; + + typedef + ExH::System::Exception + SystemException; + + class Exception_ {}; + typedef + ExH::Compound<Exception_, ExH::Logic::DescriptiveException> + Exception; + + public: + virtual void + add_ref () const throw (Exception, SystemException) = 0; + + virtual void + remove_ref () const throw () = 0; + + virtual count_t + refcount_value () const throw (Exception, SystemException) = 0; + + protected: + Interface () throw (); + + virtual + ~Interface () throw (); + + protected: + virtual void + add_ref_i () const throw (Exception, SystemException) = 0; + + virtual bool + remove_ref_i () const throw (Exception, SystemException) = 0; + + virtual count_t + refcount_value_i () const throw (Exception, SystemException) = 0; + + private: + // Copy semanic is not supported. + Interface (Interface const&) throw (); + Interface& + operator= (Interface const&) throw (); + }; + + template <typename Type> + Type* + add_ref (Type* ptr) + throw (Interface::Exception, Interface::SystemException); + } +} + +#include "Utility/ReferenceCounting/Interface.tpp" +#include "Utility/ReferenceCounting/Interface.ipp" + +#endif // UTILITY_REFERENCE_COUNTING_INTERFACE_HPP + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/Interface.ipp b/ACE/contrib/utility/Utility/ReferenceCounting/Interface.ipp new file mode 100644 index 00000000000..f901db4b248 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/Interface.ipp @@ -0,0 +1,22 @@ +// file : Utility/ReferenceCounting/Interface.ipp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +namespace Utility +{ + namespace ReferenceCounting + { + inline Interface:: + ~Interface () throw () + { + } + + inline Interface:: + Interface () throw () + { + } + } +} + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/Interface.tpp b/ACE/contrib/utility/Utility/ReferenceCounting/Interface.tpp new file mode 100644 index 00000000000..6a6a1d2d263 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/Interface.tpp @@ -0,0 +1,20 @@ +// file : Utility/ReferenceCounting/Interface.tpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +namespace Utility +{ + namespace ReferenceCounting + { + template <typename Type> + inline Type* + add_ref (Type* ptr) + throw (Interface::Exception, Interface::SystemException) + { + if (ptr != 0) ptr->add_ref (); + return ptr; + } + } +} +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/ReferenceCounting.hpp b/ACE/contrib/utility/Utility/ReferenceCounting/ReferenceCounting.hpp new file mode 100644 index 00000000000..a20fe0d888c --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/ReferenceCounting.hpp @@ -0,0 +1,16 @@ +// file : Utility/ReferenceCounting/ReferenceCounting.hpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +#ifndef UTILITY_REFERENCE_COUNTING_REFERENCE_COUNTING_HPP +#define UTILITY_REFERENCE_COUNTING_REFERENCE_COUNTING_HPP + +#include "Utility/ReferenceCounting/Interface.hpp" +#include "Utility/ReferenceCounting/DefaultImpl.hpp" +#include "Utility/ReferenceCounting/SmartPtr.hpp" +#include "Utility/ReferenceCounting/StrictPtr.hpp" + +#endif // UTILITY_REFERENCE_COUNTING_REFERENCE_COUNTING_HPP + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/SmartPtr.hpp b/ACE/contrib/utility/Utility/ReferenceCounting/SmartPtr.hpp new file mode 100644 index 00000000000..682f0678ee1 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/SmartPtr.hpp @@ -0,0 +1,103 @@ +// file : Utility/ReferenceCounting/SmartPtr.hpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +#ifndef UTILITY_REFERENCE_COUNTING_SMART_PTR_HPP +#define UTILITY_REFERENCE_COUNTING_SMART_PTR_HPP + +#include "Utility/ExH/Compound.hpp" +#include "Utility/ExH/Logic/DescriptiveException.hpp" + +#include "Utility/ReferenceCounting/Interface.hpp" + +namespace Utility +{ + namespace ReferenceCounting + { + template <typename T> + class SmartPtr + { + public: + typedef + T + Type; + + class NotInitialized_ {}; + typedef + ExH::Compound<NotInitialized_, ExH::Logic::DescriptiveException> + NotInitialized; + + public: + // c-tor's + + SmartPtr () throw (); + SmartPtr (Type* ptr) throw (); + SmartPtr (SmartPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + template <typename Other> + SmartPtr (SmartPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + // d-tor + + ~SmartPtr () throw (); + + // assignment & copy-assignment operators + + SmartPtr<Type>& + operator= (Type* ptr) throw (); + + SmartPtr<Type>& + operator= (SmartPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + template <typename Other> + SmartPtr<Type>& + operator= (SmartPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + //conversions + + operator Type* () const throw (); + + // accessors + + Type* + operator-> () const throw (NotInitialized); + + Type* + in () const throw (); + + Type* + retn() throw (); + + private: + Type* ptr_; + }; + + // Specialization of add_ref function for SmartPtr<T> + template <typename T> + T* + add_ref (SmartPtr<T> const& ptr) + throw (Interface::Exception, Interface::SystemException); + + + // Dynamic type conversion function for SmartPtr's + template <typename D, typename S> + D* + smart_cast (SmartPtr<S> const& s) + throw (Interface::Exception, Interface::SystemException); + + // Acquisition function + template <typename T> + SmartPtr<T> + acquire (T* ptr) throw (Interface::Exception, Interface::SystemException); + } +} + +#include "Utility/ReferenceCounting/SmartPtr.tpp" + +#endif // UTILITY_REFERENCE_COUNTING_SMART_PTR_HPP +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/SmartPtr.tpp b/ACE/contrib/utility/Utility/ReferenceCounting/SmartPtr.tpp new file mode 100644 index 00000000000..6596c67f1b1 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/SmartPtr.tpp @@ -0,0 +1,170 @@ +// file : Utility/ReferenceCounting/SmartPtr.tpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +namespace Utility +{ + namespace ReferenceCounting + { + // c-tor's & d-tor + + template <typename T> + SmartPtr<T>:: + SmartPtr () throw () + : ptr_ (0) + { + } + + template <typename T> + SmartPtr<T>:: + SmartPtr (Type* ptr) throw () + : ptr_ (ptr) + { + } + + template <typename T> + SmartPtr<T>:: + SmartPtr (SmartPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + : ptr_ (add_ref (s_ptr.in ())) + { + } + + template <typename T> + template <typename Other> + SmartPtr<T>:: + SmartPtr (SmartPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + : ptr_ (add_ref (s_ptr.in ())) + { + } + + + template <typename T> + SmartPtr<T>:: + ~SmartPtr () throw () + { + // This is an additional catch-all layer to protect from + // non-conformant Type. + try + { + if (ptr_ != 0) ptr_->remove_ref (); + } + catch (...) + { + } + } + + // operator= + + template <typename T> + SmartPtr<T>& SmartPtr<T>:: + operator= (Type* ptr) throw () + { + if (ptr_ != 0) ptr_->remove_ref (); + ptr_ = ptr; + return *this; + } + + + template <typename T> + SmartPtr<T>& SmartPtr<T>:: + operator= (SmartPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + { + Type* old_ptr (ptr_); + Type* new_ptr (add_ref (s_ptr.in ())); // this can throw + if (old_ptr != 0) old_ptr->remove_ref (); + + ptr_ = new_ptr; // commit + + return *this; + } + + + template <typename T> + template <typename Other> + SmartPtr<T>& SmartPtr<T>:: + operator= (SmartPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + { + Type* old_ptr (ptr_); + Other* new_ptr (add_ref (s_ptr.in ())); // this can throw + if (old_ptr != 0) old_ptr->remove_ref (); + + ptr_ = new_ptr; // commit + + return *this; + } + + // conversions + + template <typename T> + SmartPtr<T>:: + operator T* () const throw () + { + return ptr_; + } + + + // accessors + + template <typename T> + T* SmartPtr<T>:: + operator-> () const throw (NotInitialized) + { + if (ptr_ == 0) + { + throw NotInitialized( + "Utility::ReferenceCounting::SmartPtr::operator-> : " + "unable to dereference NULL pointer."); + } + return ptr_; + } + + template <typename T> + T* SmartPtr<T>:: + in () const throw () + { + return ptr_; + } + + template <typename T> + T* SmartPtr<T>:: + retn() throw () + { + Type* ret (ptr_); + ptr_ = 0; + return ret; + } + + // Specialization of add_ref function for SmartPtr<T> + template <typename T> + T* + add_ref (SmartPtr<T> const& ptr) + throw (Interface::Exception, Interface::SystemException) + { + // delegate to generic implementation + return add_ref (ptr.in ()); + } + + // Dynamic type conversion function for SmartPtr's + template <typename D, typename S> + D* + smart_cast (SmartPtr<S> const& s) + throw (Interface::Exception, Interface::SystemException) + { + return add_ref (dynamic_cast<D*>(s.in ())); + } + + // Acquisition function + template <typename T> + SmartPtr<T> + acquire (T* ptr) throw (Interface::Exception, Interface::SystemException) + { + return SmartPtr<T> (ptr); + } + } +} +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/StrictPtr.hpp b/ACE/contrib/utility/Utility/ReferenceCounting/StrictPtr.hpp new file mode 100644 index 00000000000..c88c90d5e50 --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/StrictPtr.hpp @@ -0,0 +1,108 @@ +// file : Utility/ReferenceCounting/StrictPtr.hpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +#ifndef UTILITY_REFERENCE_COUNTING_STRICT_PTR_HPP +#define UTILITY_REFERENCE_COUNTING_STRICT_PTR_HPP + +#include "Utility/ExH/Compound.hpp" +#include "Utility/ExH/Logic/DescriptiveException.hpp" + +#include "Utility/ReferenceCounting/Interface.hpp" + +namespace Utility +{ + namespace ReferenceCounting + { + template <typename T> + class StrictPtr + { + public: + typedef + T + Type; + + class NotInitialized_ {}; + typedef + ExH::Compound<NotInitialized_, ExH::Logic::DescriptiveException> + NotInitialized; + + public: + // c-tor's + + StrictPtr () throw (); + + explicit + StrictPtr (Type* ptr) throw (); + + StrictPtr (StrictPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + template <typename Other> + StrictPtr (StrictPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + // d-tor + + ~StrictPtr () throw (); + + // assignment & copy-assignment operators + + StrictPtr<Type>& + operator= (Type* ptr) throw (); + + StrictPtr<Type>& + operator= (StrictPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + template <typename Other> + StrictPtr<Type>& + operator= (StrictPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException); + + // conversions + + // Note: implicit conversion (operator Type* ()) is not supported. + + // comparison + + bool + operator== (Type* other) const throw (); + + bool + operator!= (Type* other) const throw (); + + // accessors + + Type* + operator-> () const throw (NotInitialized); + + Type* + in () const throw (); + + Type* + retn() throw (); + + private: + Type* ptr_; + }; + + // Specialization of add_ref function for StrictPtr<T> + template <typename T> + T* + add_ref (StrictPtr<T> const& ptr) + throw (Interface::Exception, Interface::SystemException); + + // Dynamic type conversion function for StrictPtr's + template <typename D, typename S> + StrictPtr<D> + strict_cast (StrictPtr<S> const& s) + throw (Interface::Exception, Interface::SystemException); + } +} + +#include "Utility/ReferenceCounting/StrictPtr.tpp" + +#endif // UTILITY_REFERENCE_COUNTING_STRICT_PTR_HPP + +//$Id$ diff --git a/ACE/contrib/utility/Utility/ReferenceCounting/StrictPtr.tpp b/ACE/contrib/utility/Utility/ReferenceCounting/StrictPtr.tpp new file mode 100644 index 00000000000..6a30188119c --- /dev/null +++ b/ACE/contrib/utility/Utility/ReferenceCounting/StrictPtr.tpp @@ -0,0 +1,167 @@ +// file : Utility/ReferenceCounting/StrictPtr.tpp +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2002-2003 Boris Kolpackov +// license : http://kolpackov.net/license.html + +namespace Utility +{ + namespace ReferenceCounting + { + // c-tor's & d-tor + + template <typename T> + StrictPtr<T>:: + StrictPtr () throw () + : ptr_ (0) + { + } + + template <typename T> + StrictPtr<T>:: + StrictPtr (Type* ptr) throw () + : ptr_ (ptr) + { + } + + template <typename T> + StrictPtr<T>:: + StrictPtr (StrictPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + : ptr_ (add_ref (s_ptr.in ())) + { + } + + template <typename T> + template <typename Other> + StrictPtr<T>:: + StrictPtr (StrictPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + : ptr_ (add_ref (s_ptr.in ())) + { + } + + + template <typename T> + StrictPtr<T>:: + ~StrictPtr () throw () + { + // This is an additional catch-all layer to protect from + // non-conformant Type. + try + { + if (ptr_ != 0) ptr_->remove_ref (); + } + catch (...) + { + } + } + + // operator= + + template <typename T> + StrictPtr<T>& + StrictPtr<T>::operator= (Type* ptr) throw () + { + if (ptr_ != 0) ptr_->remove_ref (); + ptr_ = ptr; + return *this; + } + + template <typename T> + StrictPtr<T>& StrictPtr<T>:: + operator= (StrictPtr<Type> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + { + Type* old_ptr (ptr_); + Type* new_ptr (add_ref (s_ptr.in ())); // this can throw + if (old_ptr != 0) old_ptr->remove_ref (); + + ptr_ = new_ptr; // commit + + return *this; + } + + + template <typename T> + template <typename Other> + StrictPtr<T>& StrictPtr<T>:: + operator= (StrictPtr<Other> const& s_ptr) + throw (Interface::Exception, Interface::SystemException) + { + Type* old_ptr (ptr_); + Other* new_ptr (add_ref (s_ptr.in ())); // this can throw + if (old_ptr != 0) old_ptr->remove_ref (); + + ptr_ = new_ptr; // commit + + return *this; + } + + // comparison + + template <typename T> + bool StrictPtr<T>:: + operator== (Type* other) const throw () + { + return ptr_ == other; + } + + template <typename T> + bool StrictPtr<T>:: + operator!= (Type* other) const throw () + { + return ptr_ != other; + } + + // accessors + + template <typename T> + T* StrictPtr<T>:: + operator-> () const throw (NotInitialized) + { + if (ptr_ == 0) + { + throw NotInitialized( + "Utility::ReferenceCounting::StrictPtr::operator-> : " + "unable to dereference NULL pointer."); + } + return ptr_; + } + + template <typename T> + T* StrictPtr<T>:: + in () const throw () + { + return ptr_; + } + + template <typename T> + T* StrictPtr<T>:: + retn() throw () + { + Type* ret (ptr_); + ptr_ = 0; + return ret; + } + + // Specialization of add_ref function for StrictPtr<T> + template <typename T> + T* + add_ref (StrictPtr<T> const& ptr) + throw (Interface::Exception, Interface::SystemException) + { + // delegate to generic implementation + return add_ref (ptr.in ()); + } + + // Dynamic type conversion function for StrictPtr's + template <typename D, typename S> + StrictPtr<D> + strict_cast (StrictPtr<S> const& s) + throw (Interface::Exception, Interface::SystemException) + { + return StrictPtr<D>(add_ref (dynamic_cast<D*>(s.in ()))); + } + } +} +//$Id$ |