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 \p 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
71 /// Initializes guarded pointer with \p p
72 guarded_ptr( guarded_type * p ) CDS_NOEXCEPT
76 guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT
81 guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT
83 m_guard.assign( gp.m_guard.get_native() );
87 /// The guarded pointer is not copy-constructible
88 guarded_ptr( guarded_ptr const& gp ) = delete;
90 /// Clears the guarded pointer
92 \ref release is called if guarded pointer is not \ref empty
94 ~guarded_ptr() CDS_NOEXCEPT
99 /// Move-assignment operator
100 guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT
102 m_guard.assign( gp.m_guard.get_native() );
107 /// The guarded pointer is not copy-assignable
108 guarded_ptr& operator=(guarded_ptr const& gp) = delete;
110 /// Returns a pointer to guarded value
111 value_type * operator ->() const CDS_NOEXCEPT
113 return value_cast()( m_guard.template get<guarded_type>() );
116 /// Returns a reference to guarded value
117 value_type& operator *() CDS_NOEXCEPT
120 return *value_cast()( m_guard.template get<guarded_type>() );
123 /// Returns const reference to guarded value
124 value_type const& operator *() const CDS_NOEXCEPT
127 return *value_cast()( m_guard.template get<guarded_type>() );
130 /// Checks if the guarded pointer is \p nullptr
131 bool empty() const CDS_NOEXCEPT
133 return m_guard.template get<guarded_type>() == nullptr;
136 /// \p bool operator returns <tt>!empty()</tt>
137 explicit operator bool() const CDS_NOEXCEPT
142 /// Clears guarded pointer
144 If the guarded pointer has been released, the pointer can be disposed (freed) at any time.
145 Dereferncing the guarded pointer after \p release() is dangerous.
147 void release() CDS_NOEXCEPT
153 // For internal use only!!!
154 typename gc::Guard& guard() CDS_NOEXCEPT
163 // Intrusive specialization
164 template <class GC, typename T>
165 class guarded_ptr< GC, T, T, void >
168 typedef GC gc ; ///< Garbage collector like cds::gc::HP
169 typedef T guarded_type; ///< Guarded type
170 typedef T value_type ; ///< Value type
173 typename gc::Guard m_guard;
176 guarded_ptr() CDS_NOEXCEPT
179 guarded_ptr( value_type * p ) CDS_NOEXCEPT
184 guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT
186 m_guard.assign( gp.m_guard.get_native() );
190 guarded_ptr( guarded_ptr const& gp ) = delete;
192 ~guarded_ptr() CDS_NOEXCEPT
197 guarded_ptr& operator=(guarded_ptr&& gp) CDS_NOEXCEPT
199 m_guard.assign( gp.m_guard.get_native() );
204 guarded_ptr& operator=(guarded_ptr const& gp) = delete;
206 value_type * operator ->() const CDS_NOEXCEPT
208 return m_guard.template get<value_type>();
211 value_type& operator *() CDS_NOEXCEPT
214 return *m_guard.template get<value_type>();
217 value_type const& operator *() const CDS_NOEXCEPT
220 return *m_guard.template get<value_type>();
223 bool empty() const CDS_NOEXCEPT
225 return m_guard.template get<guarded_type>() == nullptr;
228 explicit operator bool() const CDS_NOEXCEPT
233 void release() CDS_NOEXCEPT
238 typename gc::Guard& guard() CDS_NOEXCEPT
245 }} // namespace cds::gc
247 #endif // #ifndef __CDS_GC_GUARDED_PTR_H