dune-common 2.1.1
|
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 00225 if(rep_!=0 && --(rep_->count_)<=0) 00226 delete rep_; 00227 00228 rep_ = other.rep_; 00229 return *this; 00230 } 00231 00232 template<class T> 00233 inline shared_ptr<T>::~shared_ptr() 00234 { 00235 if(rep_!=0 && --(rep_->count_)==0){ 00236 delete rep_; 00237 rep_=0; 00238 } 00239 } 00240 00241 template<class T> 00242 inline T& shared_ptr<T>::operator*() 00243 { 00244 return *(rep_->rep_); 00245 } 00246 00247 template<class T> 00248 inline T *shared_ptr<T>::operator->() 00249 { 00250 return rep_->rep_; 00251 } 00252 00253 template<class T> 00254 inline const T& shared_ptr<T>::operator*() const 00255 { 00256 return *(rep_->rep_); 00257 } 00258 00259 template<class T> 00260 inline const T *shared_ptr<T>::operator->() const 00261 { 00262 return rep_->rep_; 00263 } 00264 00265 template<class T> 00266 inline int shared_ptr<T>::use_count() const 00267 { 00268 return rep_->count_; 00269 } 00270 00271 template<class T> 00272 inline void shared_ptr<T>::swap(shared_ptr<T>& other) 00273 { 00274 PointerRep* dummy = rep_; 00275 rep_ = other.rep_; 00276 other.rep_ = dummy; 00277 } 00278 00279 template<class T> 00280 inline void shared_ptr<T>::reset() 00281 { 00282 shared_ptr<T>().swap(*this); 00283 } 00284 00285 template<class T> 00286 inline void shared_ptr<T>::reset(T* pointer) 00287 { 00288 shared_ptr<T>(pointer).swap(*this); 00289 } 00290 00291 template<class T> 00292 template<class Deleter> 00293 inline void shared_ptr<T>::reset(T* pointer, Deleter deleter) 00294 { 00295 shared_ptr<T>(pointer, deleter).swap(*this); 00296 } 00297 00299 #endif // #ifdef SHARED_PTR_NAMESPACE 00300 00329 template<class T> 00330 struct null_deleter 00331 { 00332 void operator() (T* p) const {} 00333 }; 00334 00343 template<typename T> 00344 inline shared_ptr<T> stackobject_to_shared_ptr(T & t) 00345 { 00346 return shared_ptr<T>(&t, null_deleter<T>()); 00347 } 00348 00362 template<typename T, typename T2> 00363 inline shared_ptr<T2> stackobject_to_shared_ptr(T & t) 00364 { 00365 return shared_ptr<T2>(dynamic_cast<T2*>(&t), null_deleter<T2>()); 00366 } 00367 00368 } 00369 #endif