00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00048
00049 #ifndef CPPDOM_SHARED_PTR_H
00050 #define CPPDOM_SHARED_PTR_H
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include <memory>
00063 #include <algorithm>
00064 #include <functional>
00065
00067 namespace cppdom_boost {
00068
00069 template< typename T >
00070 inline void checked_delete(T * x)
00071 {
00072 delete x;
00073 }
00074
00075 template< typename T >
00076 inline void checked_array_delete(T * x)
00077 {
00078 delete [] x;
00079 }
00080
00081 namespace detail {
00082
00083 template<typename T> struct shared_deleter
00084 {
00085 static void del(T * p)
00086 {
00087 checked_delete(p);
00088 }
00089 };
00090
00091 struct dynamic_cast_tag {};
00092
00093 template<class T> struct shared_ptr_traits
00094 {
00095 typedef T & reference;
00096 };
00097
00098 template<> struct shared_ptr_traits<void>
00099 {
00100 typedef void reference;
00101 };
00102
00103 }
00104
00105
00106
00108
00112 template<typename T> class shared_ptr {
00113 public:
00114 typedef T element_type;
00115
00116 explicit shared_ptr(T* p =0) : px(p) {
00117 try { pn = new long(1); }
00118 catch (...) { delete p; throw; }
00119 }
00120
00121 shared_ptr(const shared_ptr& r) : px(r.px) { ++*(pn = r.pn); }
00122
00123 ~shared_ptr() { dispose(); }
00124
00125 shared_ptr& operator=(const shared_ptr& r) {
00126 share(r.px,r.pn);
00127 return *this;
00128 }
00129
00130 #if !defined( BOOST_NO_MEMBER_TEMPLATES )
00131 template<typename Y>
00132 shared_ptr(const shared_ptr<Y>& r) : px(r.px) {
00133 ++*(pn = r.pn);
00134 }
00135
00136 template<typename Y>
00137 shared_ptr(std::auto_ptr<Y>& r) {
00138 pn = new long(1);
00139 px = r.release();
00140 }
00141
00142 template<typename Y>
00143 shared_ptr& operator=(const shared_ptr<Y>& r) {
00144 share(r.px,r.pn);
00145 return *this;
00146 }
00147
00148 template<typename Y>
00149 shared_ptr& operator=(std::auto_ptr<Y>& r) {
00150
00151 if (*pn == 1) { delete px; }
00152 else {
00153 long * tmp = new long(1);
00154 --*pn;
00155 pn = tmp;
00156 }
00157 px = r.release();
00158 return *this;
00159 }
00160 #else
00161 shared_ptr(std::auto_ptr<T>& r) {
00162 pn = new long(1);
00163 px = r.release();
00164 }
00165
00166 shared_ptr& operator=(std::auto_ptr<T>& r) {
00167
00168 if (*pn == 1) { delete px; }
00169 else {
00170 long * tmp = new long(1);
00171 --*pn;
00172 pn = tmp;
00173 }
00174 px = r.release();
00175 return *this;
00176 }
00177 #endif
00178
00179 void reset(T* p=0) {
00180 if ( px == p ) return;
00181 if (--*pn == 0) { delete px; }
00182 else {
00183 try { pn = new long; }
00184 catch (...) {
00185 ++*pn;
00186 delete p;
00187 throw;
00188 }
00189 }
00190 *pn = 1;
00191 px = p;
00192 }
00193
00194 T& operator*() const { return *px; }
00195 T* operator->() const { return px; }
00196 T* get() const { return px; }
00197 #ifdef BOOST_SMART_PTR_CONVERSION
00198
00199 operator T*() const { return px; }
00200 #endif
00201
00202 long use_count() const { return *pn; }
00203 bool unique() const { return *pn == 1; }
00204
00205 void swap(shared_ptr<T>& other)
00206 { std::swap(px,other.px); std::swap(pn,other.pn); }
00207
00208
00209
00210
00211 #if defined(BOOST_NO_MEMBER_TEMPLATES) || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
00212 private:
00213 #endif
00214
00215 T* px;
00216 long* pn;
00217
00218
00219 #if !defined( BOOST_NO_MEMBER_TEMPLATES ) && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
00220 template<typename Y> friend class shared_ptr;
00221 #endif
00222
00223 void dispose() { if (--*pn == 0) { delete px; delete pn; } }
00224
00225 void share(T* rpx, long* rpn) {
00226 if (pn != rpn) {
00227 dispose();
00228 px = rpx;
00229 ++*(pn = rpn);
00230 }
00231 }
00232 };
00233
00234 template<typename T, typename U>
00235 inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
00236 { return a.get() == b.get(); }
00237
00238 template<typename T, typename U>
00239 inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
00240 { return a.get() != b.get(); }
00241
00242
00243
00244
00245
00246
00247
00248 template<typename T> inline bool operator<(shared_ptr<T> const& a,
00249 shared_ptr<T> const& b)
00250 {
00251 return std::less<T*>()(a.get(), b.get());
00252 }
00253
00254 template<typename T, typename U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
00255 {
00256 return shared_ptr<T>(r, detail::dynamic_cast_tag());
00257 }
00258
00259 }
00260
00261
00262
00263
00264 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
00265
00266 namespace std {
00267
00268
00269
00270
00271
00272 template<typename T>
00273 inline void swap(cppdom_boost::shared_ptr<T>& a, cppdom_boost::shared_ptr<T>& b)
00274 { a.swap(b); }
00275
00276 }
00277
00278 #endif
00279
00280 #endif