yast2-core
Rep.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | |
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
8 | |
9 | core system |
10 | (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12 
13  File: Rep.h
14 
15  Author: Michael Andres <ma@suse.de>
16  Maintainer: Michael Andres <ma@suse.de>
17 
18  Purpose: Base class for reference counted objects and counted pointer templates.
19 
20 /-*/
21 #ifndef Rep_h
22 #define Rep_h
23 
24 #include <iosfwd>
25 
27 //
28 // CLASS NAME : Rep
46 class Rep {
47  private:
48 
52  mutable unsigned _counter;
53 
54  protected:
55 
59  virtual void ref_to( unsigned /* rep_cnt_r */ ) const {}
65  virtual void unref_to( unsigned /* rep_cnt_r */ ) const {}
66 
67  public:
68 
72  Rep() : _counter( 0 ) {}
76  Rep( const Rep & /* rhs */ ) : _counter( 0 ) {}
80  Rep & operator=( const Rep & /* rhs */ ) { return *this; }
84  virtual ~Rep() { if ( _counter ) throw( this ); }
85 
86  public:
87 
91  void ref() const {
92  ref_to( ++_counter ); // trigger derived classes
93  }
99  void unref() const {
100  if ( ! _counter )
101  throw( this );
102  if ( --_counter )
103  unref_to( _counter ); // trigger derived classes
104  else
105  delete this;
106  }
107 
112  static void ref( const Rep * obj_r ) {
113  if ( obj_r )
114  obj_r->ref();
115  }
120  static void unref( const Rep * obj_r ) {
121  if ( obj_r )
122  obj_r->unref();
123  }
124 
125  public:
126 
130  unsigned refCount() const { return _counter; }
131 
132  public:
133 
137  virtual const char * repName() const { return "Rep"; }
143  virtual std::ostream & dumpOn( std::ostream & str ) const;
144 };
145 
149 std::ostream & operator<<( std::ostream & str, const Rep & obj );
153 std::ostream & operator<<( std::ostream & str, const Rep * obj );
154 
156 
158 //
159 // CLASS NAME : CountedRep
167 class CountedRep : public Rep {
168 
169  private:
170 
174  static unsigned _objectCount;
178  static unsigned _objectIds;
179 
183  const unsigned _objectId;
184 
185  public:
186 
194  CountedRep( const CountedRep & rhs ) : Rep( rhs ), _objectId( ++_objectIds ) { ++_objectCount; }
198  CountedRep & operator=( const CountedRep & rhs ) {
199  Rep::operator=( rhs );
200  return *this;
201  }
205  virtual ~CountedRep() { --_objectCount; }
206 
207  public:
208 
212  unsigned objectId() const { return _objectId; }
213 
217  static unsigned objectCount() { return _objectCount; }
218 
219  public:
220 
224  virtual std::ostream & dumpOn( std::ostream & str ) const;
225 };
226 
228 
230 //
231 // Counted pointer
232 //
234 
236 //
237 // CLASS NAME : RepPtrStore<typename _Tp, typename _Bt>
269 template<typename _Tp, typename _Bt = _Tp>
270 class RepPtrStore {
271 
272  private:
273 
277  _Tp * _obj;
278 
279  private:
280 
285  void _assign( _Tp * new_r );
286 
287  public:
288 
292  RepPtrStore() : _obj( 0 ) {}
296  RepPtrStore( _Tp * ptr ) : _obj( 0 ) { _assign( ptr ); }
300  RepPtrStore( const RepPtrStore & rhs ) : _obj( 0 ) { _assign( rhs._obj ); }
301 
305  RepPtrStore & operator=( _Tp * ptr ) { _assign( ptr ); return *this; }
309  RepPtrStore & operator=( const RepPtrStore & rhs ) { _assign( rhs._obj ); return *this; }
310 
314  ~RepPtrStore() { _assign( 0 ); }
315 
319  operator _Tp *() const { return _obj; }
320 
321  public:
322 
326  void tryAssign( _Bt * ptr );
327 
328  public:
329 
333  _Bt * base() const;
337  const Rep * refbase() const;
338 };
339 
340 template<typename _Tp,typename _Bt>
341 void RepPtrStore<_Tp,_Bt>::_assign( _Tp * new_r ) {
342  if ( new_r != _obj ) {
343  Rep::unref( _obj );
344  _obj = new_r;
345  Rep::ref( _obj );
346  }
347 }
348 
349 template<typename _Tp,typename _Bt>
351  _assign( dynamic_cast<_Tp*>(ptr) );
352  if ( !_obj && ptr && ! ptr->refCount() ) {
353  Rep::ref( ptr );
354  Rep::unref( ptr );
355  }
356 }
357 
358 template<typename _Tp,typename _Bt>
359 _Bt * RepPtrStore<_Tp,_Bt>::base() const { return _obj; }
360 
361 template<typename _Tp,typename _Bt>
362 const Rep * RepPtrStore<_Tp,_Bt>::refbase() const { return _obj; }
363 
365 
367 //
368 // CLASS NAME : RepPtrBase
377 class RepPtrBase {
381  friend std::ostream & operator<<( std::ostream & str, const RepPtrBase & obj );
382 
383  protected:
384 
388  virtual ~RepPtrBase() {}
392  virtual const Rep * refbase() const = 0;
393 
394  public:
395 
400  operator const void *() const { return refbase(); }
401 };
402 
404 
405 template<typename _Bt> class constPtrBase;
406 
408 //
409 // CLASS NAME : PtrBase<typename _Bt>
415 template<typename _Bt>
416 class PtrBase : public RepPtrBase {
417 
418  protected:
419 
420  friend class constPtrBase<_Bt>;
421 
425  virtual _Bt * base() const = 0;
426 
430  _Bt * getBase( const PtrBase & rhs ) const {
431  return rhs.base();
432  }
433 };
434 
436 
438 //
439 // CLASS NAME : constPtrBase<typename _Bt>
445 template<typename _Bt>
446 class constPtrBase : public RepPtrBase {
447 
448  protected:
449 
453  virtual const _Bt * base() const = 0;
454 
458  const _Bt * getBase( const constPtrBase & rhs ) const {
459  return rhs.base();
460  }
461 
466  const _Bt * getBase( const PtrBase<_Bt> & rhs ) const {
467  return rhs.base();
468  }
469 };
470 
472 
473 template<typename _Tp,typename _Bt> class constPtr;
474 
476 //
477 // CLASS NAME : Ptr<typename _Tp, typename _Bt>
481 template<typename _Tp, typename _Bt = _Tp>
482 class Ptr : public PtrBase<_Bt> {
483 
484  private:
485 
490 
491  protected:
492 
496  virtual const Rep * refbase() const { return _ptr.refbase(); }
500  virtual _Bt * base() const { return _ptr.base(); }
501 
502  public:
503 
507  Ptr( _Tp * ptr = 0 ) : _ptr( ptr ) {}
511  Ptr( const Ptr & rhs ) : PtrBase<_Bt>( rhs ), _ptr( rhs._ptr ) {}
515  Ptr( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( this->getBase( rhs ) ); }
516 
517  public:
518 
522  Ptr & operator=( _Tp * ptr ) { _ptr = ptr; return *this; }
526  Ptr & operator=( const Ptr & rhs ) { _ptr = rhs._ptr; return *this; }
530  Ptr & operator=( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( this->getBase( rhs ) ); return *this; }
531 
532  public:
533 
537  _Tp * operator->() const { return _ptr; }
538 
542  _Tp & operator*() const { return *_ptr; }
543 
544  public:
545 
550  return const_cast<_Tp*>(rhs.operator->());
551  }
552 };
553 
555 
557 //
558 // CLASS NAME : constPtr<typename _Tp, typename _Bt>
562 template<typename _Tp, typename _Bt = _Tp>
563 class constPtr : public constPtrBase<_Bt> {
564 
565  private:
566 
571 
572  protected:
573 
577  virtual const Rep * refbase() const { return _ptr.refbase(); }
581  virtual const _Bt * base() const { return _ptr.base(); }
582 
583  public:
584 
588  constPtr( const _Tp * ptr = 0 ) : _ptr( ptr ) {}
592  constPtr( const constPtr & rhs ) : constPtrBase<_Bt>( rhs ), _ptr( rhs._ptr ) {}
596  constPtr( const constPtrBase<_Bt> & rhs ) { _ptr.tryAssign( this->getBase( rhs ) ); }
597 
598  public:
599 
603  constPtr & operator=( const _Tp * ptr ) { _ptr = ptr; return *this; }
607  constPtr & operator=( const constPtr & rhs ) { _ptr = rhs._ptr; return *this; }
611  constPtr & operator=( const constPtrBase<_Bt> & rhs ) { _ptr.tryAssign( this->getBase( rhs ) ); return *this; }
612 
613  public:
614 
618  constPtr( const Ptr<_Tp,_Bt> & rhs ) : _ptr( rhs.operator->() ) {}
622  constPtr( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( this->getBase( rhs ) ); }
623 
624  public:
625 
629  constPtr & operator=( const Ptr<_Tp,_Bt> & rhs ) { _ptr = rhs.operator->(); return *this; }
633  constPtr & operator=( const PtrBase<_Bt> & rhs ) { _ptr.tryAssign( this->getBase( rhs ) ); return *this; }
634 
635  public:
636 
640  const _Tp * operator->() const { return _ptr; }
644  const _Tp & operator*() const { return *_ptr; }
645 };
646 
648 
650 //
651 // CLASS NAME : VarPtr
652 //
654 
656 //
657 // CLASS NAME : BasicRepPtr
669 {
673  friend std::ostream &
674  operator<<( std::ostream & str, const BasicRepPtr & obj )
675  { return str << obj._ptr; }
676 
677  public:
681  operator const void *() const
682  { return _ptr; }
683 
684  protected:
689  : _ptr( NULL )
690  {}
691 
692  explicit
693  BasicRepPtr( Rep * ptr )
694  : _ptr( NULL )
695  { _assign( ptr ); }
696 
697  BasicRepPtr( const BasicRepPtr & rhs )
698  : _ptr( NULL )
699  { _assign( rhs._ptr ); }
700 
701  BasicRepPtr &
702  operator=( const BasicRepPtr & rhs )
703  { _assign( rhs._ptr ); return *this; }
704 
706  { _assign( NULL ); }
707 
711  Rep *
712  repPtr() const
713  { return _ptr; }
714 
715  private:
720 
725  void
726  _assign( Rep * new_r )
727  {
728  // Don't miss this test
729  if ( new_r != _ptr )
730  {
731  Rep::unref( _ptr );
732  _ptr = new_r;
733  Rep::ref( _ptr );
734  }
735  }
736 };
738 
739 
741 
743 //
744 // CLASS NAME : VarPtr
768 template<typename _Rep>
769  class VarPtr : public BasicRepPtr
770  {
771  public:
772 
777  : BasicRepPtr()
778  {}
779 
783  explicit
784  VarPtr( _Rep * ptr_r )
785  : BasicRepPtr( ptr_r )
786  {}
787 
788  public:
789 
790  _Rep *
792  { return ptr(); }
793 
794  const _Rep *
795  operator->() const
796  { return ptr(); }
797 
798  _Rep &
800  { return *ptr(); }
801 
802  const _Rep &
803  operator*() const
804  { return *ptr(); }
805 
806  private:
807 
808  _Rep *
809  ptr() const
810  { return static_cast<_Rep *>( BasicRepPtr::repPtr() ); }
811  };
813 
815 
819 template<typename _Rep>
820  inline VarPtr<_Rep>
821  makeVarPtr( _Rep * ptr )
822  { return VarPtr<_Rep>( ptr ); }
823 
825 
826 #endif // Rep_h

Generated on a sunny day for yast2-core by doxygen 1.8.2