- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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].