Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

Rep.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                                        (C) SuSE GmbH |
00011 \----------------------------------------------------------------------/
00012 
00013    File:       Rep.h
00014 
00015    Author:     Michael Andres <ma@suse.de>
00016    Maintainer: Michael Andres <ma@suse.de>
00017 
00018    Purpose: Base class for reference counted objects and counted pointer templates.
00019 
00020 /-*/
00021 #ifndef Rep_h
00022 #define Rep_h
00023 
00024 #include <iosfwd>
00025 
00027 //
00028 //      CLASS NAME : Rep
00046 class Rep {
00047   private:
00048 
00052     mutable unsigned _counter;
00053 
00054   protected:
00055 
00059     virtual void ref_to( unsigned rep_cnt_r ) const {}
00065     virtual void unref_to( unsigned rep_cnt_r ) const {}
00066 
00067   public:
00068 
00072     Rep() : _counter( 0 ) {}
00076     Rep( const Rep & rhs ) : _counter( 0 ) {}
00080     Rep & operator=( const Rep & rhs ) { return *this; }
00084     virtual ~Rep() { if ( _counter ) throw( this ); }
00085 
00086   public:
00087 
00091     void ref() const {
00092       ref_to( ++_counter ); // trigger derived classes
00093     }
00099     void unref() const {
00100       if ( ! _counter )
00101         throw( this );
00102       if ( --_counter )
00103         unref_to( _counter ); // trigger derived classes
00104       else
00105         delete this;
00106     }
00107 
00112     static void ref( const Rep * obj_r ) {
00113       if ( obj_r )
00114         obj_r->ref();
00115     }
00120     static void unref( const Rep * obj_r ) {
00121       if ( obj_r )
00122         obj_r->unref();
00123     }
00124 
00125   public:
00126 
00130     unsigned refCount() const { return _counter; }
00131 
00132   public:
00133 
00137     virtual const char * repName() const { return "Rep"; }
00143     virtual std::ostream & dumpOn( std::ostream & str ) const;
00144 };
00145 
00149 std::ostream & operator<<( std::ostream & str, const Rep & obj );
00153 std::ostream & operator<<( std::ostream & str, const Rep * obj );
00154 
00156 
00158 //
00159 //      CLASS NAME : CountedRep
00167 class CountedRep : public Rep {
00168 
00169   private:
00170 
00174     static unsigned _objectCount;
00178     static unsigned _objectIds;
00179 
00183     const unsigned _objectId;
00184 
00185   public:
00186 
00190     CountedRep() : _objectId( ++_objectIds ) { ++_objectCount; }
00194     CountedRep( const CountedRep & rhs ) : _objectId( ++_objectIds ) { ++_objectCount; }
00198     CountedRep & operator=( const CountedRep & rhs ) {
00199       Rep::operator=( rhs );
00200       return *this;
00201     }
00205     virtual ~CountedRep() { --_objectCount; }
00206 
00207   public:
00208 
00212     unsigned objectId() const { return _objectId; }
00213 
00217     static unsigned objectCount() { return _objectCount; }
00218 
00219   public:
00220 
00224     virtual std::ostream & dumpOn( std::ostream & str ) const;
00225 };
00226 
00228 
00230 //
00231 // Counted pointer
00232 //
00234 
00236 //
00237 //      CLASS NAME : RepPtrStore<typename _Tp, typename _Bt>
00269 template<typename _Tp, typename _Bt = _Tp>
00270 class RepPtrStore {
00271 
00272   private:
00273 
00277     _Tp * _obj;
00278 
00279   private:
00280 
00285     void _assign( _Tp * new_r );
00286 
00287   public:
00288 
00292     RepPtrStore() : _obj( 0 ) {}
00296     RepPtrStore( _Tp * ptr ) : _obj( 0 ) { _assign( ptr ); }
00300     RepPtrStore( const RepPtrStore & rhs ) : _obj( 0 ) { _assign( rhs._obj ); }
00301 
00305     RepPtrStore & operator=( _Tp * ptr ) { _assign( ptr ); return *this; }
00309     RepPtrStore & operator=( const RepPtrStore & rhs ) { _assign( rhs._obj ); return *this; }
00310 
00314     ~RepPtrStore() { _assign( 0 ); }
00315 
00319     operator _Tp *() const { return _obj; }
00320 
00321   public:
00322 
00326     void tryAssign( _Bt * ptr );
00327 
00328   public:
00329 
00333     _Bt * base() const;
00337     const Rep * refbase() const;
00338 };
00339 
00340 template<typename _Tp,typename _Bt>
00341 void RepPtrStore<_Tp,_Bt>::_assign( _Tp * new_r ) {
00342   if ( new_r != _obj ) {
00343     Rep::unref( _obj );
00344     _obj = new_r;
00345     Rep::ref( _obj );
00346   }
00347 }
00348 
00349 template<typename _Tp,typename _Bt>
00350 void RepPtrStore<_Tp,_Bt>::tryAssign( _Bt * ptr ) {
00351   _assign( dynamic_cast<_Tp*>(ptr) );
00352   if ( !_obj && ptr && ! ptr->refCount() ) {
00353     Rep::ref( ptr );
00354     Rep::unref( ptr );
00355   }
00356 }
00357 
00358 template<typename _Tp,typename _Bt>
00359 _Bt * RepPtrStore<_Tp,_Bt>::base() const { return _obj; }
00360 
00361 template<typename _Tp,typename _Bt>
00362 const Rep * RepPtrStore<_Tp,_Bt>::refbase() const { return _obj; }
00363 
00365 
00367 //
00368 //      CLASS NAME : RepPtrBase
00377 class RepPtrBase {
00381   friend std::ostream & operator<<( std::ostream & str, const RepPtrBase & obj );
00382 
00383   protected:
00384 
00388     virtual ~RepPtrBase() {}
00392     virtual const Rep * refbase() const = 0;
00393 
00394   public:
00395 
00400     operator const void *() const  { return refbase(); }
00401 };
00402 
00404 
00405 template<typename _Bt> class constPtrBase;
00406 
00408 //
00409 //      CLASS NAME : PtrBase<typename _Bt>
00415 template<typename _Bt>
00416 class PtrBase : public RepPtrBase {
00417 
00418   protected:
00419 
00420     friend class constPtrBase<_Bt>;
00421 
00425     virtual _Bt * base() const = 0;
00426 
00430     _Bt * getBase( const PtrBase & rhs ) const {
00431       return rhs.base();
00432     }
00433 };
00434 
00436 
00438 //
00439 //      CLASS NAME : constPtrBase<typename _Bt>
00445 template<typename _Bt>
00446 class constPtrBase : public RepPtrBase {
00447 
00448   protected:
00449 
00453     virtual const _Bt * base() const = 0;
00454 
00458     const _Bt * getBase( const constPtrBase & rhs ) const {
00459       return rhs.base();
00460     }
00461 
00466     const _Bt * getBase( const PtrBase<_Bt> & rhs ) const {
00467       return rhs.base();
00468     }
00469 };
00470 
00472 
00473 template<typename _Tp,typename _Bt> class constPtr;
00474 
00476 //
00477 //      CLASS NAME : Ptr<typename _Tp, typename _Bt>
00481 template<typename _Tp, typename _Bt = _Tp>
00482 class Ptr : public PtrBase<_Bt> {
00483 
00484   private:
00485 
00489     RepPtrStore<_Tp,_Bt> _ptr;
00490 
00491   protected:
00492 
00496     virtual const Rep * refbase() const { return _ptr.refbase(); }
00500     virtual _Bt * base() const { return _ptr.base(); }
00501 
00502   public:
00503 
00507     Ptr( _Tp * ptr = 0 ) : _ptr( ptr ) {}
00511     Ptr( const Ptr & rhs ) : _ptr( rhs._ptr ) {}
00515     Ptr( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( getBase( rhs ) ); }
00516 
00517   public:
00518 
00522     Ptr & operator=( _Tp * ptr ) { _ptr = ptr; return *this; }
00526     Ptr & operator=( const Ptr & rhs ) { _ptr = rhs._ptr; return *this; }
00530     Ptr & operator=( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( getBase( rhs ) ); return *this; }
00531 
00532   public:
00533 
00537     _Tp * operator->() const { return _ptr; }
00538 
00539   public:
00540 
00544     static Ptr cast_away_const( constPtr<_Tp,_Bt> rhs ) {
00545       return const_cast<_Tp*>(rhs.operator->());
00546     }
00547 };
00548 
00550 
00552 //
00553 //      CLASS NAME : constPtr<typename _Tp, typename _Bt>
00557 template<typename _Tp, typename _Bt = _Tp>
00558 class constPtr : public constPtrBase<_Bt> {
00559 
00560   private:
00561 
00565     RepPtrStore<const _Tp,const _Bt> _ptr;
00566 
00567   protected:
00568 
00572     virtual const Rep * refbase() const { return _ptr.refbase(); }
00576     virtual const _Bt * base() const { return _ptr.base(); }
00577 
00578   public:
00579 
00583     constPtr( const _Tp * ptr = 0 ) : _ptr( ptr ) {}
00587     constPtr( const constPtr & rhs ) : _ptr( rhs._ptr ) {}
00591     constPtr( const constPtrBase<_Bt> & rhs ) { _ptr.tryAssign( getBase( rhs ) ); }
00592 
00593   public:
00594 
00598     constPtr & operator=( const _Tp * ptr ) { _ptr = ptr; return *this; }
00602     constPtr & operator=( const constPtr & rhs ) { _ptr = rhs._ptr; return *this; }
00606     constPtr & operator=( const constPtrBase<_Bt> & rhs ) { _ptr.tryAssign( getBase( rhs ) ); return *this; }
00607 
00608   public:
00609 
00613     constPtr( const Ptr<_Tp,_Bt> & rhs ) : _ptr( rhs.operator->() ) {}
00617     constPtr( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( getBase( rhs ) ); }
00618 
00619   public:
00620 
00624     constPtr & operator=( const Ptr<_Tp,_Bt> & rhs ) { _ptr = rhs.operator->(); return *this; }
00628     constPtr & operator=( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( getBase( rhs ) ); return *this; }
00629 
00630   public:
00631 
00635     const _Tp * operator->() const { return _ptr; }
00636 };
00637 
00639 
00640 #endif // Rep_h

Generated on Thu Feb 23 23:56:10 2006 for liby2util by doxygen 1.3.6