shared_ptr.hh
Go to the documentation of this file.00001
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
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
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
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
00177 typedef T* shared_ptr::PointerRep::*__unspecified_bool_type;
00178
00179 public:
00181 operator __unspecified_bool_type() const
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