shared_ptr.hh

Go to the documentation of this file.
00001 // $Id: smartpointer.hh 5504 2009-04-08 13:35:31Z christi $
00002 
00003 #ifndef DUNE_SHARED_PTR_HH
00004 #define DUNE_SHARED_PTR_HH
00005 
00006 
00007 #if defined HAVE_MEMORY
00008 # include <memory>
00009 #endif
00010 #if defined HAVE_TR1_MEMORY
00011 # include <tr1/memory>
00012 #endif
00013 #if defined HAVE_BOOST_SHARED_PTR_HPP
00014 # include <boost/shared_ptr.hpp>
00015 #endif
00016 
00017 #include<dune/common/nullptr.hh>
00024 namespace Dune
00025 {
00026     // A shared_ptr implementation has been found if SHARED_PTR_NAMESPACE is set at all
00027 #ifdef SHARED_PTR_NAMESPACE
00028     using SHARED_PTR_NAMESPACE :: shared_ptr;
00029 #else
00030 
00042     template<class T>
00043     class shared_ptr
00044     {
00045     public:
00051         typedef T element_type;
00052 
00056         inline shared_ptr();
00057         
00064         inline shared_ptr(T * pointer);
00065         
00077         template<class Deleter>
00078         inline shared_ptr(T * pointer, Deleter deleter);
00079         
00084         inline shared_ptr(const shared_ptr<T>& pointer);
00085         
00089         inline ~shared_ptr();
00090 
00092         inline shared_ptr& operator=(const shared_ptr<T>& pointer);
00093         
00095         inline element_type& operator*();
00096         
00098         inline element_type* operator->();
00099       
00101         inline const element_type& operator*() const;
00102         
00104         inline const element_type* operator->() const;
00105 
00107         element_type* get() const {
00108             return rep_==0 ? 0 : rep_->rep_;
00109         }
00110 
00112         inline void swap(shared_ptr& other);
00113 
00117         inline void reset();
00118 
00120         inline void reset(T* pointer);
00121 
00122         //** \brief Same as shared_ptr(pointer,deleter).swap(*this)
00123         template<class Deleter>
00124         inline void reset(T* pointer, Deleter deleter);
00125 
00127         int use_count() const;
00128 
00129     private:
00131         class PointerRep
00132         {
00133             friend class shared_ptr<element_type>;
00134         protected:
00136             int count_;
00138             element_type * rep_;
00140             PointerRep(element_type * p) : count_(1), rep_(p) {}
00142             virtual ~PointerRep() {};
00143         };
00144 
00146         template<class Deleter>
00147         class PointerRepImpl :
00148             public PointerRep
00149         {
00150             friend class shared_ptr<element_type>;
00151 
00153             PointerRepImpl(element_type * p, const Deleter& deleter) :
00154                 PointerRep(p),
00155                 deleter_(deleter)
00156             {}
00157 
00159             ~PointerRepImpl()
00160             { deleter_(this->rep_); }
00161 
00162             // store a copy of the deleter
00163             Deleter deleter_;
00164         };
00165 
00167         struct DefaultDeleter
00168         {
00169             void operator() (element_type* p) const
00170             { delete p; }
00171         };
00172 
00173 
00174         PointerRep *rep_;
00175 
00176         // Needed for the implicit conversion to "bool"
00177         typedef T* shared_ptr::PointerRep::*__unspecified_bool_type;
00178         
00179     public:
00181         operator __unspecified_bool_type() const // never throws
00182         { 
00183             return rep_ == 0 ? 0 : &shared_ptr::PointerRep::rep_; 
00184         }
00185 
00186 
00187     };
00188 
00189     template<class T>
00190     inline shared_ptr<T>::shared_ptr(T * p)
00191     {
00192         rep_ = new PointerRepImpl<DefaultDeleter>(p, DefaultDeleter());
00193     }
00194 
00195     template<class T>
00196     template<class Deleter>
00197     inline shared_ptr<T>::shared_ptr(T * p, Deleter deleter)
00198     {
00199         rep_ = new PointerRepImpl<Deleter>(p, deleter);
00200     }
00201 
00202     template<class T>
00203     inline shared_ptr<T>::shared_ptr()
00204     {
00205         rep_ = nullptr;
00206     }
00207 
00208     template<class T>
00209     inline shared_ptr<T>::shared_ptr(const shared_ptr<T>& other) : rep_(other.rep_)
00210     {
00211         ++(rep_->count_);
00212     }
00213 
00214     template<class T>
00215     inline shared_ptr<T>& shared_ptr<T>::operator=(const shared_ptr<T>& other)
00216     {
00217         (other.rep_->count_)++;
00218         if(rep_!=0 && --(rep_->count_)<=0) delete rep_;
00219         rep_ = other.rep_;
00220         return *this;
00221     }
00222 
00223     template<class T>
00224     inline shared_ptr<T>::~shared_ptr()
00225     {
00226         if(rep_!=0 && --(rep_->count_)==0){
00227             delete rep_;
00228             rep_=0;
00229         }
00230     }
00231 
00232     template<class T>
00233     inline T& shared_ptr<T>::operator*()
00234     {
00235         return *(rep_->rep_);
00236     }
00237 
00238     template<class T>
00239     inline T *shared_ptr<T>::operator->()
00240     {
00241         return rep_->rep_;
00242     }
00243 
00244     template<class T>
00245     inline const T& shared_ptr<T>::operator*() const
00246     {
00247         return *(rep_->rep_);
00248     }
00249 
00250     template<class T>
00251     inline const T *shared_ptr<T>::operator->() const
00252     {
00253         return rep_->rep_;
00254     }
00255     
00256     template<class T>
00257     inline int shared_ptr<T>::use_count() const
00258     {
00259         return rep_->count_;
00260     }
00261 
00262     template<class T>
00263     inline void shared_ptr<T>::swap(shared_ptr<T>& other)
00264     {
00265         PointerRep* dummy = rep_;
00266         rep_ = other.rep_;
00267         other.rep_ = dummy;
00268     }
00269 
00270     template<class T>
00271     inline void shared_ptr<T>::reset()
00272     {
00273         shared_ptr<T>().swap(*this);
00274     }
00275 
00276     template<class T>
00277     inline void shared_ptr<T>::reset(T* pointer)
00278     {
00279         shared_ptr<T>(pointer).swap(*this);
00280     }
00281 
00282     template<class T>
00283     template<class Deleter>
00284     inline void shared_ptr<T>::reset(T* pointer, Deleter deleter)
00285     {
00286         shared_ptr<T>(pointer, deleter).swap(*this);
00287     }
00288 
00290 #endif  // #ifdef SHARED_PTR_NAMESPACE
00291 
00292 }
00293 #endif
Generated on Mon Apr 26 10:45:21 2010 for dune-common by  doxygen 1.6.3