1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/ReferenceCounted.h
12 #ifndef ZYPP_BASE_REFERENCECOUNTED_H
13 #define ZYPP_BASE_REFERENCECOUNTED_H
17 #include "zypp/base/PtrTypes.h"
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////
28 // CLASS NAME : ReferenceCounted
30 /** Base class for reference counted objects.
31 * \todo Make counter thread safe.
33 class ReferenceCounted
35 /** Stream output via dumpOn. */
36 friend std::ostream & operator<<( std::ostream & str, const ReferenceCounted & obj );
40 * Initial reference count is zero.
45 * Initial reference count is zero.
47 ReferenceCounted( const ReferenceCounted & rhs );
50 * \throw std::out_of_range if reference count is not zero.
52 virtual ~ReferenceCounted();
55 * Reference count remains untouched.
57 ReferenceCounted & operator=( const ReferenceCounted & )
61 /** Return reference counter value. */
62 unsigned refCount() const
65 /** Add a reference. */
67 { ref_to( ++_counter ); }
69 /** Release a reference.
70 * Deletes the object if reference count gets zero.
71 * \throw std::out_of_range if reference count is zero.
76 unrefException(); // will throw!
83 /** Called by zypp::intrusive_ptr to add a reference.
86 static void add_ref( const ReferenceCounted * ptr_r )
87 { if( ptr_r ) ptr_r->ref(); }
89 /** Called by zypp::intrusive_ptr to add a reference.
92 static void release( const ReferenceCounted * ptr_r )
93 { if( ptr_r ) ptr_r->unref(); }
96 /** Overload to realize std::ostream & operator\<\<. */
97 virtual std::ostream & dumpOn( std::ostream & str ) const;
99 /** Trigger derived classes after refCount was increased. */
100 virtual void ref_to( unsigned /* rep_cnt_r */ ) const {}
102 /** Trigger derived classes after refCount was decreased.
103 * No trigger is sent, if refCount got zero (i.e. the
104 * object is deleted).
106 virtual void unref_to( unsigned /* rep_cnt_r */ ) const {}
109 /** The reference counter. */
110 mutable unsigned _counter;
112 /** Throws Exception on unref. */
113 void unrefException() const;
115 ///////////////////////////////////////////////////////////////////
117 /** \relates ReferenceCounted intrusive_ptr hook to add_ref. */
118 inline void intrusive_ptr_add_ref( const ReferenceCounted * ptr_r )
119 { ReferenceCounted::add_ref( ptr_r ); }
121 /** \relates ReferenceCounted intrusive_ptr hook to release. */
122 inline void intrusive_ptr_release( const ReferenceCounted * ptr_r )
123 { ReferenceCounted::release( ptr_r ); }
125 /** \relates ReferenceCounted Stream output. */
126 inline std::ostream & operator<<( std::ostream & str, const ReferenceCounted & obj )
127 { return obj.dumpOn( str ); }
129 /////////////////////////////////////////////////////////////////
131 ///////////////////////////////////////////////////////////////////
132 /////////////////////////////////////////////////////////////////
134 ///////////////////////////////////////////////////////////////////
136 #define IMPL_PTR_TYPE(NAME) \
137 void intrusive_ptr_add_ref( const NAME * ptr_r ) \
138 { zypp::base::ReferenceCounted::add_ref( ptr_r ); } \
139 void intrusive_ptr_release( const NAME * ptr_r ) \
140 { zypp::base::ReferenceCounted::release( ptr_r ); }
142 ///////////////////////////////////////////////////////////////////
143 #endif // ZYPP_BASE_REFERENCECOUNTED_H