]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/interprocess/include/boost/interprocess/smart_ptr/detail/shared_count.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / interprocess / include / boost / interprocess / smart_ptr / detail / shared_count.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // This file is the adaptation for Interprocess of boost/detail/shared_count.hpp
4 //
5 // (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003
6 // (C) Copyright Peter Dimov 2004-2005
7 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
8 // Software License, Version 1.0. (See accompanying file
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // See http://www.boost.org/libs/interprocess for documentation.
12 //
13 //////////////////////////////////////////////////////////////////////////////
14 #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
15 #define BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
16
17 #ifndef BOOST_CONFIG_HPP
18 # include <boost/config.hpp>
19 #endif
20 #
21 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 # pragma once
23 #endif
24
25 #include <boost/interprocess/detail/config_begin.hpp>
26 #include <boost/interprocess/detail/workaround.hpp>
27
28 #include <boost/checked_delete.hpp>
29 #include <boost/intrusive/pointer_traits.hpp>
30 #include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
31 #include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
32 #include <boost/interprocess/detail/utilities.hpp>
33 #include <boost/container/allocator_traits.hpp>
34 #include <boost/core/no_exceptions_support.hpp>
35 #include <boost/move/adl_move_swap.hpp>
36 #include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
37 #include <boost/container/detail/placement_new.hpp>
38
39 namespace boost {
40 namespace interprocess {
41 namespace ipcdetail{
42
43 template<class T, class VoidAllocator, class Deleter>
44 class weak_count;
45
46 template<class T, class VoidAllocator, class Deleter>
47 class shared_count
48 {
49 public:
50 typedef typename boost::intrusive::
51 pointer_traits<typename VoidAllocator::pointer>::template
52 rebind_pointer<T>::type pointer;
53
54 private:
55 typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
56
57 typedef typename boost::intrusive::
58 pointer_traits<typename VoidAllocator::pointer>::template
59 rebind_pointer<counted_impl>::type counted_impl_ptr;
60 typedef typename boost::intrusive::
61 pointer_traits<typename VoidAllocator::pointer>::template
62 rebind_pointer<sp_counted_base>::type counted_base_ptr;
63
64 typedef boost::container::allocator_traits<VoidAllocator> vallocator_traits;
65
66 typedef typename vallocator_traits::template
67 portable_rebind_alloc<counted_impl>::type counted_impl_allocator;
68
69 typedef typename boost::intrusive::
70 pointer_traits<typename VoidAllocator::pointer>::template
71 rebind_pointer<const Deleter>::type const_deleter_pointer;
72
73 typedef typename boost::intrusive::
74 pointer_traits<typename VoidAllocator::pointer>::template
75 rebind_pointer<const VoidAllocator>::type const_allocator_pointer;
76
77 pointer m_px;
78 counted_impl_ptr m_pi;
79
80 template <class T2, class VoidAllocator2, class Deleter2>
81 friend class weak_count;
82
83 template <class T2, class VoidAllocator2, class Deleter2>
84 friend class shared_count;
85
86 public:
87
88 shared_count()
89 : m_px(0), m_pi(0) // nothrow
90 {}
91
92 template <class Ptr>
93 shared_count(const shared_count &other_shared_count, const Ptr &p)
94 : m_px(p), m_pi(other_shared_count.m_pi)
95 {}
96
97 template <class Ptr>
98 shared_count(const Ptr &p, const VoidAllocator &a, Deleter d)
99 : m_px(p), m_pi(0)
100 {
101 BOOST_TRY{
102 if(p){
103 counted_impl_allocator alloc(a);
104 m_pi = alloc.allocate(1);
105 //Anti-exception deallocator
106 scoped_ptr<counted_impl,
107 scoped_ptr_dealloc_functor<counted_impl_allocator> >
108 deallocator(m_pi, alloc);
109 //It's more correct to use VoidAllocator::construct but
110 //this needs copy constructor and we don't like it
111 ::new(ipcdetail::to_raw_pointer(m_pi), boost_container_new_t())counted_impl(p, a, d);
112 deallocator.release();
113 }
114 }
115 BOOST_CATCH (...){
116 d(p); // delete p
117 BOOST_RETHROW
118 }
119 BOOST_CATCH_END
120 }
121
122 ~shared_count() // nothrow
123 {
124 if(m_pi)
125 m_pi->release();
126 }
127
128 shared_count(shared_count const & r)
129 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
130 { if( m_pi != 0 ) m_pi->add_ref_copy(); }
131
132 //this is a test
133 template<class Y>
134 explicit shared_count(shared_count<Y, VoidAllocator, Deleter> const & r)
135 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
136 { if( m_pi != 0 ) m_pi->add_ref_copy(); }
137
138 //this is a test
139 template<class Y>
140 explicit shared_count(const pointer & ptr, shared_count<Y, VoidAllocator, Deleter> const & r)
141 : m_px(ptr), m_pi(r.m_pi) // nothrow
142 { if( m_pi != 0 ) m_pi->add_ref_copy(); }
143
144 /*
145 explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
146 // throws bad_weak_ptr when r.use_count() == 0
147 : m_pi( r.m_pi )
148 {
149 if( m_pi == 0 || !m_pi->add_ref_lock() ){
150 boost::throw_exception( boost::interprocess::bad_weak_ptr() );
151 }
152 }
153 */
154 template<class Y>
155 explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
156 // throws bad_weak_ptr when r.use_count() == 0
157 : m_px(r.m_px), m_pi( r.m_pi )
158 {
159 if( m_pi == 0 || !m_pi->add_ref_lock() ){
160 throw( boost::interprocess::bad_weak_ptr() );
161 }
162 }
163
164 const pointer &to_raw_pointer() const
165 { return m_px; }
166
167 pointer &to_raw_pointer()
168 { return m_px; }
169
170 shared_count & operator= (shared_count const & r) // nothrow
171 {
172 m_px = r.m_px;
173 counted_impl_ptr tmp = r.m_pi;
174 if( tmp != m_pi ){
175 if(tmp != 0) tmp->add_ref_copy();
176 if(m_pi != 0) m_pi->release();
177 m_pi = tmp;
178 }
179 return *this;
180 }
181
182 template<class Y>
183 shared_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
184 {
185 m_px = r.m_px;
186 counted_impl_ptr tmp = r.m_pi;
187 if( tmp != m_pi ){
188 if(tmp != 0) tmp->add_ref_copy();
189 if(m_pi != 0) m_pi->release();
190 m_pi = tmp;
191 }
192 return *this;
193 }
194
195 void swap(shared_count & r) // nothrow
196 { ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_swap(m_pi, r.m_pi); }
197
198 long use_count() const // nothrow
199 { return m_pi != 0? m_pi->use_count(): 0; }
200
201 bool unique() const // nothrow
202 { return use_count() == 1; }
203
204 const_deleter_pointer get_deleter() const
205 { return m_pi ? m_pi->get_deleter() : 0; }
206
207 // const_allocator_pointer get_allocator() const
208 // { return m_pi ? m_pi->get_allocator() : 0; }
209
210 template<class T2, class VoidAllocator2, class Deleter2>
211 bool internal_equal (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
212 { return this->m_pi == other.m_pi; }
213
214 template<class T2, class VoidAllocator2, class Deleter2>
215 bool internal_less (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
216 { return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
217 };
218
219 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
220 bool operator==(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
221 { return a.internal_equal(b); }
222
223 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
224 bool operator<(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
225 { return a.internal_less(b); }
226
227
228 template<class T, class VoidAllocator, class Deleter>
229 class weak_count
230 {
231 public:
232 typedef typename boost::intrusive::
233 pointer_traits<typename VoidAllocator::pointer>::template
234 rebind_pointer<T>::type pointer;
235
236 private:
237
238 typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
239
240 typedef typename boost::intrusive::
241 pointer_traits<typename VoidAllocator::pointer>::template
242 rebind_pointer<counted_impl>::type counted_impl_ptr;
243 typedef typename boost::intrusive::
244 pointer_traits<typename VoidAllocator::pointer>::template
245 rebind_pointer<sp_counted_base>::type counted_base_ptr;
246
247 pointer m_px;
248 counted_impl_ptr m_pi;
249
250 template <class T2, class VoidAllocator2, class Deleter2>
251 friend class weak_count;
252
253 template <class T2, class VoidAllocator2, class Deleter2>
254 friend class shared_count;
255
256 public:
257
258 weak_count(): m_px(0), m_pi(0) // nothrow
259 {}
260
261 template <class Y>
262 explicit weak_count(shared_count<Y, VoidAllocator, Deleter> const & r)
263 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
264 { if(m_pi != 0) m_pi->weak_add_ref(); }
265
266 weak_count(weak_count const & r)
267 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
268 { if(m_pi != 0) m_pi->weak_add_ref(); }
269
270 template<class Y>
271 weak_count(weak_count<Y, VoidAllocator, Deleter> const & r)
272 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
273 { if(m_pi != 0) m_pi->weak_add_ref(); }
274
275 ~weak_count() // nothrow
276 { if(m_pi != 0) m_pi->weak_release(); }
277
278 template<class Y>
279 weak_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
280 {
281 m_px = r.m_px;
282 counted_impl_ptr tmp = r.m_pi;
283 if(tmp != 0) tmp->weak_add_ref();
284 if(m_pi != 0) m_pi->weak_release();
285 m_pi = tmp;
286 return *this;
287 }
288
289 weak_count & operator= (weak_count const & r) // nothrow
290 {
291 m_px = r.m_px;
292 counted_impl_ptr tmp = r.m_pi;
293 if(tmp != 0) tmp->weak_add_ref();
294 if(m_pi != 0) m_pi->weak_release();
295 m_pi = tmp;
296 return *this;
297 }
298
299 void set_pointer(const pointer &ptr)
300 { m_px = ptr; }
301
302 template<class Y>
303 weak_count & operator= (weak_count<Y, VoidAllocator, Deleter> const& r) // nothrow
304 {
305 counted_impl_ptr tmp = r.m_pi;
306 if(tmp != 0) tmp->weak_add_ref();
307 if(m_pi != 0) m_pi->weak_release();
308 m_pi = tmp;
309 return *this;
310 }
311
312 void swap(weak_count & r) // nothrow
313 { ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_swap(m_pi, r.m_pi); }
314
315 long use_count() const // nothrow
316 { return m_pi != 0? m_pi->use_count() : 0; }
317
318 template<class T2, class VoidAllocator2, class Deleter2>
319 bool internal_equal (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
320 { return this->m_pi == other.m_pi; }
321
322 template<class T2, class VoidAllocator2, class Deleter2>
323 bool internal_less (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
324 { return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
325 };
326
327 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
328 bool operator==(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
329 { return a.internal_equal(b); }
330
331 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
332 bool operator<(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
333 { return a.internal_less(b); }
334
335 } // namespace ipcdetail
336 } // namespace interprocess
337 } // namespace boost
338
339
340 #include <boost/interprocess/detail/config_end.hpp>
341
342
343 #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED