From a6c0f71a9edbc7afb017da72696c704f4465e9d0 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@dune-project.org> Date: Mon, 12 Oct 2009 07:47:00 +0000 Subject: [PATCH] Copy the file smartpointer.hh to shared_ptr.hh and change the name of the class from SmartPointer to shared_ptr. That way the implementation is like the tr1 one. The old file is deprecated. The tr1 implementation is not yet used even on platforms that have it, because I have to think of a proper test first. [[Imported from SVN: r5630]] --- common/Makefile.am | 2 +- common/shared_ptr.hh | 176 +++++++++++++++++++++++++++++++++++++++++ common/smartpointer.hh | 3 +- 3 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 common/shared_ptr.hh diff --git a/common/Makefile.am b/common/Makefile.am index 41b9d41e3..dfdc14f55 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -16,7 +16,7 @@ commoninclude_HEADERS = alignment.hh array.hh \ fvector.hh genericiterator.hh \ helpertemplates.hh iteratorfacades.hh \ misc.hh poolallocator.hh finitestack.hh \ - sllist.hh smartpointer.hh stdstreams.hh timer.hh tuples.hh \ + sllist.hh shared_ptr.hh smartpointer.hh stdstreams.hh timer.hh tuples.hh \ typetraits.hh precision.hh bigunsignedint.hh \ gcd.hh lcm.hh configparser.hh propertymap.hh \ collectivecommunication.hh mpihelper.hh singleton.hh \ diff --git a/common/shared_ptr.hh b/common/shared_ptr.hh new file mode 100644 index 000000000..7c47aa472 --- /dev/null +++ b/common/shared_ptr.hh @@ -0,0 +1,176 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +// $Id: smartpointer.hh 5504 2009-04-08 13:35:31Z christi $ + +#ifndef DUNE_SHARED_PTR_HH +#define DUNE_SHARED_PTR_HH + +/** + * @file + * @brief This file implements the class shared_ptr (a reference counting + * pointer), for those systems that don't have it in the standard library. + * @author Markus Blatt + */ +namespace Dune +{ + /** @addtogroup Common + * + * @{ + */ + /** + * @brief A reference counting smart pointer. + * + * It is designed such that it is usable within a std::vector. + * The contained object is destroyed only if there are no more + * references to it. + */ + template<class T> + class shared_ptr + { + public: + /** + * @brief The data type we are a pointer for. + * + * This has to have a parameterless constructor. + */ + typedef T element_type; + + /** + * @brief Constructs a new smart pointer and allocates the referenced Object. + */ + inline shared_ptr(); + + /** + * @brief Constructs a new smart pointer from a preallocated Object. + * + * 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. + */ + inline shared_ptr(T * pointer); + + /** + * @brief Copy constructor. + * @param pointer The object to copy. + */ + inline shared_ptr(const shared_ptr<T>& pointer); + + /** + * @brief Destructor. + */ + inline ~shared_ptr(); + + /** \brief Assignment operator */ + inline shared_ptr& operator=(const shared_ptr<T>& pointer); + + /** \brief Dereference as object */ + inline element_type& operator*(); + + /** \brief Dereference as pointer */ + inline element_type* operator->(); + + /** \brief Dereference as const object */ + inline const element_type& operator*() const; + + /** \brief Dereference as const pointer */ + inline const element_type* operator->() const; + + /** + * @brief Deallocates the references object if no other + * pointers reference it. + */ + inline void deallocate(); + int count() const; + private: + /** @brief The object we reference. */ + class PointerRep + { + friend class shared_ptr<element_type>; + /** @brief The number of references. */ + 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_; + }; + + template<class T> + inline shared_ptr<T>::shared_ptr(T * p) + { + rep_ = new PointerRep(p); + } + + template<class T> + inline shared_ptr<T>::shared_ptr() + { + rep_ = new PointerRep; + } + + template<class T> + inline shared_ptr<T>::shared_ptr(const shared_ptr<T>& other) : rep_(other.rep_) + { + ++(rep_->count_); + } + + template<class T> + inline shared_ptr<T>& shared_ptr<T>::operator=(const shared_ptr<T>& other) + { + (other.rep_->count_)++; + if(rep_!=0 && --(rep_->count_)<=0) delete rep_; + rep_ = other.rep_; + return *this; + } + + template<class T> + inline shared_ptr<T>::~shared_ptr() + { + if(rep_!=0 && --(rep_->count_)==0) { + delete rep_; + rep_=0; + } + } + + template<class T> + inline T& shared_ptr<T>::operator*() + { + return *(rep_->rep_); + } + + template<class T> + inline T *shared_ptr<T>::operator->() + { + return rep_->rep_; + } + + template<class T> + inline const T& shared_ptr<T>::operator*() const + { + return *(rep_->rep_); + } + + template<class T> + inline const T *shared_ptr<T>::operator->() const + { + return rep_->rep_; + } + + template<class T> + inline int shared_ptr<T>::count() const + { + return rep_->count_; + } + + template<class T> + inline void shared_ptr<T>::deallocate() + { + assert(rep_!=0 && rep_->count_==1); + delete rep_; + rep_=0; + } + /** @} */ +} +#endif diff --git a/common/smartpointer.hh b/common/smartpointer.hh index 79fe420c3..06b93c24f 100644 --- a/common/smartpointer.hh +++ b/common/smartpointer.hh @@ -4,7 +4,8 @@ #ifndef DUNE_SMARTPOINTER_HH #define DUNE_SMARTPOINTER_HH -#include <iostream> + +#warning This file is deprecated. Please use shared_ptr.hh instead! /** * @file -- GitLab