Skip to content
Snippets Groups Projects
Commit aaade9dd authored by Carsten Gräser's avatar Carsten Gräser
Browse files

Fix bug in get() method and implement the missing

constructor and reset() taking a deleter.

This solves the issue with bcrsmatrix.hh in fs#727.

Please merge to release.

[[Imported from SVN: r5871]]
parent 9d0790da
No related branches found
No related tags found
No related merge requests found
......@@ -65,6 +65,20 @@ namespace Dune
*/
inline shared_ptr(T * pointer);
/**
* @brief Constructs a new smart pointer from a preallocated Object.
*
* \tparam Deleter This class must by copyconstructable, the copy constructor must not throw an exception
* and it must implement void operator() (T*) const
*
* \param deleter A copy of this deleter is stored
*
* note: the object must be allocated on the heap and after handing the pointer to
* shared_ptr the ownership of the pointer is also handed to the shared_ptr.
*/
template<class Deleter>
inline shared_ptr(T * pointer, Deleter deleter);
/**
* @brief Copy constructor.
* @param pointer The object to copy.
......@@ -93,9 +107,12 @@ namespace Dune
/** \brief Access to the raw pointer, if you really want it */
element_type* get() const {
return rep_->rep_;
return rep_==0 ? 0 : rep_->rep_;
}
/** \brief Swap content of this shared_ptr and another */
inline void swap(shared_ptr& other);
/** \brief Decrease the reference count by one and free the memory if the
reference count has reached 0
*/
......@@ -104,6 +121,10 @@ namespace Dune
/** \brief Detach shared pointer and set it anew for the given pointer */
inline void reset(T* pointer);
//** \brief Same as shared_ptr(pointer,deleter).swap(*this)
template<class Deleter>
inline void reset(T* pointer, Deleter deleter);
/** \brief The number of shared_ptrs pointing to the object we point to */
int use_count() const;
......@@ -116,16 +137,44 @@ namespace Dune
int count_;
/** @brief The representative. */
element_type * rep_;
/** @brief Default Constructor. */
PointerRep() : count_(1), rep_(new element_type) {}
/** @brief Constructor from existing Pointer. */
PointerRep(element_type * p) : count_(1), rep_(p) {}
/** @brief Destructor, deletes element_type* rep_. */
~PointerRep() { delete rep_; }
} *rep_;
virtual ~PointerRep() {};
};
/** @brief Adds call to deleter to PointerRep. */
template<class Deleter>
class PointerRepImpl :
public PointerRep
{
friend class shared_ptr<element_type>;
/** @brief Constructor from existing Pointer with custom deleter. */
PointerRepImpl(element_type * p, const Deleter& deleter) :
PointerRep(p),
deleter_(deleter)
{}
/** @brief Destructor, deletes element_type* rep_ using deleter. */
~PointerRepImpl()
{ deleter_(this->rep_); }
// store a copy of the deleter
Deleter deleter_;
};
/** \brief A default deleter that just calls delete */
struct DefaultDeleter
{
void operator() (element_type* p) const
{ delete p; }
};
PointerRep *rep_;
// Needed for the implicit conversion to "bool"
private:
typedef T* shared_ptr::PointerRep::*__unspecified_bool_type;
public:
......@@ -141,7 +190,14 @@ namespace Dune
template<class T>
inline shared_ptr<T>::shared_ptr(T * p)
{
rep_ = new PointerRep(p);
rep_ = new PointerRepImpl<DefaultDeleter>(p, DefaultDeleter());
}
template<class T>
template<class Deleter>
inline shared_ptr<T>::shared_ptr(T * p, Deleter deleter)
{
rep_ = new PointerRepImpl<Deleter>(p, deleter);
}
template<class T>
......@@ -204,20 +260,31 @@ namespace Dune
return rep_->count_;
}
template<class T>
inline void shared_ptr<T>::swap(shared_ptr<T>& other)
{
PointerRep* dummy = rep_;
rep_ = other.rep_;
other.rep_ = dummy;
}
template<class T>
inline void shared_ptr<T>::reset()
{
if(rep_!=0 && --(rep_->count_)==0) {
delete rep_;
rep_=0;
}
shared_ptr<T>().swap(*this);
}
template<class T>
inline void shared_ptr<T>::reset(T* pointer)
{
reset();
rep_ = new PointerRep(pointer);
shared_ptr<T>(pointer).swap(*this);
}
template<class T>
template<class Deleter>
inline void shared_ptr<T>::reset(T* pointer, Deleter deleter)
{
shared_ptr<T>(pointer, deleter).swap(*this);
}
/** @} */
......
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