Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <boost/config.hpp>
00017
00018 #ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
00019 # pragma warning(push)
00020 # pragma warning(disable:4284) // odd return type for operator->
00021 #endif
00022
00023 #include <boost/assert.hpp>
00024 #include <boost/detail/workaround.hpp>
00025 #include <boost/smart_ptr/detail/sp_convertible.hpp>
00026
00027 #include <boost/config/no_tr1/functional.hpp>
00028
00029 #if !defined(BOOST_NO_IOSTREAM)
00030 #if !defined(BOOST_NO_IOSFWD)
00031 #include <iosfwd>
00032 #else
00033 #include <ostream>
00034 #endif
00035 #endif
00036
00037
00038 namespace boost
00039 {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 template<class T> class intrusive_ptr
00057 {
00058 private:
00059
00060 typedef intrusive_ptr this_type;
00061
00062 public:
00063
00064 typedef T element_type;
00065
00066 intrusive_ptr(): px( 0 )
00067 {
00068 }
00069
00070 intrusive_ptr( T * p, bool add_ref = true ): px( p )
00071 {
00072 if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
00073 }
00074
00075 #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00076
00077 template<class U>
00078 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
00079
00080 intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
00081
00082 #else
00083
00084 intrusive_ptr( intrusive_ptr<U> const & rhs )
00085
00086 #endif
00087 : px( rhs.get() )
00088 {
00089 if( px != 0 ) intrusive_ptr_add_ref( px );
00090 }
00091
00092 #endif
00093
00094 intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
00095 {
00096 if( px != 0 ) intrusive_ptr_add_ref( px );
00097 }
00098
00099 ~intrusive_ptr()
00100 {
00101 if( px != 0 ) intrusive_ptr_release( px );
00102 }
00103
00104 #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00105
00106 template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
00107 {
00108 this_type(rhs).swap(*this);
00109 return *this;
00110 }
00111
00112 #endif
00113
00114 intrusive_ptr & operator=(intrusive_ptr const & rhs)
00115 {
00116 this_type(rhs).swap(*this);
00117 return *this;
00118 }
00119
00120 intrusive_ptr & operator=(T * rhs)
00121 {
00122 this_type(rhs).swap(*this);
00123 return *this;
00124 }
00125
00126 void reset()
00127 {
00128 this_type().swap( *this );
00129 }
00130
00131 void reset( T * rhs )
00132 {
00133 this_type( rhs ).swap( *this );
00134 }
00135
00136 T * get() const
00137 {
00138 return px;
00139 }
00140
00141 T & operator*() const
00142 {
00143 BOOST_ASSERT( px != 0 );
00144 return *px;
00145 }
00146
00147 T * operator->() const
00148 {
00149 BOOST_ASSERT( px != 0 );
00150 return px;
00151 }
00152
00153
00154 #include <boost/smart_ptr/detail/operator_bool.hpp>
00155
00156 void swap(intrusive_ptr & rhs)
00157 {
00158 T * tmp = px;
00159 px = rhs.px;
00160 rhs.px = tmp;
00161 }
00162
00163 private:
00164
00165 T * px;
00166 };
00167
00168 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
00169 {
00170 return a.get() == b.get();
00171 }
00172
00173 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
00174 {
00175 return a.get() != b.get();
00176 }
00177
00178 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
00179 {
00180 return a.get() == b;
00181 }
00182
00183 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
00184 {
00185 return a.get() != b;
00186 }
00187
00188 template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
00189 {
00190 return a == b.get();
00191 }
00192
00193 template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
00194 {
00195 return a != b.get();
00196 }
00197
00198 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00199
00200
00201
00202 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
00203 {
00204 return a.get() != b.get();
00205 }
00206
00207 #endif
00208
00209 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
00210 {
00211 return std::less<T *>()(a.get(), b.get());
00212 }
00213
00214 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
00215 {
00216 lhs.swap(rhs);
00217 }
00218
00219
00220
00221 template<class T> T * get_pointer(intrusive_ptr<T> const & p)
00222 {
00223 return p.get();
00224 }
00225
00226 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
00227 {
00228 return static_cast<T *>(p.get());
00229 }
00230
00231 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
00232 {
00233 return const_cast<T *>(p.get());
00234 }
00235
00236 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
00237 {
00238 return dynamic_cast<T *>(p.get());
00239 }
00240
00241
00242
00243 #if !defined(BOOST_NO_IOSTREAM)
00244
00245 #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
00246
00247 template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
00248 {
00249 os << p.get();
00250 return os;
00251 }
00252
00253 #else
00254
00255
00256 #ifndef _STLP_NO_IOSTREAMS
00257
00258 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
00259
00260 using std::basic_ostream;
00261 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
00262 # else
00263 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
00264 # endif
00265 {
00266 os << p.get();
00267 return os;
00268 }
00269
00270 #endif // _STLP_NO_IOSTREAMS
00271
00272 #endif // __GNUC__ < 3
00273
00274 #endif // !defined(BOOST_NO_IOSTREAM)
00275
00276 }
00277
00278 #ifdef BOOST_MSVC
00279 # pragma warning(pop)
00280 #endif
00281
00282 #endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED