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
00075 struct NullDeleter
00076 {
00077 void operator()( const void *const ) const
00078 {}
00079 };
00080
00082 using boost::scoped_ptr;
00083
00085 using boost::shared_ptr;
00086
00088 using boost::weak_ptr;
00089
00091 using boost::intrusive_ptr;
00092
00094 using boost::static_pointer_cast;
00096 using boost::const_pointer_cast;
00098 using boost::dynamic_pointer_cast;
00099
00101 template<class _D>
00102 inline std::ostream &
00103 operator<<( std::ostream & str, const shared_ptr<_D> & obj )
00104 {
00105 if ( obj )
00106 return str << *obj;
00107 return str << std::string("NULL");
00108 }
00109
00111 template<class _D>
00112 inline std::ostream &
00113 operator<<( std::ostream & str, const intrusive_ptr<_D> & obj )
00114 {
00115 if ( obj )
00116 return str << *obj;
00117 return str << std::string("NULL");
00118 }
00119
00121
00122
00123
00125
00130 namespace rw_pointer {
00131
00132 template<class _D>
00133 struct Shared
00134 {
00135 typedef shared_ptr<_D> _Ptr;
00136 typedef shared_ptr<const _D> _constPtr;
00138 bool unique( const _constPtr & ptr_r )
00139 { return !ptr_r || ptr_r.unique(); }
00140 bool unique( const _Ptr & ptr_r )
00141 { return !ptr_r || ptr_r.unique(); }
00143 long use_count( const _constPtr & ptr_r ) const
00144 { return ptr_r.use_count(); }
00145 long use_count( const _Ptr & ptr_r ) const
00146 { return ptr_r.use_count(); }
00147 };
00148
00149 template<class _D>
00150 struct Intrusive
00151 {
00152 typedef intrusive_ptr<_D> _Ptr;
00153 typedef intrusive_ptr<const _D> _constPtr;
00155 bool unique( const _constPtr & ptr_r )
00156 { return !ptr_r || (ptr_r->refCount() <= 1); }
00157 bool unique( const _Ptr & ptr_r )
00158 { return !ptr_r || (ptr_r->refCount() <= 1); }
00160 long use_count( const _constPtr & ptr_r ) const
00161 { return ptr_r ? ptr_r->refCount() : 0; }
00162 long use_count( const _Ptr & ptr_r ) const
00163 { return ptr_r ? ptr_r->refCount() : 0; }
00164 };
00165 }
00167
00169
00170
00171
00209 template<class _D, class _Traits = rw_pointer::Shared<_D> >
00210 struct RW_pointer
00211 {
00212 typedef typename _Traits::_Ptr _Ptr;
00213 typedef typename _Traits::_constPtr _constPtr;
00214 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00215
00216 explicit
00217 RW_pointer( typename _Ptr::element_type * dptr = 0 )
00218 : _dptr( dptr )
00219 {}
00220
00221 explicit
00222 RW_pointer( _Ptr dptr )
00223 : _dptr( dptr )
00224 {}
00225
00226 void reset()
00227 { _Ptr().swap( _dptr ); }
00228
00229 void reset( typename _Ptr::element_type * dptr )
00230 { _Ptr( dptr ).swap( _dptr ); }
00231
00232 void swap( RW_pointer & rhs )
00233 { _dptr.swap( rhs._dptr ); }
00234
00235 void swap( _Ptr & rhs )
00236 { _dptr.swap( rhs ); }
00237
00238 operator unspecified_bool_type() const
00239 { return _dptr; }
00240
00241 const _D & operator*() const
00242 { return *_dptr; };
00243
00244 const _D * operator->() const
00245 { return _dptr.get(); }
00246
00247 const _D * get() const
00248 { return _dptr.get(); }
00249
00250 _D & operator*()
00251 { return *_dptr; }
00252
00253 _D * operator->()
00254 { return _dptr.get(); }
00255
00256 _D * get()
00257 { return _dptr.get(); }
00258
00259 public:
00260 bool unique() const
00261 { return _Traits().unique( _dptr ); }
00262
00263 long use_count() const
00264 { return _Traits().use_count( _dptr ); }
00265
00266 _constPtr getPtr() const
00267 { return _dptr; }
00268
00269 _Ptr getPtr()
00270 { return _dptr; }
00271
00272 private:
00273 _Ptr _dptr;
00274 };
00276
00282 template<class _D, class _Ptr>
00283 inline std::ostream &
00284 operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
00285 {
00286 if ( obj.get() )
00287 return str << *obj.get();
00288 return str << std::string("NULL");
00289 }
00290
00292
00294
00295
00296
00304 template<class _D, class _Traits = rw_pointer::Shared<_D> >
00305 struct RWCOW_pointer
00306 {
00307 typedef typename _Traits::_Ptr _Ptr;
00308 typedef typename _Traits::_constPtr _constPtr;
00309 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00310
00311 explicit
00312 RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
00313 : _dptr( dptr )
00314 {}
00315
00316 explicit
00317 RWCOW_pointer( _Ptr dptr )
00318 : _dptr( dptr )
00319 {}
00320
00321 void reset()
00322 { _Ptr().swap( _dptr ); }
00323
00324 void reset( typename _Ptr::element_type * dptr )
00325 { _Ptr( dptr ).swap( _dptr ); }
00326
00327 void swap( RWCOW_pointer & rhs )
00328 { _dptr.swap( rhs._dptr ); }
00329
00330 void swap( _Ptr & rhs )
00331 { _dptr.swap( rhs ); }
00332
00333 operator unspecified_bool_type() const
00334 { return _dptr; }
00335
00336 const _D & operator*() const
00337 { return *_dptr; };
00338
00339 const _D * operator->() const
00340 { return _dptr.get(); }
00341
00342 const _D * get() const
00343 { return _dptr.get(); }
00344
00345 _D & operator*()
00346 { assertUnshared(); return *_dptr; }
00347
00348 _D * operator->()
00349 { assertUnshared(); return _dptr.get(); }
00350
00351 _D * get()
00352 { assertUnshared(); return _dptr.get(); }
00353
00354 public:
00355 bool unique() const
00356 { return _Traits().unique( _dptr ); }
00357
00358 long use_count() const
00359 { return _Traits().use_count( _dptr ); }
00360
00361 _constPtr getPtr() const
00362 { return _dptr; }
00363
00364 _Ptr getPtr()
00365 { assertUnshared(); return _dptr; }
00366
00367 private:
00368
00369 void assertUnshared()
00370 {
00371 if ( !unique() )
00372 _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
00373 }
00374
00375 private:
00376 _Ptr _dptr;
00377 };
00379
00385 template<class _D>
00386 inline _D * rwcowClone( const _D * rhs )
00387 { return rhs->clone(); }
00388
00390
00396 template<class _D, class _Ptr>
00397 inline std::ostream &
00398 operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
00399 {
00400 if ( obj.get() )
00401 return str << *obj.get();
00402 return str << std::string("NULL");
00403 }
00404
00406
00409
00410 }
00412
00414 #define DEFINE_PTR_TYPE(NAME) \
00415 class NAME; \
00416 extern void intrusive_ptr_add_ref( const NAME * ); \
00417 extern void intrusive_ptr_release( const NAME * ); \
00418 typedef zypp::intrusive_ptr<NAME> NAME##_Ptr; \
00419 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr;
00420
00422 #endif // ZYPP_BASE_PTRTYPES_H