libzypp  10.5.0
PtrTypes.h
Go to the documentation of this file.
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