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 - implemntation-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.
167 assert( !rcu::is_locked() );
174 /// Adapter \p raw_ptr for non-intrusive containers based on intrusive counterpart
180 class raw_ptr_adaptor: private RawPtr
183 typedef RawPtr intrusive_raw_ptr;
184 typedef ValueType value_type;
185 typedef typename intrusive_raw_ptr::value_type node_type;
186 typedef Converter converter_type;
189 /// Constructs an empty raw pointer
191 : intrusive_raw_ptr()
195 raw_ptr_adaptor( intrusive_raw_ptr&& p )
196 : intrusive_raw_ptr( std::move(p))
200 raw_ptr_adaptor( raw_ptr_adaptor&& p )
201 : intrusive_raw_ptr( std::move(p))
204 /// Copy ctor is prohibited
205 raw_ptr_adaptor( raw_ptr_adaptor const& ) = delete;
207 /// Releases the raw pointer
214 /// Move assignment operator
216 This operator may be called only inside RCU-lock.
217 The \p this should be empty.
219 In general, move assignment is intented for internal use.
221 raw_ptr_adaptor& operator=( raw_ptr_adaptor&& p ) CDS_NOEXCEPT
223 intrusive_raw_ptr::operator =(std::move(p));
227 /// Copy assignment is prohibited
228 raw_ptr_adaptor& operator=( raw_ptr_adaptor const& ) = delete;
230 /// Returns a pointer to stored value
231 value_type * operator ->() const CDS_NOEXCEPT
233 return converter_type()( intrusive_raw_ptr::operator->());
236 /// Returns a reference to stored value
237 value_type& operator *()
239 return converter_type()( intrusive_raw_ptr::operator*());
242 /// Returns a reference to stored value
243 value_type const& operator *() const
245 return converter_type()( intrusive_raw_ptr::operator*());
248 /// Checks if the \p %raw_ptr is \p nullptr
249 bool empty() const CDS_NOEXCEPT
251 return intrusive_raw_ptr::empty();
254 /// Checks if the \p %raw_ptr is not empty
255 explicit operator bool() const CDS_NOEXCEPT
260 /// Releases the \p %raw_ptr object
262 This function may be called only outside RCU section.
263 After \p %release() the object can be reused.
267 intrusive_raw_ptr::release();
272 }} // namespace cds::urcu
274 #endif // #ifndef CDSLIB_URCU_RAW_PTR_H