3 #ifndef __CDS_GC_GUARDED_PTR_H
4 #define __CDS_GC_GUARDED_PTR_H
6 #include <cds/details/defs.h>
8 namespace cds { namespace gc {
12 A guarded pointer is a pair of the pointer and GC's guard.
13 Usually, it is used for returning a pointer to the item from an lock-free container.
14 The guard prevents the pointer to be early disposed (freed) by GC.
15 After destructing \p %guarded_ptr object the pointer can be automatically disposed (freed) at any time.
18 - \p GC - a garbage collector type like cds::gc::HP and any other from cds::gc namespace
19 - \p GuardedType - a type which the guard stores
20 - \p ValueType - a value type
21 - \p Cast - a functor for converting <tt>GuardedType*</tt> to <tt>ValueType*</tt>. Default is \p void (no casting).
23 For intrusive containers, \p GuardedType is the same as \p ValueType and no casting is needed.
24 In such case the \p %guarded_ptr is:
26 typedef cds::gc::guarded_ptr< cds::gc::HP, foo > intrusive_guarded_ptr;
29 For standard (non-intrusive) containers \p GuardedType is not the same as \p ValueType and casting is needed.
37 struct value_accessor {
38 std::string* operator()( foo* pFoo ) const
40 return &(pFoo->value);
45 typedef cds::gc::guarded_ptr< cds::gc::HP, Foo, std::string, value_accessor > nonintrusive_guarded_ptr;
48 Many set/map container classes from \p libcds declare the typedef for \p %guarded_ptr with appropriate casting functor.
50 template <class GC, typename GuardedType, typename ValueType=GuardedType, typename Cast=void >
53 //TODO: use moce semantics and explicit operator bool!
55 typedef GC gc ; ///< Garbage collector like cds::gc::HP and any other from cds::gc namespace
56 typedef GuardedType guarded_type; ///< Guarded type
57 typedef ValueType value_type ; ///< Value type
58 typedef Cast value_cast ; ///< Functor for casting \p guarded_type to \p value_type
62 typename gc::Guard m_guard;
66 /// Creates empty guarded pointer
67 guarded_ptr() CDS_NOEXCEPT
70 /// Initializes guarded pointer with \p p
71 guarded_ptr( guarded_type * p ) CDS_NOEXCEPT
77 guarded_ptr( guarded_ptr const& gp ) CDS_NOEXCEPT
79 m_guard.copy( gp.m_guard );
82 /// Clears the guarded pointer
84 \ref release is called if guarded pointer is not \ref empty
86 ~guarded_ptr() CDS_NOEXCEPT
91 /// Assignment operator
92 guarded_ptr& operator=( guarded_ptr const& gp ) CDS_NOEXCEPT
94 m_guard.copy( gp.m_guard );
98 /// Returns a pointer to guarded value
99 value_type * operator ->() const CDS_NOEXCEPT
101 return value_cast()( m_guard.template get<guarded_type>() );
104 /// Returns a reference to guarded value
105 value_type& operator *() CDS_NOEXCEPT
108 return *value_cast()( m_guard.template get<guarded_type>() );
111 /// Returns const reference to guarded value
112 value_type const& operator *() const CDS_NOEXCEPT
115 return *value_cast()( m_guard.template get<guarded_type>() );
118 /// Checks if the guarded pointer is \p nullptr
119 bool empty() const CDS_NOEXCEPT
121 return m_guard.template get<guarded_type>() == nullptr;
124 /// Clears guarded pointer
126 If the guarded pointer has been released, the pointer can be disposed (freed) at any time.
127 Dereferncing the guarded pointer after \p release() is dangerous.
129 void release() CDS_NOEXCEPT
135 // For internal use only!!!
136 typename gc::Guard& guard() CDS_NOEXCEPT
145 // Intrusive specialization
146 template <class GC, typename T>
147 class guarded_ptr< GC, T, T, void >
150 typedef GC gc ; ///< Garbage collector like cds::gc::HP
151 typedef T guarded_type; ///< Guarded type
152 typedef T value_type ; ///< Value type
155 typename gc::Guard m_guard;
158 guarded_ptr() CDS_NOEXCEPT
161 guarded_ptr( value_type * p ) CDS_NOEXCEPT
166 guarded_ptr( guarded_ptr const& gp ) CDS_NOEXCEPT
168 m_guard.copy( gp.m_guard );
171 ~guarded_ptr() CDS_NOEXCEPT
176 guarded_ptr& operator=( guarded_ptr const& gp ) CDS_NOEXCEPT
178 m_guard.copy( gp.m_guard );
182 value_type * operator ->() const CDS_NOEXCEPT
184 return m_guard.template get<value_type>();
187 value_type& operator *() CDS_NOEXCEPT
190 return *m_guard.template get<value_type>();
193 value_type const& operator *() const CDS_NOEXCEPT
196 return *m_guard.template get<value_type>();
199 bool empty() const CDS_NOEXCEPT
201 return m_guard.template get<guarded_type>() == nullptr;
204 void release() CDS_NOEXCEPT
209 typename gc::Guard& guard() CDS_NOEXCEPT
216 }} // namespace cds::gc
218 #endif // #ifndef __CDS_GC_GUARDED_PTR_H