Salome HOME
Update comments
[modules/gui.git] / src / SUIT / SUIT_SmartPtr.h
1 #if !defined(__SUIT_SMARTPTR_H)
2 #define __SUIT_SMARTPTR_H
3
4 #include "SUIT.h"
5
6 /*! \brief Base counter class what children using in SmartPtr class how template */
7 class SUIT_EXPORT RefCount {
8 public:
9   //! constructor
10   RefCount() : crefs( 0 ) {}
11   //! copy constructor 
12   RefCount( const RefCount& ) : crefs( 0 ) {}
13   //! destructor
14   virtual ~RefCount() {}
15   //! operator= (does not change counter)
16   RefCount& operator=( const RefCount& ) { return *this; }
17
18   //! increments reference counter
19   void upcount() { 
20     ++crefs; 
21   }
22
23   //! decrements reference counter
24   void downcount()
25   {
26     if ( crefs > 0 && --crefs == 0 )
27       delete this;
28   }
29   
30   //! get reference counter value
31   int refcount() const { return crefs; }
32
33 private:
34   unsigned long crefs;   //!< reference counter
35 };
36
37 /*! \brief Template class that provides automatic casting for hold RefCount based objects.*/
38 template <class T> class SmartPtr {
39 public:
40   //! default constructor
41   SmartPtr() : p( 0 ) {}
42   //! constructor from any RefCount-based class
43   template<class Y> SmartPtr( Y* y_ ) { p = dynamic_cast<T*>( y_ ); if ( p ) p->upcount(); }
44   //! copy constructor from any RefCount-based class
45   template<class Y> SmartPtr( const SmartPtr<Y>& y_ ) { p = dynamic_cast<T*>( y_.get() ); if ( p ) p->upcount(); }
46   //! copy constructor
47   SmartPtr( const SmartPtr& t_ ) : p( t_.p ) { if ( p ) p->upcount();   }
48   //! destructor
49   virtual ~SmartPtr(void)     
50   { 
51     if ( p )
52       p->downcount(); 
53   }
54
55   // getting access
56   T& operator*() const        { return *p;           }//!< return *pointer
57   T* operator->() const       { return  p;           }//!< return pointer
58   operator T*() const         { return  p;           }//!< return pointer
59   T* get() const              { return  p;           }//!< return pointer
60
61   //! assignment
62   template<class Y> SmartPtr& operator=( const SmartPtr<Y>& y_ ) 
63   { 
64     if ( this == &y_) return *this;
65     return operator=( y_.get() );
66   }
67   //! assignment
68   SmartPtr& operator=( const SmartPtr& t_ )
69   { 
70     if ( this == &t_) return *this;
71     return operator=( t_.get() ); 
72   }
73   //!< assignment
74   SmartPtr& operator=( T* p_ )
75   {
76     if ( p )
77       p->downcount(); 
78     p = p_; 
79     if ( p )
80       p->upcount(); 
81     return *this;
82   }
83   
84   // comparing
85   int operator==( const SmartPtr& t_ ) { return p == t_.p; }//!< comparing
86   int operator==( const T* p_ )           { return p == p_; }//!< comparing
87   friend int operator==( const T* p_, const SmartPtr& t_ ) { return t_ == p_; }//!< comparing
88   int operator!=( SmartPtr& t_ ) { return p != t_.p; }//!< comparing
89   int operator!=( T* p_ )           { return p != p_; }//!< comparing
90   friend int operator!=( T* p_, SmartPtr& t_ ) { return p_ != t_.p; }//!< comparing
91
92   //! nullify
93   void nullify() { if ( p ) p->downcount(); p = 0; }
94   //! check for null
95   bool isNull() const { return p == 0; }
96
97 private:
98   T* p;//!< stored pointer
99 };
100
101 /*! \def SMART( C )
102  * Define macros SMART( C ) - same as SmartPtr(C), where \a C - class object.
103  */
104 #define SMART( C ) SmartPtr<C>
105 //! casting class T2 to class T1
106 template <class T1, class T2> SMART(T1) downcast( SMART(T2)& t ) 
107 {
108   return SMART(T1)(t.get());
109 }
110
111 #endif // __SUIT_SMARTPTR_H