// Copyright (C) 2007 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_SHARED_PTr_ABSTRACT_ #ifdef DLIB_SHARED_PTr_ABSTRACT_ #include "weak_ptr_abstract.h" #include namespace dlib { // ---------------------------------------------------------------------------------------- class bad_weak_ptr: public std::exception {} // ---------------------------------------------------------------------------------------- template < typename T > class shared_ptr { /*! INITIAL VALUE defined by constructors WHAT THIS OBJECT REPRESENTS This object represents a reference counted smart pointer. Each shared_ptr contains a pointer to some object and when the last shared_ptr that points to the object is destructed or reset() then the object is guaranteed to be deleted. This is an implementation of the std::tr1::shared_ptr template from the document ISO/IEC PDTR 19768, Proposed Draft Technical Report on C++ Library Extensions. The only deviation from that document is that this shared_ptr is declared inside the dlib namespace rather than std::tr1. THREAD SAFETY This object is not thread safe. Especially so since it is reference counted. So you should take care to not have two shared_ptr objects in different threads that point to the same object. If you want a thread safe version of this object you should use the dlib::shared_ptr_thread_safe object instead. !*/ public: typedef T element_type; shared_ptr( ); /*! ensures - #get() == 0 - #use_count() == 0 !*/ template explicit shared_ptr( Y* p ); /*! requires - p is convertible to a T* type pointer - p can be deleted by calling "delete p;" and doing so will not throw exceptions - p != 0 ensures - #get() == p - #use_count() == 1 - #*this object owns the pointer p throws - std::bad_alloc if this exception is thrown then "delete p;" is called !*/ template shared_ptr( Y* p, const D& d ); /*! requires - p is convertible to a T* type pointer - D is copy constructable (and the copy constructor of D doesn't throw) - p can be deleted by calling "d(p);" and doing so will not throw exceptions - p != 0 ensures - #get() == p - #use_count() == 1 - #*this object owns the pointer p throws - std::bad_alloc if this exception is thrown then "d(p);" is called !*/ shared_ptr( const shared_ptr& r ); /*! ensures - #get() == #r.get() - #use_count() == #r.use_count() - If r is empty, constructs an empty shared_ptr object; otherwise, constructs a shared_ptr object that shares ownership with r. !*/ template shared_ptr( const shared_ptr& r ); /*! requires - Y* is convertible to T* ensures - #get() == #r.get() - #use_count() == #r.use_count() - If r is empty, constructs an empty shared_ptr object; otherwise, constructs a shared_ptr object that shares ownership with r. !*/ template explicit shared_ptr( const weak_ptr& r ); /*! requires - Y* is convertible to T* ensures - #get() == #r.get() - #use_count() == #r.use_count() - If r is empty, constructs an empty shared_ptr object; otherwise, constructs a shared_ptr object that shares ownership with r. throws - bad_weak_ptr this exception is thrown if r.expired() == true !*/ ~shared_ptr( ); /*! ensures - if (use_count() > 1) - this object destroys itself but otherwise has no effect (i.e. the pointer get() is still valid and shared between the remaining shared_ptr objects) - else if (use_count() == 1) - deletes the pointer get() by calling delete (or using the deleter passed to the constructor if one was passed in) - else - in this case get() == 0 so there is nothing to do so nothing occurs !*/ shared_ptr& operator= ( const shared_ptr& r ); /*! ensures - equivalent to shared_ptr(r).swap(*this). - returns #*this !*/ template shared_ptr& operator= ( const shared_ptr& r ); /*! requires - Y* is convertible to T* ensures - equivalent to shared_ptr(r).swap(*this). - returns #*this !*/ void reset( ); /*! ensures - equivalent to shared_ptr().swap(*this) !*/ template void reset( Y* p ); /*! requires - p is convertible to a T* type pointer - p can be deleted by calling "delete p;" and doing so will not throw exceptions - p != 0 ensures - equivalent to shared_ptr(p).swap(*this) !*/ template void reset( Y* p, const D& d ); /*! requires - p is convertible to a T* type pointer - D is copy constructable (and the copy constructor of D doesn't throw) - p can be deleted by calling "d(p);" and doing so will not throw exceptions - p != 0 ensures - equivalent to shared_ptr(p,d).swap(*this) !*/ T* get( ) const; /*! ensures - returns the stored pointer !*/ T& operator*( ) const; /*! requires - get() != 0 ensures - returns a reference to *get() !*/ T* operator->( ) const; /*! requires - get() != 0 ensures - returns get() !*/ bool unique( ) const; /*! ensures - returns (use_count() == 1) !*/ long use_count( ) const; /*! ensures - The number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this is empty. !*/ operator bool( ) const; /*! ensures - returns (get() != 0) !*/ void swap( shared_ptr& b ); /*! ensures - swaps *this and item !*/ }; // ---------------------------------------------------------------------------------------- template bool operator== ( const shared_ptr& a, const shared_ptr& b ); /*! ensures - returns a.get() == b.get() !*/ template bool operator!= ( const shared_ptr& a, const shared_ptr& b ) { return a.get() != b.get(); } /*! ensures - returns a.get() != b.get() !*/ template bool operator< ( const shared_ptr& a, const shared_ptr& b ); /*! ensures - Defines an operator< on shared_ptr types appropriate for use in the associative containers. !*/ template void swap( shared_ptr& a, shared_ptr& b ) { a.swap(b); } /*! provides a global swap function !*/ template shared_ptr static_pointer_cast( const shared_ptr& r ); /*! - if (r.get() == 0) then - returns shared_ptr() - else - returns a shared_ptr object that stores static_cast(r.get()) and shares ownership with r. !*/ template shared_ptr const_pointer_cast( const shared_ptr& r ); /*! - if (r.get() == 0) then - returns shared_ptr() - else - returns a shared_ptr object that stores const_cast(r.get()) and shares ownership with r. !*/ template shared_ptr dynamic_pointer_cast( const shared_ptr& r ); /*! ensures - if (dynamic_cast(r.get()) returns a nonzero value) then - returns a shared_ptr object that stores a copy of dynamic_cast(r.get()) and shares ownership with r - else - returns an empty shared_ptr object. !*/ template std::basic_ostream & operator<< ( std::basic_ostream & os, const shared_ptr& p ); /*! ensures - performs os << p.get() - returns os !*/ template D* get_deleter( const shared_ptr& p ); /*! ensures - if (*this owns a deleter d of type cv-unqualified D) then - returns &d - else - returns 0 !*/ // ---------------------------------------------------------------------------------------- } #endif // DLIB_SHARED_PTr_ABSTRACT_