From ee50361d9f4d657f4867491403a058d0a85c36a4 Mon Sep 17 00:00:00 2001 From: Martin Nolte <mnolte@dune-project.org> Date: Wed, 22 Aug 2012 08:14:23 +0000 Subject: [PATCH] add SmartPtr SmartPtr< T > is similar to shared_ptr< T > in its intention. However, it demands methods addReference and removeReference on the object it points to. Actually, you could implement shared_ptr< T > through a SmartPtr< RefCountWrapper< T > > and a few cast operators. [[Imported from SVN: r6919]] --- dune/common/Makefile.am | 1 + dune/common/smartptr.hh | 107 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 dune/common/smartptr.hh diff --git a/dune/common/Makefile.am b/dune/common/Makefile.am index 19262854a..b3f283bba 100644 --- a/dune/common/Makefile.am +++ b/dune/common/Makefile.am @@ -70,6 +70,7 @@ commoninclude_HEADERS = \ shared_ptr.hh \ singleton.hh \ smallobject.hh \ + smartptr.hh \ static_assert.hh \ stdstreams.hh \ timer.hh \ diff --git a/dune/common/smartptr.hh b/dune/common/smartptr.hh new file mode 100644 index 000000000..7ff081dae --- /dev/null +++ b/dune/common/smartptr.hh @@ -0,0 +1,107 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_SMARTPTR_HH +#define DUNE_SMARTPTR_HH + +#include <dune/common/nullptr.hh> + +namespace Dune +{ + + // ReferenceCountable + // ------------------ + + struct ReferenceCountable + { + ReferenceCountable () + : refCount_( 0 ) + {} + + ReferenceCountable ( const ReferenceCountable &other ) + : refCount_( 0 ) + {} + + const ReferenceCountable &operator= ( const ReferenceCountable &other ) + { + return *this; + } + + void addReference () + { + ++refCount_; + } + + bool removeReference () + { + return (--refCount_ == 0); + } + + private: + unsigned int refCount_; + }; + + + + // SmartPtr + // -------- + + template< class T > + struct SmartPtr + { + explicit SmartPtr ( T *ptr = nullptr ) + : ptr_( ptr ) + { + if( ptr_ ) + ptr_->addReference(); + } + + SmartPtr ( const SmartPtr &other ) + : ptr_( other.ptr_ ) + { + if( ptr_ ) + ptr_->addReference(); + } + + ~SmartPtr () + { + if( ptr_ && ptr_->removeReference() ) + delete ptr_; + } + + const SmartPtr &operator= ( T *ptr ) + { + if( ptr ) + ptr->addReference(); + if( ptr_ && ptr_->removeReference() ) + delete ptr_; + ptr_ = ptr; + return *this; + } + + const SmartPtr &operator= ( const SmartPtr &other ) + { + if( other.ptr_ ) + other.ptr_->addReference(); + if( ptr_ && ptr_->removeReference() ) + delete ptr_; + ptr_ = other.ptr_; + return *this; + } + + operator bool () const { return ptr_; } + operator T * () const { return ptr_; } + + T &operator* () const { return *ptr_; } + T *operator-> () const { return ptr_; } + + + bool operator== ( const SmartPtr &other ) const { return (ptr_ == other.ptr_); } + bool operator!= ( const SmartPtr &other ) const { return (ptr_ != other.ptr_); } + + private: + T *ptr_; + }; + +} // namespace Dune + +#endif // #ifndef DUNE_SMARTPTR_HH -- GitLab