3 #ifndef CDSLIB_URCU_RAW_PTR_H
4 #define CDSLIB_URCU_RAW_PTR_H
6 #include <utility> // std::move
8 #include <cds/details/defs.h>
10 namespace cds { namespace urcu {
12 /// Raw pointer to node of RCU-based container
14 This class is intented for returning a pointer to node of RCU-based container.
15 The objects of \p %raw_ptr class is returned by functions like \p get() of that containers.
16 Those functions must be called only under RCU-lock, otherwise the node returned can be reclaimed.
17 On the other hand, traversing the container can remove a lot of nodes marked as deleted ones.
18 Since RCU is locked, such nodes cannot be reclaimed immediately and must be retired only
21 The object of \p %raw_ptr solves that problem: it contains the pointer to the node found
22 and a chain of nodes that be reclaimed during traversing. The \p %raw_ptr object destructor
23 frees the chain (but not the node found) passing it to RCU \p batch_retire().
25 The object of \p %raw_ptr class must be destructed only outside RCU-lock of current thread.
27 Usually, you do not need to use \p %raw_ptr class directly. Each RCU container declares
28 a \p %raw_ptr typedef suitable for the container.
31 - \p RCU - one of \ref cds_urcu_gc "RCU type"
32 - \p ValueType - type of values stored in container
33 - \p ReclaimedEnumerator - implementation-defined for each type of container
35 Example: let \p Container is an RCU container
40 typename Container::raw_ptr pRaw;
44 typename Container::rcu_lock l;
50 // Release outside RCU-lock
57 typename ReclaimedEnumerator
62 typedef RCU rcu; ///< RCU type - one of <tt>cds::urcu::gc< ... ></tt>
63 typedef ValueType value_type; ///< Value type pointed by \p %raw_ptr
64 typedef ReclaimedEnumerator reclaimed_enumerator; ///< implementation-defined, for internal use only
68 value_type * m_ptr; ///< pointer to node
69 reclaimed_enumerator m_Enum; ///< reclaimed node enumerator
73 /// Constructs an empty raw pointer
79 raw_ptr( raw_ptr&& p )
81 , m_Enum(std::move( p.m_Enum ))
86 /// Copy ctor is prohibited
87 raw_ptr( raw_ptr const& ) = delete;
90 // Only for internal use
91 raw_ptr( value_type * p, reclaimed_enumerator&& e )
93 , m_Enum(std::move( e ))
95 raw_ptr( reclaimed_enumerator&& e )
97 , m_Enum(std::move( e ))
101 /// Releases the raw pointer
108 /// Move assignment operator
110 This operator may be called only inside RCU-lock.
111 The \p this should be empty.
113 In general, move assignment is intented for internal use.
115 raw_ptr& operator=( raw_ptr&& p ) CDS_NOEXCEPT
120 m_Enum = std::move( p.m_Enum );
125 /// Copy assignment is prohibited
126 raw_ptr& operator=( raw_ptr const& ) = delete;
128 /// Returns a pointer to stored value
129 value_type * operator ->() const CDS_NOEXCEPT
134 /// Returns a reference to stored value
135 value_type& operator *()
137 assert( m_ptr != nullptr );
141 /// Returns a reference to stored value
142 value_type const& operator *() const
144 assert( m_ptr != nullptr );
148 /// Checks if the \p %raw_ptr is \p nullptr
149 bool empty() const CDS_NOEXCEPT
151 return m_ptr == nullptr;
154 /// Checks if the \p %raw_ptr is not empty
155 explicit operator bool() const CDS_NOEXCEPT
160 /// Releases the \p %raw_ptr object
162 This function may be called only outside RCU section.
163 After \p %release() the object can be reused.
173 // Adapter of \p raw_ptr for non-intrusive containers based on intrusive counterpart
179 class raw_ptr_adaptor: private RawPtr
182 typedef RawPtr intrusive_raw_ptr;
183 typedef ValueType value_type;
184 typedef typename intrusive_raw_ptr::value_type node_type;
185 typedef Converter converter_type;
188 // Constructs an empty raw pointer
190 : intrusive_raw_ptr()
194 raw_ptr_adaptor( intrusive_raw_ptr&& p )
195 : intrusive_raw_ptr( std::move(p))
199 raw_ptr_adaptor( raw_ptr_adaptor&& p )
200 : intrusive_raw_ptr( std::move(p))
203 // Copy ctor is prohibited
204 raw_ptr_adaptor( raw_ptr_adaptor const& ) = delete;
206 // Releases the raw pointer
213 // Move assignment operator
215 This operator may be called only inside RCU-lock.
216 The \p this should be empty.
218 In general, move assignment is intented for internal use.
220 raw_ptr_adaptor& operator=( raw_ptr_adaptor&& p ) CDS_NOEXCEPT
222 intrusive_raw_ptr::operator =(std::move(p));
226 // Copy assignment is prohibited
227 raw_ptr_adaptor& operator=( raw_ptr_adaptor const& ) = delete;
229 // Returns a pointer to stored value
230 value_type * operator ->() const CDS_NOEXCEPT
232 return converter_type()( intrusive_raw_ptr::operator->());
235 // Returns a reference to stored value
236 value_type& operator *()
238 return converter_type()( intrusive_raw_ptr::operator*());
241 // Returns a reference to stored value
242 value_type const& operator *() const
244 return converter_type()( intrusive_raw_ptr::operator*());
247 // Checks if the \p %raw_ptr is \p nullptr
248 bool empty() const CDS_NOEXCEPT
250 return intrusive_raw_ptr::empty();
253 // Checks if the \p %raw_ptr is not empty
254 explicit operator bool() const CDS_NOEXCEPT
259 // Releases the \p %raw_ptr object
261 This function may be called only outside RCU section.
262 After \p %release() the object can be reused.
266 intrusive_raw_ptr::release();
271 }} // namespace cds::urcu
273 #endif // #ifndef CDSLIB_URCU_RAW_PTR_H