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