Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/interprocess/smart_ptr/detail/shared_count.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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 // MS compatible compilers support #pragma once | |
18 | |
19 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
20 # pragma once | |
21 #endif | |
22 | |
23 #include <boost/interprocess/detail/config_begin.hpp> | |
24 #include <boost/interprocess/detail/workaround.hpp> | |
25 | |
26 #include <boost/checked_delete.hpp> | |
27 #include <boost/intrusive/pointer_traits.hpp> | |
28 #include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp> | |
29 #include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp> | |
30 #include <boost/interprocess/detail/utilities.hpp> | |
31 #include <boost/container/allocator_traits.hpp> | |
32 #include <boost/detail/no_exceptions_support.hpp> | |
33 #include <functional> // std::less | |
34 | |
35 namespace boost { | |
36 namespace interprocess { | |
37 namespace ipcdetail{ | |
38 | |
39 template<class T, class VoidAllocator, class Deleter> | |
40 class weak_count; | |
41 | |
42 template<class T, class VoidAllocator, class Deleter> | |
43 class shared_count | |
44 { | |
45 public: | |
46 typedef typename boost::intrusive:: | |
47 pointer_traits<typename VoidAllocator::pointer>::template | |
48 rebind_pointer<T>::type pointer; | |
49 | |
50 private: | |
51 typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl; | |
52 | |
53 typedef typename boost::intrusive:: | |
54 pointer_traits<typename VoidAllocator::pointer>::template | |
55 rebind_pointer<counted_impl>::type counted_impl_ptr; | |
56 typedef typename boost::intrusive:: | |
57 pointer_traits<typename VoidAllocator::pointer>::template | |
58 rebind_pointer<sp_counted_base>::type counted_base_ptr; | |
59 | |
60 typedef boost::container::allocator_traits<VoidAllocator> vallocator_traits; | |
61 | |
62 typedef typename vallocator_traits::template | |
63 portable_rebind_alloc<counted_impl>::type counted_impl_allocator; | |
64 | |
65 typedef typename boost::intrusive:: | |
66 pointer_traits<typename VoidAllocator::pointer>::template | |
67 rebind_pointer<const Deleter>::type const_deleter_pointer; | |
68 | |
69 typedef typename boost::intrusive:: | |
70 pointer_traits<typename VoidAllocator::pointer>::template | |
71 rebind_pointer<const VoidAllocator>::type const_allocator_pointer; | |
72 | |
73 pointer m_px; | |
74 counted_impl_ptr m_pi; | |
75 | |
76 template <class T2, class VoidAllocator2, class Deleter2> | |
77 friend class weak_count; | |
78 | |
79 template <class T2, class VoidAllocator2, class Deleter2> | |
80 friend class shared_count; | |
81 | |
82 public: | |
83 | |
84 shared_count() | |
85 : m_px(0), m_pi(0) // nothrow | |
86 {} | |
87 | |
88 template <class Ptr> | |
89 shared_count(const shared_count &other_shared_count, const Ptr &p) | |
90 : m_px(p), m_pi(other_shared_count.m_pi) | |
91 {} | |
92 | |
93 template <class Ptr> | |
94 shared_count(const Ptr &p, const VoidAllocator &a, Deleter d) | |
95 : m_px(p), m_pi(0) | |
96 { | |
97 BOOST_TRY{ | |
98 if(p){ | |
99 counted_impl_allocator alloc(a); | |
100 m_pi = alloc.allocate(1); | |
101 //Anti-exception deallocator | |
102 scoped_ptr<counted_impl, | |
103 scoped_ptr_dealloc_functor<counted_impl_allocator> > | |
104 deallocator(m_pi, alloc); | |
105 //It's more correct to use VoidAllocator::construct but | |
106 //this needs copy constructor and we don't like it | |
107 new(ipcdetail::to_raw_pointer(m_pi))counted_impl(p, a, d); | |
108 deallocator.release(); | |
109 } | |
110 } | |
111 BOOST_CATCH (...){ | |
112 d(p); // delete p | |
113 BOOST_RETHROW | |
114 } | |
115 BOOST_CATCH_END | |
116 } | |
117 | |
118 ~shared_count() // nothrow | |
119 { | |
120 if(m_pi) | |
121 m_pi->release(); | |
122 } | |
123 | |
124 shared_count(shared_count const & r) | |
125 : m_px(r.m_px), m_pi(r.m_pi) // nothrow | |
126 { if( m_pi != 0 ) m_pi->add_ref_copy(); } | |
127 | |
128 //this is a test | |
129 template<class Y> | |
130 explicit shared_count(shared_count<Y, VoidAllocator, Deleter> const & r) | |
131 : m_px(r.m_px), m_pi(r.m_pi) // nothrow | |
132 { if( m_pi != 0 ) m_pi->add_ref_copy(); } | |
133 | |
134 //this is a test | |
135 template<class Y> | |
136 explicit shared_count(const pointer & ptr, shared_count<Y, VoidAllocator, Deleter> const & r) | |
137 : m_px(ptr), m_pi(r.m_pi) // nothrow | |
138 { if( m_pi != 0 ) m_pi->add_ref_copy(); } | |
139 | |
140 /* | |
141 explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r) | |
142 // throws bad_weak_ptr when r.use_count() == 0 | |
143 : m_pi( r.m_pi ) | |
144 { | |
145 if( m_pi == 0 || !m_pi->add_ref_lock() ){ | |
146 boost::throw_exception( boost::interprocess::bad_weak_ptr() ); | |
147 } | |
148 } | |
149 */ | |
150 template<class Y> | |
151 explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r) | |
152 // throws bad_weak_ptr when r.use_count() == 0 | |
153 : m_px(r.m_px), m_pi( r.m_pi ) | |
154 { | |
155 if( m_pi == 0 || !m_pi->add_ref_lock() ){ | |
156 throw( boost::interprocess::bad_weak_ptr() ); | |
157 } | |
158 } | |
159 | |
160 const pointer &to_raw_pointer() const | |
161 { return m_px; } | |
162 | |
163 pointer &to_raw_pointer() | |
164 { return m_px; } | |
165 | |
166 shared_count & operator= (shared_count const & r) // nothrow | |
167 { | |
168 m_px = r.m_px; | |
169 counted_impl_ptr tmp = r.m_pi; | |
170 if( tmp != m_pi ){ | |
171 if(tmp != 0) tmp->add_ref_copy(); | |
172 if(m_pi != 0) m_pi->release(); | |
173 m_pi = tmp; | |
174 } | |
175 return *this; | |
176 } | |
177 | |
178 template<class Y> | |
179 shared_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow | |
180 { | |
181 m_px = r.m_px; | |
182 counted_impl_ptr tmp = r.m_pi; | |
183 if( tmp != m_pi ){ | |
184 if(tmp != 0) tmp->add_ref_copy(); | |
185 if(m_pi != 0) m_pi->release(); | |
186 m_pi = tmp; | |
187 } | |
188 return *this; | |
189 } | |
190 | |
191 void swap(shared_count & r) // nothrow | |
192 { ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); } | |
193 | |
194 long use_count() const // nothrow | |
195 { return m_pi != 0? m_pi->use_count(): 0; } | |
196 | |
197 bool unique() const // nothrow | |
198 { return use_count() == 1; } | |
199 | |
200 const_deleter_pointer get_deleter() const | |
201 { return m_pi ? m_pi->get_deleter() : 0; } | |
202 | |
203 // const_allocator_pointer get_allocator() const | |
204 // { return m_pi ? m_pi->get_allocator() : 0; } | |
205 | |
206 template<class T2, class VoidAllocator2, class Deleter2> | |
207 bool internal_equal (shared_count<T2, VoidAllocator2, Deleter2> const & other) const | |
208 { return this->m_pi == other.m_pi; } | |
209 | |
210 template<class T2, class VoidAllocator2, class Deleter2> | |
211 bool internal_less (shared_count<T2, VoidAllocator2, Deleter2> const & other) const | |
212 { return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); } | |
213 }; | |
214 | |
215 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline | |
216 bool operator==(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b) | |
217 { return a.internal_equal(b); } | |
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_less(b); } | |
222 | |
223 | |
224 template<class T, class VoidAllocator, class Deleter> | |
225 class weak_count | |
226 { | |
227 public: | |
228 typedef typename boost::intrusive:: | |
229 pointer_traits<typename VoidAllocator::pointer>::template | |
230 rebind_pointer<T>::type pointer; | |
231 | |
232 private: | |
233 | |
234 typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl; | |
235 | |
236 typedef typename boost::intrusive:: | |
237 pointer_traits<typename VoidAllocator::pointer>::template | |
238 rebind_pointer<counted_impl>::type counted_impl_ptr; | |
239 typedef typename boost::intrusive:: | |
240 pointer_traits<typename VoidAllocator::pointer>::template | |
241 rebind_pointer<sp_counted_base>::type counted_base_ptr; | |
242 | |
243 pointer m_px; | |
244 counted_impl_ptr m_pi; | |
245 | |
246 template <class T2, class VoidAllocator2, class Deleter2> | |
247 friend class weak_count; | |
248 | |
249 template <class T2, class VoidAllocator2, class Deleter2> | |
250 friend class shared_count; | |
251 | |
252 public: | |
253 | |
254 weak_count(): m_px(0), m_pi(0) // nothrow | |
255 {} | |
256 | |
257 template <class Y> | |
258 explicit weak_count(shared_count<Y, VoidAllocator, Deleter> const & r) | |
259 : m_px(r.m_px), m_pi(r.m_pi) // nothrow | |
260 { if(m_pi != 0) m_pi->weak_add_ref(); } | |
261 | |
262 weak_count(weak_count 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 template<class Y> | |
267 weak_count(weak_count<Y, VoidAllocator, Deleter> const & r) | |
268 : m_px(r.m_px), m_pi(r.m_pi) // nothrow | |
269 { if(m_pi != 0) m_pi->weak_add_ref(); } | |
270 | |
271 ~weak_count() // nothrow | |
272 { if(m_pi != 0) m_pi->weak_release(); } | |
273 | |
274 template<class Y> | |
275 weak_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow | |
276 { | |
277 m_px = r.m_px; | |
278 counted_impl_ptr tmp = r.m_pi; | |
279 if(tmp != 0) tmp->weak_add_ref(); | |
280 if(m_pi != 0) m_pi->weak_release(); | |
281 m_pi = tmp; | |
282 return *this; | |
283 } | |
284 | |
285 weak_count & operator= (weak_count const & r) // nothrow | |
286 { | |
287 m_px = r.m_px; | |
288 counted_impl_ptr tmp = r.m_pi; | |
289 if(tmp != 0) tmp->weak_add_ref(); | |
290 if(m_pi != 0) m_pi->weak_release(); | |
291 m_pi = tmp; | |
292 return *this; | |
293 } | |
294 | |
295 void set_pointer(const pointer &ptr) | |
296 { m_px = ptr; } | |
297 | |
298 template<class Y> | |
299 weak_count & operator= (weak_count<Y, VoidAllocator, Deleter> const& r) // nothrow | |
300 { | |
301 counted_impl_ptr tmp = r.m_pi; | |
302 if(tmp != 0) tmp->weak_add_ref(); | |
303 if(m_pi != 0) m_pi->weak_release(); | |
304 m_pi = tmp; | |
305 return *this; | |
306 } | |
307 | |
308 void swap(weak_count & r) // nothrow | |
309 { ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); } | |
310 | |
311 long use_count() const // nothrow | |
312 { return m_pi != 0? m_pi->use_count() : 0; } | |
313 | |
314 template<class T2, class VoidAllocator2, class Deleter2> | |
315 bool internal_equal (weak_count<T2, VoidAllocator2, Deleter2> const & other) const | |
316 { return this->m_pi == other.m_pi; } | |
317 | |
318 template<class T2, class VoidAllocator2, class Deleter2> | |
319 bool internal_less (weak_count<T2, VoidAllocator2, Deleter2> const & other) const | |
320 { return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); } | |
321 }; | |
322 | |
323 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline | |
324 bool operator==(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b) | |
325 { return a.internal_equal(b); } | |
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_less(b); } | |
330 | |
331 } // namespace ipcdetail | |
332 } // namespace interprocess | |
333 } // namespace boost | |
334 | |
335 | |
336 #include <boost/interprocess/detail/config_end.hpp> | |
337 | |
338 | |
339 #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED |