// 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 <exception>
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<typename Y>
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<typename Y, typename D>
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<typename Y>
shared_ptr(
const shared_ptr<Y>& 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<typename Y>
explicit shared_ptr(
const weak_ptr<Y>& 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<typename Y>
shared_ptr& operator= (
const shared_ptr<Y>& 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<typename Y>
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<typename Y, typename D>
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<typename T, typename U>
bool operator== (
const shared_ptr<T>& a,
const shared_ptr<U>& b
);
/*!
ensures
- returns a.get() == b.get()
!*/
template<typename T, typename U>
bool operator!= (
const shared_ptr<T>& a,
const shared_ptr<U>& b
) { return a.get() != b.get(); }
/*!
ensures
- returns a.get() != b.get()
!*/
template<typename T, typename U>
bool operator< (
const shared_ptr<T>& a,
const shared_ptr<U>& b
);
/*!
ensures
- Defines an operator< on shared_ptr types appropriate for use in the associative
containers.
!*/
template<typename T>
void swap(
shared_ptr<T>& a,
shared_ptr<T>& b
) { a.swap(b); }
/*!
provides a global swap function
!*/
template<typename T, typename U>
shared_ptr<T> static_pointer_cast(
const shared_ptr<U>& r
);
/*!
- if (r.get() == 0) then
- returns shared_ptr<T>()
- else
- returns a shared_ptr<T> object that stores static_cast<T*>(r.get()) and shares
ownership with r.
!*/
template<typename T, typename U>
shared_ptr<T> const_pointer_cast(
const shared_ptr<U>& r
);
/*!
- if (r.get() == 0) then
- returns shared_ptr<T>()
- else
- returns a shared_ptr<T> object that stores const_cast<T*>(r.get()) and shares
ownership with r.
!*/
template<typename T, typename U>
shared_ptr<T> dynamic_pointer_cast(
const shared_ptr<U>& r
);
/*!
ensures
- if (dynamic_cast<T*>(r.get()) returns a nonzero value) then
- returns a shared_ptr<T> object that stores a copy of
dynamic_cast<T*>(r.get()) and shares ownership with r
- else
- returns an empty shared_ptr<T> object.
!*/
template<typename E, typename T, typename Y>
std::basic_ostream<E, T> & operator<< (
std::basic_ostream<E, T> & os,
const shared_ptr<Y>& p
);
/*!
ensures
- performs os << p.get()
- returns os
!*/
template<typename D, typename T>
D* get_deleter(
const shared_ptr<T>& p
);
/*!
ensures
- if (*this owns a deleter d of type cv-unqualified D) then
- returns &d
- else
- returns 0
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SHARED_PTr_ABSTRACT_