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>
00018 #include<dune/common/typetraits.hh>
00025 namespace Dune
00026 {
00027     // A shared_ptr implementation has been found if SHARED_PTR_NAMESPACE is set at all
00028 #ifdef SHARED_PTR_NAMESPACE
00029     using SHARED_PTR_NAMESPACE :: shared_ptr;
00030 #else
00031 
00043     template<class T>
00044     class shared_ptr
00045     {
00046     public:
00052         typedef T element_type;
00053 
00057         inline shared_ptr();
00058         
00067         inline shared_ptr(T * pointer);
00068         
00081         template<class Deleter>
00082         inline shared_ptr(T * pointer, Deleter deleter);
00083         
00088         inline shared_ptr(const shared_ptr<T>& pointer);
00089         
00093         inline ~shared_ptr();
00094 
00096         inline shared_ptr& operator=(const shared_ptr<T>& pointer);
00097         
00099         inline element_type& operator*();
00100         
00102         inline element_type* operator->();
00103       
00105         inline const element_type& operator*() const;
00106         
00108         inline const element_type* operator->() const;
00109 
00111         element_type* get() const {
00112             return rep_==0 ? 0 : rep_->rep_;
00113         }
00114 
00116         inline void swap(shared_ptr& other);
00117 
00121         inline void reset();
00122 
00124         inline void reset(T* pointer);
00125 
00126         //** \brief Same as shared_ptr(pointer,deleter).swap(*this)
00127         template<class Deleter>
00128         inline void reset(T* pointer, Deleter deleter);
00129 
00131         int use_count() const;
00132 
00133     private:
00135         class PointerRep
00136         {
00137             friend class shared_ptr<element_type>;
00138         protected:
00140             int count_;
00142             element_type * rep_;
00144             PointerRep(element_type * p) : count_(1), rep_(p) {}
00146             virtual ~PointerRep() {};
00147         };
00148 
00150         template<class Deleter>
00151         class PointerRepImpl :
00152             public PointerRep
00153         {
00154             friend class shared_ptr<element_type>;
00155 
00157             PointerRepImpl(element_type * p, const Deleter& deleter) :
00158                 PointerRep(p),
00159                 deleter_(deleter)
00160             {}
00161 
00163             ~PointerRepImpl()
00164             { deleter_(this->rep_); }
00165 
00166             // store a copy of the deleter
00167             Deleter deleter_;
00168         };
00169 
00171         struct DefaultDeleter
00172         {
00173             void operator() (element_type* p) const
00174             { delete p; }
00175         };
00176 
00177 
00178         PointerRep *rep_;
00179 
00180         // Needed for the implicit conversion to "bool"
00181         typedef T* shared_ptr::PointerRep::*__unspecified_bool_type;
00182         
00183     public:
00185         operator __unspecified_bool_type() const // never throws
00186         { 
00187             return rep_ == 0 ? 0 : &shared_ptr::PointerRep::rep_; 
00188         }
00189 
00190 
00191     };
00192 
00193     template<class T>
00194     inline shared_ptr<T>::shared_ptr(T * p)
00195     {
00196         rep_ = new PointerRepImpl<DefaultDeleter>(p, DefaultDeleter());
00197     }
00198 
00199     template<class T>
00200     template<class Deleter>
00201     inline shared_ptr<T>::shared_ptr(T * p, Deleter deleter)
00202     {
00203         rep_ = new PointerRepImpl<Deleter>(p, deleter);
00204     }
00205 
00206     template<class T>
00207     inline shared_ptr<T>::shared_ptr()
00208     {
00209         rep_ = nullptr;
00210     }
00211 
00212     template<class T>
00213     inline shared_ptr<T>::shared_ptr(const shared_ptr<T>& other) : rep_(other.rep_)
00214     {
00215         if (rep_)
00216             ++(rep_->count_);
00217     }
00218 
00219     template<class T>
00220     inline shared_ptr<T>& shared_ptr<T>::operator=(const shared_ptr<T>& other)
00221     {
00222         if (other.rep_) {
00223             (other.rep_->count_)++;
00224             if(rep_!=0 && --(rep_->count_)<=0) delete rep_;
00225         }
00226         rep_ = other.rep_;
00227         return *this;
00228     }
00229 
00230     template<class T>
00231     inline shared_ptr<T>::~shared_ptr()
00232     {
00233         if(rep_!=0 && --(rep_->count_)==0){
00234             delete rep_;
00235             rep_=0;
00236         }
00237     }
00238 
00239     template<class T>
00240     inline T& shared_ptr<T>::operator*()
00241     {
00242         return *(rep_->rep_);
00243     }
00244 
00245     template<class T>
00246     inline T *shared_ptr<T>::operator->()
00247     {
00248         return rep_->rep_;
00249     }
00250 
00251     template<class T>
00252     inline const T& shared_ptr<T>::operator*() const
00253     {
00254         return *(rep_->rep_);
00255     }
00256 
00257     template<class T>
00258     inline const T *shared_ptr<T>::operator->() const
00259     {
00260         return rep_->rep_;
00261     }
00262     
00263     template<class T>
00264     inline int shared_ptr<T>::use_count() const
00265     {
00266         return rep_->count_;
00267     }
00268 
00269     template<class T>
00270     inline void shared_ptr<T>::swap(shared_ptr<T>& other)
00271     {
00272         PointerRep* dummy = rep_;
00273         rep_ = other.rep_;
00274         other.rep_ = dummy;
00275     }
00276 
00277     template<class T>
00278     inline void shared_ptr<T>::reset()
00279     {
00280         shared_ptr<T>().swap(*this);
00281     }
00282 
00283     template<class T>
00284     inline void shared_ptr<T>::reset(T* pointer)
00285     {
00286         shared_ptr<T>(pointer).swap(*this);
00287     }
00288 
00289     template<class T>
00290     template<class Deleter>
00291     inline void shared_ptr<T>::reset(T* pointer, Deleter deleter)
00292     {
00293         shared_ptr<T>(pointer, deleter).swap(*this);
00294     }
00295 
00297 #endif  // #ifdef SHARED_PTR_NAMESPACE
00298 
00327     template<class T>
00328     struct null_deleter
00329     {
00330         void operator() (T* p) const {}
00331     };
00332 
00341     template<typename T>
00342     inline shared_ptr<T> stackobject_to_shared_ptr(T & t)
00343     {
00344         return shared_ptr<T>(&t, null_deleter<T>());
00345     }
00346 
00360     template<typename T, typename T2>
00361     inline shared_ptr<T2> stackobject_to_shared_ptr(T & t)
00362     {
00363         return shared_ptr<T2>(dynamic_cast<T2*>(&t), null_deleter<T2>());
00364     }
00365 
00366 }
00367 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].