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