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   }
00125 
00127   template<class _D>
00128   inline std::ostream & operator<<( std::ostream & str, const zypp::intrusive_ptr<_D> & obj )
00129   {
00130     if ( obj )
00131       return str << *obj;
00132     return str << std::string("NULL");
00133   }
00135 } // namespace std
00138 namespace zypp
00139 { 
00140 
00142     //
00143     //  RW_pointer traits
00144     //
00146 
00151     namespace rw_pointer {
00152 
00153       template<class _D>
00154         struct Shared
00155         {
00156           typedef shared_ptr<_D>       _Ptr;
00157           typedef shared_ptr<const _D> _constPtr;
00159           bool unique( const _constPtr & ptr_r )
00160           { return !ptr_r || ptr_r.unique(); }
00161           bool unique( const _Ptr & ptr_r )
00162           { return !ptr_r || ptr_r.unique(); }
00164           long use_count( const _constPtr & ptr_r ) const
00165           { return ptr_r.use_count(); }
00166           long use_count( const _Ptr & ptr_r ) const
00167           { return ptr_r.use_count(); }
00168         };
00169 
00170       template<class _D>
00171         struct Intrusive
00172         {
00173           typedef intrusive_ptr<_D>       _Ptr;
00174           typedef intrusive_ptr<const _D> _constPtr;
00176           bool unique( const _constPtr & ptr_r )
00177           { return !ptr_r || (ptr_r->refCount() <= 1); }
00178           bool unique( const _Ptr & ptr_r )
00179           { return !ptr_r || (ptr_r->refCount() <= 1); }
00181           long use_count( const _constPtr & ptr_r ) const
00182           { return ptr_r ? ptr_r->refCount() : 0; }
00183           long use_count( const _Ptr & ptr_r ) const
00184           { return ptr_r ? ptr_r->refCount() : 0; }
00185         };
00186 
00187        template<class _D>
00188         struct Scoped
00189         {
00190           typedef scoped_ptr<_D>       _Ptr;
00191           typedef scoped_ptr<const _D> _constPtr;
00193           bool unique( const _constPtr & ptr_r )
00194           { return true; }
00195           bool unique( const _Ptr & ptr_r )
00196           { return true; }
00198           long use_count( const _constPtr & ptr_r ) const
00199           { return ptr_r ? 1 : 0; }
00200           long use_count( const _Ptr & ptr_r ) const
00201           { return ptr_r ? 1 : 0; }
00202         };
00203 
00204    }
00206 
00208     //
00209     //  CLASS NAME : RW_pointer
00210     //
00248     template<class _D, class _Traits = rw_pointer::Shared<_D> >
00249       struct RW_pointer
00250       {
00251         typedef typename _Traits::_Ptr               _Ptr;
00252         typedef typename _Traits::_constPtr          _constPtr;
00253         typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00254 
00255         explicit
00256         RW_pointer( typename _Ptr::element_type * dptr = 0 )
00257         : _dptr( dptr )
00258         {}
00259 
00260         explicit
00261         RW_pointer( _Ptr dptr )
00262         : _dptr( dptr )
00263         {}
00264 
00265         void reset()
00266         { _Ptr().swap( _dptr ); }
00267 
00268         void reset( typename _Ptr::element_type * dptr )
00269         { _Ptr( dptr ).swap( _dptr ); }
00270 
00271         void swap( RW_pointer & rhs )
00272         { _dptr.swap( rhs._dptr ); }
00273 
00274         void swap( _Ptr & rhs )
00275         { _dptr.swap( rhs ); }
00276 
00277         operator unspecified_bool_type() const
00278         { return _dptr; }
00279 
00280         const _D & operator*() const
00281         { return *_dptr; };
00282 
00283         const _D * operator->() const
00284         { return _dptr.get(); }
00285 
00286         const _D * get() const
00287         { return _dptr.get(); }
00288 
00289         _D & operator*()
00290         { return *_dptr; }
00291 
00292         _D * operator->()
00293         { return _dptr.get(); }
00294 
00295         _D * get()
00296         { return _dptr.get(); }
00297 
00298       public:
00299         bool unique() const
00300         { return _Traits().unique( _dptr ); }
00301 
00302         long use_count() const
00303         { return _Traits().use_count( _dptr ); }
00304 
00305         _constPtr getPtr() const
00306         { return _dptr; }
00307 
00308         _Ptr getPtr()
00309         { return _dptr; }
00310 
00311       private:
00312         _Ptr _dptr;
00313       };
00315 
00321     template<class _D, class _Ptr>
00322       inline std::ostream &
00323       operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
00324       {
00325         if ( obj.get() )
00326           return str << *obj.get();
00327         return str << std::string("NULL");
00328       }
00329 
00331     template<class _D, class _Ptr>
00332       inline bool
00333       operator==( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
00334       {
00335         return( lhs.get() == rhs.get() );
00336       }
00337 
00339     template<class _D, class _Ptr>
00340       inline bool
00341       operator!=( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
00342       {
00343         return ! ( lhs == rhs );
00344       }
00345 
00347 
00349     //
00350     //  CLASS NAME : RWCOW_pointer
00351     //
00359     template<class _D, class _Traits = rw_pointer::Shared<_D> >
00360       struct RWCOW_pointer
00361       {
00362         typedef typename _Traits::_Ptr               _Ptr;
00363         typedef typename _Traits::_constPtr          _constPtr;
00364         typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
00365 
00366         explicit
00367         RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
00368         : _dptr( dptr )
00369         {}
00370 
00371         explicit
00372         RWCOW_pointer( _Ptr dptr )
00373         : _dptr( dptr )
00374         {}
00375 
00376         void reset()
00377         { _Ptr().swap( _dptr ); }
00378 
00379         void reset( typename _Ptr::element_type * dptr )
00380         { _Ptr( dptr ).swap( _dptr ); }
00381 
00382         void swap( RWCOW_pointer & rhs )
00383         { _dptr.swap( rhs._dptr ); }
00384 
00385         void swap( _Ptr & rhs )
00386         { _dptr.swap( rhs ); }
00387 
00388         operator unspecified_bool_type() const
00389         { return _dptr; }
00390 
00391         const _D & operator*() const
00392         { return *_dptr; };
00393 
00394         const _D * operator->() const
00395         { return _dptr.get(); }
00396 
00397         const _D * get() const
00398         { return _dptr.get(); }
00399 
00400         _D & operator*()
00401         { assertUnshared(); return *_dptr; }
00402 
00403         _D * operator->()
00404         { assertUnshared(); return _dptr.get(); }
00405 
00406         _D * get()
00407         { assertUnshared(); return _dptr.get(); }
00408 
00409       public:
00410         bool unique() const
00411         { return _Traits().unique( _dptr ); }
00412 
00413         long use_count() const
00414         { return _Traits().use_count( _dptr ); }
00415 
00416         _constPtr getPtr() const
00417         { return _dptr; }
00418 
00419         _Ptr getPtr()
00420         { assertUnshared(); return _dptr; }
00421 
00422       private:
00423 
00424         void assertUnshared()
00425         {
00426           if ( !unique() )
00427             _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
00428         }
00429 
00430       private:
00431         _Ptr _dptr;
00432       };
00434 
00440     template<class _D>
00441       inline _D * rwcowClone( const _D * rhs )
00442       { return rhs->clone(); }
00443 
00445 
00451     template<class _D, class _Ptr>
00452       inline std::ostream &
00453       operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
00454       {
00455         if ( obj.get() )
00456           return str << *obj.get();
00457         return str << std::string("NULL");
00458       }
00459 
00461     template<class _D, class _Ptr>
00462       inline bool
00463       operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
00464       {
00465         return( lhs.get() == rhs.get() );
00466       }
00467 
00469     template<class _D, class _Ptr>
00470       inline bool
00471       operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
00472       {
00473         return ! ( lhs == rhs );
00474       }
00475 
00477 
00479 
00480 } // namespace zypp
00482 
00484 #define DEFINE_PTR_TYPE(NAME) \
00485 class NAME;                                                      \
00486 extern void intrusive_ptr_add_ref( const NAME * );               \
00487 extern void intrusive_ptr_release( const NAME * );               \
00488 typedef zypp::intrusive_ptr<NAME>       NAME##_Ptr;        \
00489 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr;
00490 
00492 #endif // ZYPP_BASE_PTRTYPES_H

Generated on Tue Sep 25 19:22:59 2007 for libzypp by  doxygen 1.5.3