00001
00010
00011 #ifndef SUBSYNTH_BOOST_SMART_PTR_H
00012 #define SUBSYNTH_BOOST_SMART_PTR_H
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cstddef>
00024 #include <memory>
00025 #include <algorithm>
00026 #include <functional>
00027
00029 namespace syn
00030 {
00031
00032 template< typename T >
00033 inline void checked_delete(T * x)
00034 {
00035 delete x;
00036 }
00037
00038 template< typename T >
00039 inline void checked_array_delete(T * x)
00040 {
00041 delete [] x;
00042 }
00043
00044
00045 namespace detail {
00046
00047 template<typename T> struct shared_deleter
00048 {
00049 static void del(T * p)
00050 {
00051 checked_delete(p);
00052 }
00053 };
00054
00055 struct dynamic_cast_tag {};
00056
00057 template<class T> struct shared_ptr_traits
00058 {
00059 typedef T & reference;
00060 };
00061
00062 template<> struct shared_ptr_traits<void>
00063 {
00064 typedef void reference;
00065 };
00066
00067 }
00068
00069
00071
00075 template<typename T> class shared_ptr {
00076 public:
00077 typedef T element_type;
00078
00079 explicit shared_ptr(T* p =0) : px(p) {
00080 try { pn = new long(1); }
00081 catch (...) { delete p; throw; }
00082 }
00083
00084 shared_ptr(const shared_ptr& r) : px(r.px) { ++*(pn = r.pn); }
00085
00086 ~shared_ptr() { dispose(); }
00087
00088 shared_ptr& operator=(const shared_ptr& r) {
00089 share(r.px,r.pn);
00090 return *this;
00091 }
00092
00093 #if !defined( BOOST_NO_MEMBER_TEMPLATES )
00094 template<typename Y>
00095 shared_ptr(const shared_ptr<Y>& r) : px(r.px) {
00096 ++*(pn = r.pn);
00097 }
00098
00099 template<typename Y>
00100 shared_ptr(std::auto_ptr<Y>& r) {
00101 pn = new long(1);
00102 px = r.release();
00103 }
00104
00105 template<typename Y>
00106 shared_ptr& operator=(const shared_ptr<Y>& r) {
00107 share(r.px,r.pn);
00108 return *this;
00109 }
00110
00111 template<typename Y>
00112 shared_ptr& operator=(std::auto_ptr<Y>& r) {
00113
00114 if (*pn == 1) { delete px; }
00115 else {
00116 long * tmp = new long(1);
00117 --*pn;
00118 pn = tmp;
00119 }
00120 px = r.release();
00121 return *this;
00122 }
00123 #else
00124 shared_ptr(std::auto_ptr<T>& r) {
00125 pn = new long(1);
00126 px = r.release();
00127 }
00128
00129 shared_ptr& operator=(std::auto_ptr<T>& r) {
00130
00131 if (*pn == 1) { delete px; }
00132 else {
00133 long * tmp = new long(1);
00134 --*pn;
00135 pn = tmp;
00136 }
00137 px = r.release();
00138 return *this;
00139 }
00140 #endif
00141
00142 void reset(T* p=0) {
00143 if ( px == p ) return;
00144 if (--*pn == 0) { delete px; }
00145 else {
00146 try { pn = new long; }
00147 catch (...) {
00148 ++*pn;
00149 delete p;
00150 throw;
00151 }
00152 }
00153 *pn = 1;
00154 px = p;
00155 }
00156
00157 T& operator*() const { return *px; }
00158 T* operator->() const { return px; }
00159 T* get() const { return px; }
00160 #ifdef BOOST_SMART_PTR_CONVERSION
00161
00162 operator T*() const { return px; }
00163 #endif
00164
00165 long use_count() const { return *pn; }
00166 bool unique() const { return *pn == 1; }
00167
00168 void swap(shared_ptr<T>& other)
00169 { std::swap(px,other.px); std::swap(pn,other.pn); }
00170
00171
00172
00173
00174 #if defined(BOOST_NO_MEMBER_TEMPLATES) || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
00175 private:
00176 #endif
00177
00178 T* px;
00179 long* pn;
00180
00181
00182 #if !defined( BOOST_NO_MEMBER_TEMPLATES ) && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
00183 template<typename Y> friend class shared_ptr;
00184 #endif
00185
00186 void dispose() { if (--*pn == 0) { delete px; delete pn; } }
00187
00188 void share(T* rpx, long* rpn) {
00189 if (pn != rpn) {
00190 dispose();
00191 px = rpx;
00192 ++*(pn = rpn);
00193 }
00194 }
00195 };
00196
00197 template<typename T, typename U>
00198 inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
00199 { return a.get() == b.get(); }
00200
00201 template<typename T, typename U>
00202 inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
00203 { return a.get() != b.get(); }
00204
00205
00206
00207
00208
00209
00210
00211 template<typename T, typename U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
00212 {
00213 return shared_ptr<T>(r, detail::dynamic_cast_tag());
00214 }
00215
00216 }
00217
00218 #endif