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       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

doxygen