libzypp 8.13.6
|
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 private: 00328 _Ptr _dptr; 00329 }; 00331 00337 template<class _D, class _Ptr> 00338 inline std::ostream & 00339 operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj ) 00340 { 00341 if ( obj.get() ) 00342 return str << *obj.get(); 00343 return str << std::string("NULL"); 00344 } 00345 00347 template<class _D, class _Ptr> 00348 inline bool 00349 operator==( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00350 { 00351 return( lhs.get() == rhs.get() ); 00352 } 00353 00355 template<class _D, class _Ptr> 00356 inline bool 00357 operator!=( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs ) 00358 { 00359 return ! ( lhs == rhs ); 00360 } 00361 00363 00365 // 00366 // CLASS NAME : RWCOW_pointer 00367 // 00375 template<class _D, class _Traits = rw_pointer::Shared<_D> > 00376 struct RWCOW_pointer 00377 { 00378 typedef typename _Traits::_Ptr _Ptr; 00379 typedef typename _Traits::_constPtr _constPtr; 00380 typedef typename _Ptr::unspecified_bool_type unspecified_bool_type; 00381 00382 explicit 00383 RWCOW_pointer( typename _Ptr::element_type * dptr = 0 ) 00384 : _dptr( dptr ) 00385 {} 00386 00387 explicit 00388 RWCOW_pointer( _Ptr dptr ) 00389 : _dptr( dptr ) 00390 {} 00391 00392 void reset() 00393 { _Ptr().swap( _dptr ); } 00394 00395 void reset( typename _Ptr::element_type * dptr ) 00396 { _Ptr( dptr ).swap( _dptr ); } 00397 00398 void swap( RWCOW_pointer & rhs ) 00399 { _dptr.swap( rhs._dptr ); } 00400 00401 void swap( _Ptr & rhs ) 00402 { _dptr.swap( rhs ); } 00403 00404 operator unspecified_bool_type() const 00405 { return _dptr; } 00406 00407 const _D & operator*() const 00408 { return *_dptr; }; 00409 00410 const _D * operator->() const 00411 { return _dptr.get(); } 00412 00413 const _D * get() const 00414 { return _dptr.get(); } 00415 00416 _D & operator*() 00417 { assertUnshared(); return *_dptr; } 00418 00419 _D * operator->() 00420 { assertUnshared(); return _dptr.get(); } 00421 00422 _D * get() 00423 { assertUnshared(); return _dptr.get(); } 00424 00425 public: 00426 bool unique() const 00427 { return _Traits().unique( _dptr ); } 00428 00429 long use_count() const 00430 { return _Traits().use_count( _dptr ); } 00431 00432 _constPtr getPtr() const 00433 { return _dptr; } 00434 00435 _Ptr getPtr() 00436 { assertUnshared(); return _dptr; } 00437 00438 private: 00439 00440 void assertUnshared() 00441 { 00442 if ( !unique() ) 00443 _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr ); 00444 } 00445 00446 private: 00447 _Ptr _dptr; 00448 }; 00450 00456 template<class _D> 00457 inline _D * rwcowClone( const _D * rhs ) 00458 { return rhs->clone(); } 00459 00461 00467 template<class _D, class _Ptr> 00468 inline std::ostream & 00469 operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj ) 00470 { 00471 if ( obj.get() ) 00472 return str << *obj.get(); 00473 return str << std::string("NULL"); 00474 } 00475 00477 template<class _D, class _Ptr> 00478 inline bool 00479 operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00480 { 00481 return( lhs.get() == rhs.get() ); 00482 } 00483 00485 template<class _D, class _Ptr> 00486 inline bool 00487 operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs ) 00488 { 00489 return ! ( lhs == rhs ); 00490 } 00491 00493 00495 00496 } // namespace zypp 00498 00500 #define DEFINE_PTR_TYPE(NAME) \ 00501 class NAME; \ 00502 extern void intrusive_ptr_add_ref( const NAME * ); \ 00503 extern void intrusive_ptr_release( const NAME * ); \ 00504 typedef zypp::intrusive_ptr<NAME> NAME##_Ptr; \ 00505 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr; 00506 00508 #endif // ZYPP_BASE_PTRTYPES_H