Skip to content
Snippets Groups Projects
Commit 22f49fa4 authored by Markus Blatt's avatar Markus Blatt
Browse files

Merged latest shared_ptr improvements from trunk

[[Imported from SVN: r7048]]
parents 8b9ddf01 08167899
No related branches found
No related tags found
No related merge requests found
......@@ -33,6 +33,26 @@ namespace Dune
*
* @{
*/
/** @brief The object we reference. */
class SharedCount
{
template<class T1>
friend class shared_ptr;
protected:
/** @brief The number of references. */
int count_;
/** @brief Constructor from existing Pointer. */
SharedCount() : count_(1) {}
/** @brief Copy constructor with type conversion. */
template<class T1>
SharedCount(const SharedCount& rep)
: count_(rep.count_) {}
/** @brief Destructor, deletes element_type* rep_. */
virtual ~SharedCount() {};
};
/**
* @brief A reference counting smart pointer.
*
......@@ -58,6 +78,8 @@ namespace Dune
*/
inline shared_ptr();
inline shared_ptr(nullptr_t null);
/**
* @brief Constructs a new smart pointer from a preallocated Object.
*
......@@ -69,6 +91,7 @@ namespace Dune
template<class T1>
inline shared_ptr(T1 * pointer);
/**
* @brief Constructs a new smart pointer from a preallocated Object.
*
......@@ -91,6 +114,12 @@ namespace Dune
template<class T1>
inline shared_ptr(const shared_ptr<T1>& pointer);
/**
* @brief Copy constructor.
* @param pointer The object to copy.
*/
inline shared_ptr(const shared_ptr& pointer);
/**
* @brief Destructor.
*/
......@@ -114,7 +143,12 @@ namespace Dune
/** \brief Access to the raw pointer, if you really want it */
element_type* get() const {
return rep_==0 ? 0 : rep_->rep_;
return rep_;
}
/** \brief Checks if shared_ptr manages an object, i.e. whether get() != 0. */
operator bool() const {
return count_->count_ != 0 && rep_ != nullptr;
}
/** \brief Swap content of this shared_ptr and another */
......@@ -137,56 +171,30 @@ namespace Dune
int use_count() const;
private:
/** @brief The object we reference. */
class PointerRep
{
template<class T1>
friend class shared_ptr;
protected:
/** @brief The number of references. */
int count_;
/** @brief The representative. */
element_type * rep_;
/** @brief Constructor from existing Pointer. */
template<class T1>
PointerRep(T1 * p) : count_(1), rep_(p) {}
/** @brief Copy constructor with type conversion. */
template<class T1>
PointerRep(const typename shared_ptr<T1>::PointerRep& rep)
: count_(rep.count_), rep_(rep.rep_) {}
template<class T1>
operator typename shared_ptr<T1>::PointerRep()
{
return shared_ptr<T1>::PointerRep(*this);
}
/** @brief Destructor, deletes element_type* rep_. */
virtual ~PointerRep() {};
};
/** @brief Adds call to deleter to PointerRep. */
/** @brief Adds call to deleter to SharedCount. */
template<class Deleter>
class PointerRepImpl :
public PointerRep
class SharedCountImpl :
public SharedCount
{
template<class T1>
friend class shared_ptr;
/** @brief Constructor from existing Pointer with custom deleter. */
PointerRepImpl(element_type * p, const Deleter& deleter) :
PointerRep(p),
SharedCountImpl(T* elem,const Deleter& deleter) :
SharedCount(),
rep_(elem),
deleter_(deleter)
{}
/** @brief Copy constructor with type conversion. */
template<class T1>
PointerRepImpl(const typename shared_ptr<T1>::PointerRepImpl& rep)
: PointerRep(rep), deleter_(rep.deleter_) {}
SharedCountImpl(const SharedCountImpl& rep)
: SharedCount(rep), deleter_(rep.deleter_) {}
/** @brief Destructor, deletes element_type* rep_ using deleter. */
~PointerRepImpl()
{ deleter_(this->rep_); }
~SharedCountImpl()
{ deleter_(rep_); }
// store a copy of the deleter
Deleter deleter_;
T* rep_;
};
/** \brief A default deleter that just calls delete */
......@@ -197,16 +205,17 @@ namespace Dune
};
PointerRep *rep_;
SharedCount *count_;
T *rep_;
// Needed for the implicit conversion to "bool"
typedef T* shared_ptr::PointerRep::*__unspecified_bool_type;
typedef T* SharedCount::*__unspecified_bool_type;
public:
/** \brief Implicit conversion to "bool" */
operator __unspecified_bool_type() const // never throws
{
return rep_ == 0 ? 0 : &shared_ptr::PointerRep::rep_;
return rep_ == 0 ? 0 : &shared_ptr::SharedCount::rep_;
}
......@@ -216,91 +225,115 @@ namespace Dune
template<class T1>
inline shared_ptr<T>::shared_ptr(T1 * p)
{
rep_ = new PointerRepImpl<DefaultDeleter>(p, DefaultDeleter());
rep_ = p;
count_ = new SharedCountImpl<DefaultDeleter>(p, DefaultDeleter());
}
template<class T>
inline shared_ptr<T>::shared_ptr(nullptr_t n)
{
rep_ = n;
count_ = new SharedCountImpl<DefaultDeleter>(rep_, DefaultDeleter());
count_->count_=0;
}
template<class T>
template<class T1, class Deleter>
inline shared_ptr<T>::shared_ptr(T1 * p, Deleter deleter)
{
rep_ = new PointerRepImpl<Deleter>(p, deleter);
rep_ = p;
count_ = new SharedCountImpl<Deleter>(p, deleter);
}
template<class T>
inline shared_ptr<T>::shared_ptr()
{
rep_ = nullptr;
count_ = new SharedCountImpl<DefaultDeleter>(rep_, DefaultDeleter());
count_->count_=0;
}
template<class T>
template<class T1>
inline shared_ptr<T>::shared_ptr(const shared_ptr<T1>& other) : rep_()
inline shared_ptr<T>::shared_ptr(const shared_ptr<T1>& other)
: rep_(other.rep_), count_(other.count_)
{
rep_->count_=other.rep_->count_;
rep_->rep_=other.rep_->rep_;
if (rep_)
++(rep_->count_);
++(count_->count_);
}
template<class T>
inline shared_ptr<T>::shared_ptr(const shared_ptr& other)
: rep_(other.rep_), count_(other.count_)
{
if (rep_)
++(count_->count_);
}
template<class T>
template<class T1>
inline shared_ptr<T>& shared_ptr<T>::operator=(const shared_ptr<T1>& other)
{
if (other.rep_)
(other.rep_->count_)++;
if (other.count_)
(other.count_->count_)++;
if(rep_!=0 && --(rep_->count_)<=0)
delete rep_;
if(rep_!=0 && --(count_->count_)<=0) {
delete count_;
}
rep_ = other.rep_;
count_ = other.count_;
return *this;
}
template<class T>
inline shared_ptr<T>::~shared_ptr()
{
if(rep_!=0 && --(rep_->count_)==0) {
delete rep_;
rep_=0;
if(rep_!=nullptr && --(count_->count_)==0) {
delete count_;
rep_=nullptr;
}
}
template<class T>
inline T& shared_ptr<T>::operator*()
{
return *(rep_->rep_);
return *(rep_);
}
template<class T>
inline T *shared_ptr<T>::operator->()
{
return rep_->rep_;
return rep_;
}
template<class T>
inline const T& shared_ptr<T>::operator*() const
{
return *(rep_->rep_);
return *(rep_);
}
template<class T>
inline const T *shared_ptr<T>::operator->() const
{
return rep_->rep_;
return rep_;
}
template<class T>
inline int shared_ptr<T>::use_count() const
{
return rep_->count_;
return count_->count_;
}
template<class T>
inline void shared_ptr<T>::swap(shared_ptr<T>& other)
{
PointerRep* dummy = rep_;
SharedCount* dummy = count_;
count_=other.count_;
other.count_ = dummy;
T* tdummy=rep_;
rep_ = other.rep_;
other.rep_ = dummy;
other.rep_ = tdummy;
}
template<class T>
......
......@@ -65,6 +65,23 @@ int main(){
// test conversion in make_shared
shared_ptr<A> a=test_make_shared();
{
shared_ptr<B> b(new B);
a=b;
if(b.use_count()!=2) {
std::cout << "Reference count is wrong! "<<__LINE__<<":"<<
__FILE__<<std::endl;
ret=1;
}
if(a.use_count()!=2) {
std::cout << "Reference count is wrong! "<<__LINE__<<":"<<
__FILE__<<std::endl;
ret=1;
}
}
// print the type of the shared_ptr, so we know whether we are
// checking dune's shared_ptr or some std one
std::cout << "=== checking shared_ptr type: " << className(foo)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment