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 }
00104 namespace std
00105 {
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00118 template<class _D>
00119 inline std::ostream & operator<<( std::ostream & str, const zypp::shared_ptr<_D> & obj )
00120 {
00121 if ( obj )
00122 return str << *obj;
00123 return str << std::string("NULL");
00124 }
00125
00127 template<class _D>
00128 inline std::ostream & operator<<( std::ostream & str, const zypp::intrusive_ptr<_D> & obj )
00129 {
00130 if ( obj )
00131 return str << *obj;
00132 return str << std::string("NULL");
00133 }
00135 }
00138 namespace zypp
00139 {
00140
00142
00143
00144
00146
00151 namespace rw_pointer {
00152
00153 template<class _D>
00154 struct Shared
00155 {
00156 typedef shared_ptr<_D> _Ptr;
00157 typedef shared_ptr<const _D> _constPtr;
00159 bool unique( const _constPtr & ptr_r )
00160 { return !ptr_r || ptr_r.unique(); }
00161 bool unique( const _Ptr & ptr_r )
00162 { return !ptr_r || ptr_r.unique(); }
00164 long use_count( const _constPtr & ptr_r ) const
00165 { return ptr_r.use_count(); }
00166 long use_count( const _Ptr & ptr_r ) const
00167 { return ptr_r.use_count(); }
00168 };
00169
00170 template<class _D>
00171 struct Intrusive
00172 {
00173 typedef intrusive_ptr<_D> _Ptr;
00174 typedef intrusive_ptr<const _D> _constPtr;
00176 bool unique( const _constPtr & ptr_r )
00177 { return !ptr_r || (ptr_r->refCount() <= 1); }
00178 bool unique( const _Ptr & ptr_r )
00179 { return !ptr_r || (ptr_r->refCount() <= 1); }
00181 long use_count( const _constPtr & ptr_r ) const
00182 { return ptr_r ? ptr_r->refCount() : 0; }
00183 long use_count( const _Ptr & ptr_r ) const
00184 { return ptr_r ? ptr_r->refCount() : 0; }
00185 };
00186
00187 template<class _D>
00188 struct Scoped
00189 {
00190 typedef scoped_ptr<_D> _Ptr;
00191 typedef scoped_ptr<const _D> _constPtr;
00193 bool unique( const _constPtr & ptr_r )
00194 { return true; }
00195 bool unique( const _Ptr & ptr_r )
00196 { return true; }
00198 long use_count( const _constPtr & ptr_r ) const
00199 { return ptr_r ? 1 : 0; }
00200 long use_count( const _Ptr & ptr_r ) const
00201 { return ptr_r ? 1 : 0; }
00202 };
00203
00204 }
00206
00208
00209
00210
00248 template<class _D, class _Traits = rw_pointer::Shared<_D> >
00249 struct RW_pointer
00250 {
00251 typedef typename _Traits::_Ptr _Ptr;
00252 typedef typename _Traits::_constPtr _constPtr;
00253 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00254
00255 explicit
00256 RW_pointer( typename _Ptr::element_type * dptr = 0 )
00257 : _dptr( dptr )
00258 {}
00259
00260 explicit
00261 RW_pointer( _Ptr dptr )
00262 : _dptr( dptr )
00263 {}
00264
00265 void reset()
00266 { _Ptr().swap( _dptr ); }
00267
00268 void reset( typename _Ptr::element_type * dptr )
00269 { _Ptr( dptr ).swap( _dptr ); }
00270
00271 void swap( RW_pointer & rhs )
00272 { _dptr.swap( rhs._dptr ); }
00273
00274 void swap( _Ptr & rhs )
00275 { _dptr.swap( rhs ); }
00276
00277 operator unspecified_bool_type() const
00278 { return _dptr; }
00279
00280 const _D & operator*() const
00281 { return *_dptr; };
00282
00283 const _D * operator->() const
00284 { return _dptr.get(); }
00285
00286 const _D * get() const
00287 { return _dptr.get(); }
00288
00289 _D & operator*()
00290 { return *_dptr; }
00291
00292 _D * operator->()
00293 { return _dptr.get(); }
00294
00295 _D * get()
00296 { return _dptr.get(); }
00297
00298 public:
00299 bool unique() const
00300 { return _Traits().unique( _dptr ); }
00301
00302 long use_count() const
00303 { return _Traits().use_count( _dptr ); }
00304
00305 _constPtr getPtr() const
00306 { return _dptr; }
00307
00308 _Ptr getPtr()
00309 { return _dptr; }
00310
00311 private:
00312 _Ptr _dptr;
00313 };
00315
00321 template<class _D, class _Ptr>
00322 inline std::ostream &
00323 operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
00324 {
00325 if ( obj.get() )
00326 return str << *obj.get();
00327 return str << std::string("NULL");
00328 }
00329
00331 template<class _D, class _Ptr>
00332 inline bool
00333 operator==( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
00334 {
00335 return( lhs.get() == rhs.get() );
00336 }
00337
00339 template<class _D, class _Ptr>
00340 inline bool
00341 operator!=( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
00342 {
00343 return ! ( lhs == rhs );
00344 }
00345
00347
00349
00350
00351
00359 template<class _D, class _Traits = rw_pointer::Shared<_D> >
00360 struct RWCOW_pointer
00361 {
00362 typedef typename _Traits::_Ptr _Ptr;
00363 typedef typename _Traits::_constPtr _constPtr;
00364 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00365
00366 explicit
00367 RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
00368 : _dptr( dptr )
00369 {}
00370
00371 explicit
00372 RWCOW_pointer( _Ptr dptr )
00373 : _dptr( dptr )
00374 {}
00375
00376 void reset()
00377 { _Ptr().swap( _dptr ); }
00378
00379 void reset( typename _Ptr::element_type * dptr )
00380 { _Ptr( dptr ).swap( _dptr ); }
00381
00382 void swap( RWCOW_pointer & rhs )
00383 { _dptr.swap( rhs._dptr ); }
00384
00385 void swap( _Ptr & rhs )
00386 { _dptr.swap( rhs ); }
00387
00388 operator unspecified_bool_type() const
00389 { return _dptr; }
00390
00391 const _D & operator*() const
00392 { return *_dptr; };
00393
00394 const _D * operator->() const
00395 { return _dptr.get(); }
00396
00397 const _D * get() const
00398 { return _dptr.get(); }
00399
00400 _D & operator*()
00401 { assertUnshared(); return *_dptr; }
00402
00403 _D * operator->()
00404 { assertUnshared(); return _dptr.get(); }
00405
00406 _D * get()
00407 { assertUnshared(); return _dptr.get(); }
00408
00409 public:
00410 bool unique() const
00411 { return _Traits().unique( _dptr ); }
00412
00413 long use_count() const
00414 { return _Traits().use_count( _dptr ); }
00415
00416 _constPtr getPtr() const
00417 { return _dptr; }
00418
00419 _Ptr getPtr()
00420 { assertUnshared(); return _dptr; }
00421
00422 private:
00423
00424 void assertUnshared()
00425 {
00426 if ( !unique() )
00427 _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
00428 }
00429
00430 private:
00431 _Ptr _dptr;
00432 };
00434
00440 template<class _D>
00441 inline _D * rwcowClone( const _D * rhs )
00442 { return rhs->clone(); }
00443
00445
00451 template<class _D, class _Ptr>
00452 inline std::ostream &
00453 operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
00454 {
00455 if ( obj.get() )
00456 return str << *obj.get();
00457 return str << std::string("NULL");
00458 }
00459
00461 template<class _D, class _Ptr>
00462 inline bool
00463 operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
00464 {
00465 return( lhs.get() == rhs.get() );
00466 }
00467
00469 template<class _D, class _Ptr>
00470 inline bool
00471 operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
00472 {
00473 return ! ( lhs == rhs );
00474 }
00475
00477
00479
00480 }
00482
00484 #define DEFINE_PTR_TYPE(NAME) \
00485 class NAME; \
00486 extern void intrusive_ptr_add_ref( const NAME * ); \
00487 extern void intrusive_ptr_release( const NAME * ); \
00488 typedef zypp::intrusive_ptr<NAME> NAME##_Ptr; \
00489 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr;
00490
00492 #endif // ZYPP_BASE_PTRTYPES_H