fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / libcds-2.3.2 / cds / urcu / raw_ptr.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSLIB_URCU_RAW_PTR_H
32 #define CDSLIB_URCU_RAW_PTR_H
33
34 #include <utility> // std::move
35 #include <type_traits>
36 #include <cds/details/defs.h>
37
38 namespace cds { namespace urcu {
39
40     /// Raw pointer to node of RCU-based container
41     /**
42         This class is intented for returning a pointer to node of RCU-based container.
43         The objects of \p %raw_ptr class is returned by functions like \p get() of that containers.
44         Those functions must be called only under RCU-lock, otherwise the node returned can be reclaimed.
45         On the other hand, traversing the container can remove a lot of nodes marked as deleted ones.
46         Since RCU is locked, such nodes cannot be reclaimed immediately and must be retired only
47         outside RCU lock.
48
49         The object of \p %raw_ptr solves that problem: it contains the pointer to the node found
50         and a chain of nodes that were be reclaimed during traversing. The \p %raw_ptr object destructor
51         frees the chain (but not the node found) passing it to RCU \p batch_retire().
52
53         The object of \p %raw_ptr class must be destructed only outside RCU-lock of current thread.
54
55         Usually, you do not need to use \p %raw_ptr class directly. Each RCU container declares
56         a \p %raw_ptr typedef suitable for the container.
57
58         Template arguments:
59         - \p RCU - one of \ref cds_urcu_gc "RCU type"
60         - \p ValueType - type of values stored in container
61         - \p ReclaimedEnumerator - implementation-defined for each type of container
62
63         Example: let \p Container is an RCU container
64         @code
65             Container c;
66             // ...
67             // Find a key
68             typename Container::raw_ptr pRaw;
69
70             // RCU locked section
71             {
72                 typename Container::rcu_lock l;
73                 pRaw = c.get( key );
74                 if ( pRaw ) {
75                     // Deal with pRaw
76                 }
77             }
78             // Release outside RCU-lock
79             pRaw.release();
80         @endcode
81     */
82     template <
83         class RCU,
84         typename ValueType,
85         typename ReclaimedEnumerator
86     >
87     class raw_ptr
88     {
89     public:
90         typedef RCU rcu;    ///< RCU type - one of <tt>cds::urcu::gc< ... ></tt>
91         typedef ValueType   value_type; ///< Value type pointed by \p %raw_ptr
92         typedef ReclaimedEnumerator reclaimed_enumerator; ///< implementation-defined, for internal use only
93
94     private:
95         //@cond
96         value_type *            m_ptr;  ///< pointer to node
97         reclaimed_enumerator    m_Enum; ///< reclaimed node enumerator
98         //@endcond
99
100     public:
101         /// Constructs an empty raw pointer
102         raw_ptr()
103             : m_ptr( nullptr )
104         {}
105
106         /// Move ctor
107         raw_ptr( raw_ptr&& p )
108             : m_ptr( p.m_ptr )
109             , m_Enum(std::move( p.m_Enum ))
110         {
111             p.m_ptr = nullptr;
112         }
113
114         /// Copy ctor is prohibited
115         raw_ptr( raw_ptr const& ) = delete;
116
117         //@cond
118         // Only for internal use
119         raw_ptr( value_type * p, reclaimed_enumerator&& e )
120             : m_ptr( p )
121             , m_Enum(std::move( e ))
122         {}
123         raw_ptr( reclaimed_enumerator&& e )
124             : m_ptr( nullptr )
125             , m_Enum(std::move( e ))
126         {}
127         //@endcond
128
129         /// Releases the raw pointer
130         ~raw_ptr()
131         {
132             release();
133         }
134
135     public:
136         /// Move assignment operator
137         /**
138             This operator may be called only inside RCU-lock.
139         */
140         raw_ptr& operator=( raw_ptr&& p ) noexcept
141         {
142             assert( rcu::is_locked());
143             m_ptr = p.m_ptr;
144             m_Enum.combine(  std::move( p.m_Enum ));
145             p.m_ptr = nullptr;
146             return *this;
147         }
148
149         /// Copy assignment is prohibited
150         raw_ptr& operator=( raw_ptr const& ) = delete;
151
152         /// Returns a pointer to stored value
153         value_type * operator ->() const noexcept
154         {
155             return m_ptr;
156         }
157
158         /// Returns a reference to stored value
159         value_type& operator *()
160         {
161             assert( m_ptr != nullptr );
162             return *m_ptr;
163         }
164
165         /// Returns a reference to stored value
166         value_type const& operator *() const
167         {
168             assert( m_ptr != nullptr );
169             return *m_ptr;
170         }
171
172         /// Checks if the \p %raw_ptr is \p nullptr
173         bool empty() const noexcept
174         {
175             return m_ptr == nullptr;
176         }
177
178         /// Checks if the \p %raw_ptr is not empty
179         explicit operator bool() const noexcept
180         {
181             return !empty();
182         }
183
184         /// Releases the \p %raw_ptr object
185         /**
186             This function may be called only outside RCU locked region.
187             After \p %release() the object becomes empty and can be reused.
188         */
189         void release()
190         {
191             m_Enum.apply();
192             m_ptr = nullptr;
193         }
194     };
195
196     //@cond
197     // Adapter of \p raw_ptr for non-intrusive containers based on intrusive counterpart
198     template <
199         typename ValueType,
200         typename RawPtr,
201         typename Converter
202     >
203     class raw_ptr_adaptor: private RawPtr
204     {
205     public:
206         typedef RawPtr      intrusive_raw_ptr;
207         typedef ValueType   value_type;
208         typedef typename intrusive_raw_ptr::value_type node_type;
209         typedef Converter   converter_type;
210
211     public:
212         // Constructs an empty raw pointer
213         raw_ptr_adaptor()
214             : intrusive_raw_ptr()
215         {}
216
217         // Move ctor
218         raw_ptr_adaptor( intrusive_raw_ptr&& p )
219             : intrusive_raw_ptr( std::move(p))
220         {}
221
222         // Move ctor
223         raw_ptr_adaptor( raw_ptr_adaptor&& p )
224             : intrusive_raw_ptr( std::move(p))
225         {}
226
227         // Copy ctor is prohibited
228         raw_ptr_adaptor( raw_ptr_adaptor const& ) = delete;
229
230         // Releases the raw pointer
231         ~raw_ptr_adaptor()
232         {
233             release();
234         }
235
236     public:
237         // Move assignment operator
238         /*
239             This operator may be called only inside RCU-lock.
240             The \p this should be empty.
241
242             In general, move assignment is intented for internal use.
243         */
244         raw_ptr_adaptor& operator=( raw_ptr_adaptor&& p ) noexcept
245         {
246             intrusive_raw_ptr::operator =(std::move(p));
247             return *this;
248         }
249
250         // Copy assignment is prohibited
251         raw_ptr_adaptor& operator=( raw_ptr_adaptor const& ) = delete;
252
253         // Returns a pointer to stored value
254         value_type * operator ->() const noexcept
255         {
256             return converter_type()( intrusive_raw_ptr::operator->());
257         }
258
259         // Returns a reference to stored value
260         value_type& operator *()
261         {
262             return converter_type()( intrusive_raw_ptr::operator*());
263         }
264
265         // Returns a reference to stored value
266         value_type const& operator *() const
267         {
268             return converter_type()( intrusive_raw_ptr::operator*());
269         }
270
271         // Checks if the \p %raw_ptr is \p nullptr
272         bool empty() const noexcept
273         {
274             return intrusive_raw_ptr::empty();
275         }
276
277         // Checks if the \p %raw_ptr is not empty
278         explicit operator bool() const noexcept
279         {
280             return !empty();
281         }
282
283         // Releases the \p %raw_ptr object
284         /*
285             This function may be called only outside RCU section.
286             After \p %release() the object can be reused.
287         */
288         void release()
289         {
290             intrusive_raw_ptr::release();
291         }
292     };
293     //@endcond
294
295 }} // namespace cds::urcu
296
297 #endif // #ifndef CDSLIB_URCU_RAW_PTR_H