00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef ZYPP_BASE_PTRTYPES_H
00014 #define ZYPP_BASE_PTRTYPES_H
00015
00016 #include <string>
00017
00018 #include <boost/scoped_ptr.hpp>
00019 #include <boost/shared_ptr.hpp>
00020 #include <boost/weak_ptr.hpp>
00021 #include <boost/intrusive_ptr.hpp>
00022
00024 namespace zypp
00025 {
00026
00043
00045 using boost::scoped_ptr;
00046
00048 using boost::shared_ptr;
00049
00051 using boost::weak_ptr;
00052
00054 using boost::intrusive_ptr;
00055
00057 using boost::static_pointer_cast;
00059 using boost::const_pointer_cast;
00061 using boost::dynamic_pointer_cast;
00062
00063 template<class _D>
00064 inline std::ostream &
00065 operator<<( std::ostream & str, const shared_ptr<_D> & obj )
00066 {
00067 if ( obj )
00068 return str << *obj;
00069 return str << std::string("NULL");
00070 }
00071
00072 template<class _D>
00073 inline std::ostream &
00074 operator<<( std::ostream & str, const intrusive_ptr<_D> & obj )
00075 {
00076 if ( obj )
00077 return str << *obj;
00078 return str << std::string("NULL");
00079 }
00080
00082
00083
00084
00086
00091 namespace rw_pointer {
00092
00093 template<class _D>
00094 struct Shared
00095 {
00096 typedef shared_ptr<_D> _Ptr;
00097 typedef shared_ptr<const _D> _constPtr;
00099 bool unique( const _constPtr & ptr_r )
00100 { return !ptr_r || ptr_r.unique(); }
00101 bool unique( const _Ptr & ptr_r )
00102 { return !ptr_r || ptr_r.unique(); }
00104 long use_count( const _constPtr & ptr_r ) const
00105 { return ptr_r.use_count(); }
00106 long use_count( const _Ptr & ptr_r ) const
00107 { return ptr_r.use_count(); }
00108 };
00109
00110 template<class _D>
00111 struct Intrusive
00112 {
00113 typedef intrusive_ptr<_D> _Ptr;
00114 typedef intrusive_ptr<const _D> _constPtr;
00116 bool unique( const _constPtr & ptr_r )
00117 { return !ptr_r || (ptr_r->refCount() <= 1); }
00118 bool unique( const _Ptr & ptr_r )
00119 { return !ptr_r || (ptr_r->refCount() <= 1); }
00121 long use_count( const _constPtr & ptr_r ) const
00122 { return ptr_r ? ptr_r->refCount() : 0; }
00123 long use_count( const _Ptr & ptr_r ) const
00124 { return ptr_r ? ptr_r->refCount() : 0; }
00125 };
00126 }
00128
00130
00131
00132
00170 template<class _D, class _Traits = rw_pointer::Shared<_D> >
00171 struct RW_pointer
00172 {
00173 typedef typename _Traits::_Ptr _Ptr;
00174 typedef typename _Traits::_constPtr _constPtr;
00175 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00176
00177 explicit
00178 RW_pointer( typename _Ptr::element_type * dptr = 0 )
00179 : _dptr( dptr )
00180 {}
00181
00182 explicit
00183 RW_pointer( _Ptr dptr )
00184 : _dptr( dptr )
00185 {}
00186
00187 void reset()
00188 { _Ptr().swap( _dptr ); }
00189
00190 void reset( typename _Ptr::element_type * dptr )
00191 { _Ptr( dptr ).swap( _dptr ); }
00192
00193 void swap( RW_pointer & rhs )
00194 { _dptr.swap( rhs._dptr ); }
00195
00196 void swap( _Ptr & rhs )
00197 { _dptr.swap( rhs ); }
00198
00199 operator unspecified_bool_type() const
00200 { return _dptr; }
00201
00202 const _D & operator*() const
00203 { return *_dptr; };
00204
00205 const _D * operator->() const
00206 { return _dptr.get(); }
00207
00208 const _D * get() const
00209 { return _dptr.get(); }
00210
00211 _D & operator*()
00212 { return *_dptr; }
00213
00214 _D * operator->()
00215 { return _dptr.get(); }
00216
00217 _D * get()
00218 { return _dptr.get(); }
00219
00220 public:
00221 bool unique() const
00222 { return _Traits().unique( _dptr ); }
00223
00224 long use_count() const
00225 { return _Traits().use_count( _dptr ); }
00226
00227 _constPtr getPtr() const
00228 { return _dptr; }
00229
00230 _Ptr getPtr()
00231 { return _dptr; }
00232
00233 private:
00234 _Ptr _dptr;
00235 };
00237
00243 template<class _D, class _Ptr>
00244 inline std::ostream &
00245 operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
00246 {
00247 if ( obj.get() )
00248 return str << *obj.get();
00249 return str << std::string("NULL");
00250 }
00251
00253
00255
00256
00257
00265 template<class _D, class _Traits = rw_pointer::Shared<_D> >
00266 struct RWCOW_pointer
00267 {
00268 typedef typename _Traits::_Ptr _Ptr;
00269 typedef typename _Traits::_constPtr _constPtr;
00270 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00271
00272 explicit
00273 RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
00274 : _dptr( dptr )
00275 {}
00276
00277 explicit
00278 RWCOW_pointer( _Ptr dptr )
00279 : _dptr( dptr )
00280 {}
00281
00282 void reset()
00283 { _Ptr().swap( _dptr ); }
00284
00285 void reset( typename _Ptr::element_type * dptr )
00286 { _Ptr( dptr ).swap( _dptr ); }
00287
00288 void swap( RWCOW_pointer & rhs )
00289 { _dptr.swap( rhs._dptr ); }
00290
00291 void swap( _Ptr & rhs )
00292 { _dptr.swap( rhs ); }
00293
00294 operator unspecified_bool_type() const
00295 { return _dptr; }
00296
00297 const _D & operator*() const
00298 { return *_dptr; };
00299
00300 const _D * operator->() const
00301 { return _dptr.get(); }
00302
00303 const _D * get() const
00304 { return _dptr.get(); }
00305
00306 _D & operator*()
00307 { assertUnshared(); return *_dptr; }
00308
00309 _D * operator->()
00310 { assertUnshared(); return _dptr.get(); }
00311
00312 _D * get()
00313 { assertUnshared(); return _dptr.get(); }
00314
00315 public:
00316 bool unique() const
00317 { return _Traits().unique( _dptr ); }
00318
00319 long use_count() const
00320 { return _Traits().use_count( _dptr ); }
00321
00322 _constPtr getPtr() const
00323 { return _dptr; }
00324
00325 _Ptr getPtr()
00326 { assertUnshared(); return _dptr; }
00327
00328 private:
00329
00330 void assertUnshared()
00331 {
00332 if ( !unique() )
00333 _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
00334 }
00335
00336 private:
00337 _Ptr _dptr;
00338 };
00340
00346 template<class _D>
00347 inline _D * rwcowClone( const _D * rhs )
00348 { return rhs->clone(); }
00349
00351
00357 template<class _D, class _Ptr>
00358 inline std::ostream &
00359 operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
00360 {
00361 if ( obj.get() )
00362 return str << *obj.get();
00363 return str << std::string("NULL");
00364 }
00365
00367
00370
00371 }
00373
00375 #define DEFINE_PTR_TYPE(NAME) \
00376 class NAME; \
00377 extern void intrusive_ptr_add_ref( const NAME * ); \
00378 extern void intrusive_ptr_release( const NAME * ); \
00379 typedef zypp::intrusive_ptr<NAME> NAME##_Ptr; \
00380 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr;
00381
00383 #endif // ZYPP_BASE_PTRTYPES_H