PtrTypes.h
Go to the documentation of this file.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 }
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 }
00154 namespace zypp
00155 {
00156
00158
00159
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
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
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 }
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