libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 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 } // namespace zypp 00104 namespace std 00105 { 00106 00107 // namespace sub { 00108 // class Foo; 00109 // typedef zypp::intrusive_ptr<Foo> Foo_Ptr; // see DEFINE_PTR_TYPE(NAME) macro below 00110 // } 00111 00112 // Defined in namespace std g++ finds the output operator (König-Lookup), 00113 // even if we typedef the pointer in a different namespace than ::zypp. 00114 // Otherwise we had to define an output operator always in the same namespace 00115 // as the typedef (else g++ will just print the pointer value). 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 } 00126 template<class _D> 00127 inline std::ostream & dumpOn( std::ostream & str, const zypp::shared_ptr<_D> & obj ) 00128 { 00129 if ( obj ) 00130 return dumpOn( str, *obj ); 00131 return str << std::string("NULL"); 00132 } 00133 00135 template<class _D> 00136 inline std::ostream & operator<<( std::ostream & str, const zypp::intrusive_ptr<_D> & obj ) 00137 { 00138 if ( obj ) 00139 return str << *obj; 00140 return str << std::string("NULL"); 00141 } 00143 template<class _D> 00144 inline std::ostream & dumpOn( std::ostream & str, const zypp::intrusive_ptr<_D> & obj ) 00145 { 00146 if ( obj ) 00147 return dumpOn( str, *obj ); 00148 return str << std::string("NULL"); 00149 } 00151 } // namespace std 00154 namespace zypp 00155 { 00156 00158 // 00159 // RW_pointer traits 00160 // 00162 00167 namespace rw_pointer { 00168 00169 template<class _D> 00170 struct Shared 00171 { 00172 typedef shared_ptr<_D> _Ptr; 00173 typedef shared_ptr<const _D> _constPtr; 00175 bool unique( const _constPtr & ptr_r ) 00176 { return !ptr_r || ptr_r.unique(); } 00177 bool unique( const _Ptr & ptr_r ) 00178 { return !ptr_r || ptr_r.unique(); } 00180 long use_count( const _constPtr & ptr_r ) const 00181 { return ptr_r.use_count(); } 00182 long use_count( const _Ptr & ptr_r ) const 00183 { return ptr_r.use_count(); } 00184 }; 00185 00186 template<class _D> 00187 struct Intrusive 00188 { 00189 typedef intrusive_ptr<_D> _Ptr; 00190 typedef intrusive_ptr<const _D> _constPtr; 00192 bool unique( const _constPtr & ptr_r ) 00193 { return !ptr_r || (ptr_r->refCount() <= 1); } 00194 bool unique( const _Ptr & ptr_r ) 00195 { return !ptr_r || (ptr_r->refCount() <= 1); } 00197 long use_count( const _constPtr & ptr_r ) const 00198 { return ptr_r ? ptr_r->refCount() : 0; } 00199 long use_count( const _Ptr & ptr_r ) const 00200 { return ptr_r ? ptr_r->refCount() : 0; } 00201 }; 00202 00203 template<class _D> 00204 struct Scoped 00205 { 00206 typedef scoped_ptr<_D> _Ptr; 00207 typedef scoped_ptr<const _D> _constPtr; 00209 bool unique( const _constPtr & ptr_r ) 00210 { return true; } 00211 bool unique( const _Ptr & ptr_r ) 00212 { return true; } 00214 long use_count( const _constPtr & ptr_r ) const 00215 { return ptr_r ? 1 : 0; } 00216 long use_count( const _Ptr & ptr_r ) const 00217 { return ptr_r ? 1 : 0; } 00218 }; 00219 00220 } 00222 00224 // 00225 // CLASS NAME : RW_pointer 00226 // 00264 template<class _D, class _Traits = rw_pointer::Shared<_D> > 00265 struct RW_pointer 00266 { 00267 typedef typename _Traits::_Ptr _Ptr; 00268 typedef typename _Traits::_constPtr _constPtr; 00269 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type; 00270 00271 explicit 00272 RW_pointer( typename _Ptr::element_type * dptr = 0 ) 00273 : _dptr( dptr ) 00274 {} 00275 00276 explicit 00277 RW_pointer( _Ptr dptr ) 00278 : _dptr( dptr ) 00279 {} 00280 00281 void reset() 00282 { _Ptr().swap( _dptr ); } 00283 00284 void reset( typename _Ptr::element_type * dptr ) 00285 { _Ptr( dptr ).swap( _dptr ); } 00286 00287 void swap( RW_pointer & rhs ) 00288 { _dptr.swap( rhs._dptr ); } 00289 00290 void swap( _Ptr & rhs ) 00291 { _dptr.swap( rhs ); } 00292 00293 operator unspecified_bool_type() const 00294 { return _dptr; } 00295 00296 const _D & operator*() const 00297 { return *_dptr; }; 00298 00299 const _D * operator->() const 00300 { return _dptr.get(); } 00301 00302 const _D * get() const 00303 { return _dptr.get(); } 00304 00305 _D & operator*() 00306 { return *_dptr; } 00307 00308 _D * operator->() 00309 { return _dptr.get(); } 00310 00311 _D * get() 00312 { return _dptr.get(); } 00313 00314 public: 00315 bool unique() const 00316 { return _Traits().unique( _dptr ); } 00317 00318 long use_count() const 00319 { return _Traits().use_count( _dptr ); } 00320 00321 _constPtr getPtr() const 00322 { return _dptr; } 00323 00324 _Ptr getPtr() 00325 { return _dptr; } 00326 00327 _constPtr cgetPtr() 00328 { return _dptr; } 00329 00330 private: 00331 _Ptr _dptr; 00332 }; 00334 00340 template<class _D, class _Ptr> 00341 inline std::ostream & operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj ) 00342 { 00343 if ( obj.get() ) 00344 return str << *obj.get(); 00345 return str << std::string("NULL"); 00346 } 00347 00349 template<class _D, class _Ptr> 00350 inline bool operator==( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00351 { return( lhs.get() == rhs.get() ); } 00353 template<class _D, class _Ptr> 00354 inline bool operator==( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs ) 00355 { return( lhs.get() == rhs.get() ); } 00357 template<class _D, class _Ptr> 00358 inline bool operator==( const typename _Ptr::_Ptr & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00359 { return( lhs.get() == rhs.get() ); } 00361 template<class _D, class _Ptr> 00362 inline bool operator==( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs ) 00363 { return( lhs.get() == rhs.get() ); } 00365 template<class _D, class _Ptr> 00366 inline bool operator==( const typename _Ptr::_constPtr & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00367 { return( lhs.get() == rhs.get() ); } 00368 00369 00371 template<class _D, class _Ptr> 00372 inline bool operator!=( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00373 { return ! ( lhs == rhs ); } 00375 template<class _D, class _Ptr> 00376 inline bool operator!=( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs ) 00377 { return ! ( lhs == rhs ); } 00379 template<class _D, class _Ptr> 00380 inline bool operator!=( const typename _Ptr::_Ptr & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00381 { return ! ( lhs == rhs ); } 00383 template<class _D, class _Ptr> 00384 inline bool operator!=( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs ) 00385 { return ! ( lhs == rhs ); } 00387 template<class _D, class _Ptr> 00388 inline bool operator!=( const typename _Ptr::_constPtr & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00389 { return ! ( lhs == rhs ); } 00390 00392 00394 // 00395 // CLASS NAME : RWCOW_pointer 00396 // 00404 template<class _D, class _Traits = rw_pointer::Shared<_D> > 00405 struct RWCOW_pointer 00406 { 00407 typedef typename _Traits::_Ptr _Ptr; 00408 typedef typename _Traits::_constPtr _constPtr; 00409 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type; 00410 00411 explicit 00412 RWCOW_pointer( typename _Ptr::element_type * dptr = 0 ) 00413 : _dptr( dptr ) 00414 {} 00415 00416 explicit 00417 RWCOW_pointer( _Ptr dptr ) 00418 : _dptr( dptr ) 00419 {} 00420 00421 void reset() 00422 { _Ptr().swap( _dptr ); } 00423 00424 void reset( typename _Ptr::element_type * dptr ) 00425 { _Ptr( dptr ).swap( _dptr ); } 00426 00427 void swap( RWCOW_pointer & rhs ) 00428 { _dptr.swap( rhs._dptr ); } 00429 00430 void swap( _Ptr & rhs ) 00431 { _dptr.swap( rhs ); } 00432 00433 operator unspecified_bool_type() const 00434 { return _dptr; } 00435 00436 const _D & operator*() const 00437 { return *_dptr; }; 00438 00439 const _D * operator->() const 00440 { return _dptr.get(); } 00441 00442 const _D * get() const 00443 { return _dptr.get(); } 00444 00445 _D & operator*() 00446 { assertUnshared(); return *_dptr; } 00447 00448 _D * operator->() 00449 { assertUnshared(); return _dptr.get(); } 00450 00451 _D * get() 00452 { assertUnshared(); return _dptr.get(); } 00453 00454 public: 00455 bool unique() const 00456 { return _Traits().unique( _dptr ); } 00457 00458 long use_count() const 00459 { return _Traits().use_count( _dptr ); } 00460 00461 _constPtr getPtr() const 00462 { return _dptr; } 00463 00464 _Ptr getPtr() 00465 { assertUnshared(); return _dptr; } 00466 00467 _constPtr cgetPtr() 00468 { return _dptr; } 00469 00470 private: 00471 00472 void assertUnshared() 00473 { 00474 if ( !unique() ) 00475 _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr ); 00476 } 00477 00478 private: 00479 _Ptr _dptr; 00480 }; 00482 00488 template<class _D> 00489 inline _D * rwcowClone( const _D * rhs ) 00490 { return rhs->clone(); } 00491 00493 00499 template<class _D, class _Ptr> 00500 inline std::ostream & operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj ) 00501 { 00502 if ( obj.get() ) 00503 return str << *obj.get(); 00504 return str << std::string("NULL"); 00505 } 00506 00508 template<class _D, class _Ptr> 00509 inline bool operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00510 { return( lhs.get() == rhs.get() ); } 00512 template<class _D, class _Ptr> 00513 inline bool operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs ) 00514 { return( lhs.get() == rhs.get() ); } 00516 template<class _D, class _Ptr> 00517 inline bool operator==( const typename _Ptr::_Ptr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00518 { return( lhs.get() == rhs.get() ); } 00520 template<class _D, class _Ptr> 00521 inline bool operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs ) 00522 { return( lhs.get() == rhs.get() ); } 00524 template<class _D, class _Ptr> 00525 inline bool operator==( const typename _Ptr::_constPtr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00526 { return( lhs.get() == rhs.get() ); } 00527 00529 template<class _D, class _Ptr> 00530 inline bool operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00531 { return ! ( lhs == rhs ); } 00533 template<class _D, class _Ptr> 00534 inline bool operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs ) 00535 { return ! ( lhs == rhs ); } 00537 template<class _D, class _Ptr> 00538 inline bool operator!=( const typename _Ptr::_Ptr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00539 { return ! ( lhs == rhs ); } 00541 template<class _D, class _Ptr> 00542 inline bool operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs ) 00543 { return ! ( lhs == rhs ); } 00545 template<class _D, class _Ptr> 00546 inline bool operator!=( const typename _Ptr::_constPtr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00547 { return ! ( lhs == rhs ); } 00548 00550 00552 00553 } // namespace zypp 00555 00557 #define DEFINE_PTR_TYPE(NAME) \ 00558 class NAME; \ 00559 extern void intrusive_ptr_add_ref( const NAME * ); \ 00560 extern void intrusive_ptr_release( const NAME * ); \ 00561 typedef zypp::intrusive_ptr<NAME> NAME##_Ptr; \ 00562 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr; 00563 00565 #endif // ZYPP_BASE_PTRTYPES_H