Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // This file is the adaptation for Interprocess of boost/shared_ptr.hpp
|
Chris@16
|
4 //
|
Chris@16
|
5 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
Chris@16
|
6 // (C) Copyright Peter Dimov 2001, 2002, 2003
|
Chris@16
|
7 // (C) Copyright Ion Gaztanaga 2006-2012.
|
Chris@16
|
8 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
9 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
10 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
11 //
|
Chris@16
|
12 // See http://www.boost.org/libs/interprocess for documentation.
|
Chris@16
|
13 //
|
Chris@16
|
14 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
15
|
Chris@16
|
16 #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
|
Chris@16
|
17 #define BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
|
Chris@16
|
18
|
Chris@101
|
19 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
20 # include <boost/config.hpp>
|
Chris@101
|
21 #endif
|
Chris@101
|
22 #
|
Chris@101
|
23 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
24 # pragma once
|
Chris@101
|
25 #endif
|
Chris@101
|
26
|
Chris@16
|
27 #include <boost/interprocess/detail/config_begin.hpp>
|
Chris@16
|
28 #include <boost/interprocess/detail/workaround.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 #include <boost/interprocess/detail/utilities.hpp>
|
Chris@16
|
31 #include <boost/interprocess/detail/cast_tags.hpp>
|
Chris@16
|
32 #include <boost/assert.hpp>
|
Chris@16
|
33 #include <boost/interprocess/smart_ptr/detail/shared_count.hpp>
|
Chris@16
|
34 #include <boost/interprocess/detail/mpl.hpp>
|
Chris@101
|
35 #include <boost/interprocess/detail/nothrow.hpp>
|
Chris@101
|
36 #include <boost/move/utility_core.hpp>
|
Chris@16
|
37 #include <boost/interprocess/detail/type_traits.hpp>
|
Chris@16
|
38 #include <boost/interprocess/allocators/allocator.hpp>
|
Chris@16
|
39 #include <boost/interprocess/smart_ptr/deleter.hpp>
|
Chris@16
|
40 #include <boost/static_assert.hpp>
|
Chris@16
|
41 #include <boost/intrusive/pointer_traits.hpp>
|
Chris@16
|
42
|
Chris@101
|
43 #include <iosfwd> // for std::basic_ostream
|
Chris@16
|
44
|
Chris@16
|
45 //!\file
|
Chris@16
|
46 //!Describes the smart pointer shared_ptr
|
Chris@16
|
47
|
Chris@16
|
48 namespace boost{
|
Chris@16
|
49 namespace interprocess{
|
Chris@16
|
50
|
Chris@16
|
51 template<class T, class VoidAllocator, class Deleter> class weak_ptr;
|
Chris@16
|
52 template<class T, class VoidAllocator, class Deleter> class enable_shared_from_this;
|
Chris@16
|
53
|
Chris@16
|
54 namespace ipcdetail{
|
Chris@16
|
55
|
Chris@16
|
56 template<class T, class VoidAllocator, class Deleter>
|
Chris@16
|
57 inline void sp_enable_shared_from_this
|
Chris@16
|
58 (shared_count<T, VoidAllocator, Deleter> const & pn
|
Chris@16
|
59 ,enable_shared_from_this<T, VoidAllocator, Deleter> *pe
|
Chris@16
|
60 ,T *ptr)
|
Chris@16
|
61
|
Chris@16
|
62 {
|
Chris@16
|
63 (void)ptr;
|
Chris@16
|
64 if(pe != 0){
|
Chris@16
|
65 pe->_internal_weak_this._internal_assign(pn);
|
Chris@16
|
66 }
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 template<class T, class VoidAllocator, class Deleter>
|
Chris@16
|
70 inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> const &, ...)
|
Chris@16
|
71 {}
|
Chris@16
|
72
|
Chris@16
|
73 } // namespace ipcdetail
|
Chris@16
|
74
|
Chris@16
|
75 //!shared_ptr stores a pointer to a dynamically allocated object.
|
Chris@16
|
76 //!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
|
Chris@16
|
77 //!it is destroyed or reset.
|
Chris@16
|
78 //!
|
Chris@16
|
79 //!shared_ptr is parameterized on
|
Chris@16
|
80 //!T (the type of the object pointed to), VoidAllocator (the void allocator to be used
|
Chris@16
|
81 //!to allocate the auxiliary data) and Deleter (the deleter whose
|
Chris@16
|
82 //!operator() will be used to delete the object.
|
Chris@16
|
83 //!
|
Chris@16
|
84 //!The internal pointer will be of the same pointer type as typename
|
Chris@16
|
85 //!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is
|
Chris@16
|
86 //!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
|
Chris@16
|
87 //!
|
Chris@16
|
88 //!Because the implementation uses reference counting, cycles of shared_ptr
|
Chris@16
|
89 //!instances will not be reclaimed. For example, if main() holds a
|
Chris@16
|
90 //!shared_ptr to A, which directly or indirectly holds a shared_ptr back
|
Chris@16
|
91 //!to A, A's use count will be 2. Destruction of the original shared_ptr
|
Chris@16
|
92 //!will leave A dangling with a use count of 1.
|
Chris@16
|
93 //!Use weak_ptr to "break cycles."
|
Chris@16
|
94 template<class T, class VoidAllocator, class Deleter>
|
Chris@16
|
95 class shared_ptr
|
Chris@16
|
96 {
|
Chris@101
|
97 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
98 private:
|
Chris@16
|
99 typedef shared_ptr<T, VoidAllocator, Deleter> this_type;
|
Chris@101
|
100 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
101
|
Chris@16
|
102 public:
|
Chris@16
|
103
|
Chris@16
|
104 typedef T element_type;
|
Chris@16
|
105 typedef T value_type;
|
Chris@16
|
106 typedef typename boost::intrusive::
|
Chris@16
|
107 pointer_traits<typename VoidAllocator::pointer>::template
|
Chris@16
|
108 rebind_pointer<T>::type pointer;
|
Chris@16
|
109 typedef typename ipcdetail::add_reference
|
Chris@16
|
110 <value_type>::type reference;
|
Chris@16
|
111 typedef typename ipcdetail::add_reference
|
Chris@16
|
112 <const value_type>::type const_reference;
|
Chris@16
|
113 typedef typename boost::intrusive::
|
Chris@16
|
114 pointer_traits<typename VoidAllocator::pointer>::template
|
Chris@16
|
115 rebind_pointer<const Deleter>::type const_deleter_pointer;
|
Chris@16
|
116 typedef typename boost::intrusive::
|
Chris@16
|
117 pointer_traits<typename VoidAllocator::pointer>::template
|
Chris@16
|
118 rebind_pointer<const VoidAllocator>::type const_allocator_pointer;
|
Chris@16
|
119
|
Chris@16
|
120 BOOST_COPYABLE_AND_MOVABLE(shared_ptr)
|
Chris@16
|
121 public:
|
Chris@16
|
122
|
Chris@16
|
123 //!Constructs an empty shared_ptr.
|
Chris@16
|
124 //!Use_count() == 0 && get()== 0.
|
Chris@16
|
125 shared_ptr()
|
Chris@16
|
126 : m_pn() // never throws
|
Chris@16
|
127 {}
|
Chris@16
|
128
|
Chris@16
|
129 //!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated
|
Chris@16
|
130 //!with a copy of a and the object will be deleted with a copy of d.
|
Chris@16
|
131 //!Requirements: Deleter and A's copy constructor must not throw.
|
Chris@16
|
132 explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
|
Chris@16
|
133 : m_pn(p, a, d)
|
Chris@16
|
134 {
|
Chris@16
|
135 //Check that the pointer passed is of the same type that
|
Chris@16
|
136 //the pointer the allocator defines or it's a raw pointer
|
Chris@16
|
137 typedef typename boost::intrusive::
|
Chris@16
|
138 pointer_traits<pointer>::template
|
Chris@16
|
139 rebind_pointer<T>::type ParameterPointer;
|
Chris@16
|
140
|
Chris@16
|
141 BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
|
Chris@16
|
142 (ipcdetail::is_pointer<pointer>::value));
|
Chris@16
|
143 ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) );
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 //!Copy constructs a shared_ptr. If r is empty, constructs an empty shared_ptr. Otherwise, constructs
|
Chris@16
|
147 //!a shared_ptr that shares ownership with r. Never throws.
|
Chris@16
|
148 shared_ptr(const shared_ptr &r)
|
Chris@16
|
149 : m_pn(r.m_pn) // never throws
|
Chris@16
|
150 {}
|
Chris@16
|
151
|
Chris@16
|
152 //!Constructs a shared_ptr that shares ownership with other and stores p.
|
Chris@16
|
153 //!Postconditions: get() == p && use_count() == r.use_count().
|
Chris@16
|
154 //!Throws: nothing.
|
Chris@16
|
155 shared_ptr(const shared_ptr &other, const pointer &p)
|
Chris@16
|
156 : m_pn(other.m_pn, p)
|
Chris@16
|
157 {}
|
Chris@16
|
158
|
Chris@16
|
159 //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
|
Chris@16
|
160 //!a shared_ptr that shares ownership with r. Never throws.
|
Chris@16
|
161 template<class Y>
|
Chris@16
|
162 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
|
Chris@16
|
163 : m_pn(r.m_pn) // never throws
|
Chris@16
|
164 {}
|
Chris@16
|
165
|
Chris@16
|
166 //!Constructs a shared_ptr that shares ownership with r and stores
|
Chris@16
|
167 //!a copy of the pointer stored in r.
|
Chris@16
|
168 template<class Y>
|
Chris@16
|
169 explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
|
Chris@16
|
170 : m_pn(r.m_pn) // may throw
|
Chris@16
|
171 {}
|
Chris@16
|
172
|
Chris@16
|
173 //!Move-Constructs a shared_ptr that takes ownership of other resource and
|
Chris@16
|
174 //!other is put in default-constructed state.
|
Chris@16
|
175 //!Throws: nothing.
|
Chris@16
|
176 explicit shared_ptr(BOOST_RV_REF(shared_ptr) other)
|
Chris@16
|
177 : m_pn()
|
Chris@16
|
178 { this->swap(other); }
|
Chris@16
|
179
|
Chris@101
|
180 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
181 template<class Y>
|
Chris@16
|
182 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::static_cast_tag)
|
Chris@16
|
183 : m_pn( pointer(static_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
|
Chris@16
|
184 , r.m_pn)
|
Chris@16
|
185 {}
|
Chris@16
|
186
|
Chris@16
|
187 template<class Y>
|
Chris@16
|
188 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::const_cast_tag)
|
Chris@16
|
189 : m_pn( pointer(const_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
|
Chris@16
|
190 , r.m_pn)
|
Chris@16
|
191 {}
|
Chris@16
|
192
|
Chris@16
|
193 template<class Y>
|
Chris@16
|
194 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::dynamic_cast_tag)
|
Chris@16
|
195 : m_pn( pointer(dynamic_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
|
Chris@16
|
196 , r.m_pn)
|
Chris@16
|
197 {
|
Chris@16
|
198 if(!m_pn.to_raw_pointer()){ // need to allocate new counter -- the cast failed
|
Chris@16
|
199 m_pn = ipcdetail::shared_count<T, VoidAllocator, Deleter>();
|
Chris@16
|
200 }
|
Chris@16
|
201 }
|
Chris@101
|
202 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
203
|
Chris@16
|
204 //!Equivalent to shared_ptr(r).swap(*this).
|
Chris@16
|
205 //!Never throws
|
Chris@16
|
206 template<class Y>
|
Chris@16
|
207 shared_ptr & operator=(shared_ptr<Y, VoidAllocator, Deleter> const & r)
|
Chris@16
|
208 {
|
Chris@16
|
209 m_pn = r.m_pn; // shared_count::op= doesn't throw
|
Chris@16
|
210 return *this;
|
Chris@16
|
211 }
|
Chris@16
|
212
|
Chris@16
|
213 //!Equivalent to shared_ptr(r).swap(*this).
|
Chris@16
|
214 //!Never throws
|
Chris@16
|
215 shared_ptr & operator=(BOOST_COPY_ASSIGN_REF(shared_ptr) r)
|
Chris@16
|
216 {
|
Chris@16
|
217 m_pn = r.m_pn; // shared_count::op= doesn't throw
|
Chris@16
|
218 return *this;
|
Chris@16
|
219 }
|
Chris@16
|
220
|
Chris@16
|
221 //!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
|
Chris@16
|
222 //!Never throws
|
Chris@16
|
223 shared_ptr & operator=(BOOST_RV_REF(shared_ptr) other) // never throws
|
Chris@16
|
224 {
|
Chris@16
|
225 this_type(other).swap(*this);
|
Chris@16
|
226 return *this;
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 //!This is equivalent to:
|
Chris@16
|
230 //!this_type().swap(*this);
|
Chris@16
|
231 void reset()
|
Chris@16
|
232 {
|
Chris@16
|
233 this_type().swap(*this);
|
Chris@16
|
234 }
|
Chris@16
|
235
|
Chris@16
|
236 //!This is equivalent to:
|
Chris@16
|
237 //!this_type(p, a, d).swap(*this);
|
Chris@16
|
238 template<class Pointer>
|
Chris@16
|
239 void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
|
Chris@16
|
240 {
|
Chris@16
|
241 //Check that the pointer passed is of the same type that
|
Chris@16
|
242 //the pointer the allocator defines or it's a raw pointer
|
Chris@16
|
243 typedef typename boost::intrusive::
|
Chris@16
|
244 pointer_traits<Pointer>::template
|
Chris@16
|
245 rebind_pointer<T>::type ParameterPointer;
|
Chris@16
|
246 BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
|
Chris@16
|
247 (ipcdetail::is_pointer<Pointer>::value));
|
Chris@16
|
248 this_type(p, a, d).swap(*this);
|
Chris@16
|
249 }
|
Chris@16
|
250
|
Chris@16
|
251 template<class Y>
|
Chris@16
|
252 void reset(shared_ptr<Y, VoidAllocator, Deleter> const & r, const pointer &p)
|
Chris@16
|
253 {
|
Chris@16
|
254 this_type(r, p).swap(*this);
|
Chris@16
|
255 }
|
Chris@16
|
256
|
Chris@16
|
257 //!Returns a reference to the
|
Chris@16
|
258 //!pointed type
|
Chris@16
|
259 reference operator* () const // never throws
|
Chris@16
|
260 { BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return *m_pn.to_raw_pointer(); }
|
Chris@16
|
261
|
Chris@16
|
262 //!Returns the pointer pointing
|
Chris@16
|
263 //!to the owned object
|
Chris@16
|
264 pointer operator-> () const // never throws
|
Chris@16
|
265 { BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return m_pn.to_raw_pointer(); }
|
Chris@16
|
266
|
Chris@16
|
267 //!Returns the pointer pointing
|
Chris@16
|
268 //!to the owned object
|
Chris@16
|
269 pointer get() const // never throws
|
Chris@16
|
270 { return m_pn.to_raw_pointer(); }
|
Chris@16
|
271
|
Chris@101
|
272 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
273 // implicit conversion to "bool"
|
Chris@16
|
274 void unspecified_bool_type_func() const {}
|
Chris@16
|
275 typedef void (this_type::*unspecified_bool_type)() const;
|
Chris@16
|
276
|
Chris@16
|
277 operator unspecified_bool_type() const // never throws
|
Chris@16
|
278 { return !m_pn.to_raw_pointer() ? 0 : &this_type::unspecified_bool_type_func; }
|
Chris@101
|
279 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
280
|
Chris@16
|
281 //!Not operator.
|
Chris@16
|
282 //!Returns true if this->get() != 0, false otherwise
|
Chris@16
|
283 bool operator! () const // never throws
|
Chris@16
|
284 { return !m_pn.to_raw_pointer(); }
|
Chris@16
|
285
|
Chris@16
|
286 //!Returns use_count() == 1.
|
Chris@16
|
287 //!unique() might be faster than use_count()
|
Chris@16
|
288 bool unique() const // never throws
|
Chris@16
|
289 { return m_pn.unique(); }
|
Chris@16
|
290
|
Chris@16
|
291 //!Returns the number of shared_ptr objects, *this included,
|
Chris@16
|
292 //!that share ownership with *this, or an unspecified nonnegative
|
Chris@16
|
293 //!value when *this is empty.
|
Chris@16
|
294 //!use_count() is not necessarily efficient. Use only for
|
Chris@16
|
295 //!debugging and testing purposes, not for production code.
|
Chris@16
|
296 long use_count() const // never throws
|
Chris@16
|
297 { return m_pn.use_count(); }
|
Chris@16
|
298
|
Chris@16
|
299 //!Exchanges the contents of the two
|
Chris@16
|
300 //!smart pointers.
|
Chris@16
|
301 void swap(shared_ptr<T, VoidAllocator, Deleter> & other) // never throws
|
Chris@16
|
302 { m_pn.swap(other.m_pn); }
|
Chris@16
|
303
|
Chris@101
|
304 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
305
|
Chris@16
|
306 template<class T2, class A2, class Deleter2>
|
Chris@16
|
307 bool _internal_less(shared_ptr<T2, A2, Deleter2> const & rhs) const
|
Chris@16
|
308 { return m_pn < rhs.m_pn; }
|
Chris@16
|
309
|
Chris@16
|
310 const_deleter_pointer get_deleter() const
|
Chris@16
|
311 { return m_pn.get_deleter(); }
|
Chris@16
|
312
|
Chris@16
|
313 // const_allocator_pointer get_allocator() const
|
Chris@16
|
314 // { return m_pn.get_allocator(); }
|
Chris@16
|
315
|
Chris@16
|
316 private:
|
Chris@16
|
317
|
Chris@16
|
318 template<class T2, class A2, class Deleter2> friend class shared_ptr;
|
Chris@16
|
319 template<class T2, class A2, class Deleter2> friend class weak_ptr;
|
Chris@16
|
320
|
Chris@16
|
321 ipcdetail::shared_count<T, VoidAllocator, Deleter> m_pn; // reference counter
|
Chris@101
|
322 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
323 }; // shared_ptr
|
Chris@16
|
324
|
Chris@16
|
325 template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
|
Chris@16
|
326 bool operator==(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
|
Chris@16
|
327 { return a.get() == b.get(); }
|
Chris@16
|
328
|
Chris@16
|
329 template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
|
Chris@16
|
330 bool operator!=(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
|
Chris@16
|
331 { return a.get() != b.get(); }
|
Chris@16
|
332
|
Chris@16
|
333 template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
|
Chris@16
|
334 bool operator<(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
|
Chris@16
|
335 { return a._internal_less(b); }
|
Chris@16
|
336
|
Chris@16
|
337 template<class T, class VoidAllocator, class Deleter> inline
|
Chris@16
|
338 void swap(shared_ptr<T, VoidAllocator, Deleter> & a, shared_ptr<T, VoidAllocator, Deleter> & b)
|
Chris@16
|
339 { a.swap(b); }
|
Chris@16
|
340
|
Chris@16
|
341 template<class T, class VoidAllocator, class Deleter, class U> inline
|
Chris@16
|
342 shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
|
Chris@16
|
343 { return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::static_cast_tag()); }
|
Chris@16
|
344
|
Chris@16
|
345 template<class T, class VoidAllocator, class Deleter, class U> inline
|
Chris@16
|
346 shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
|
Chris@16
|
347 { return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::const_cast_tag()); }
|
Chris@16
|
348
|
Chris@16
|
349 template<class T, class VoidAllocator, class Deleter, class U> inline
|
Chris@16
|
350 shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
|
Chris@16
|
351 { return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::dynamic_cast_tag()); }
|
Chris@16
|
352
|
Chris@16
|
353 // to_raw_pointer() enables boost::mem_fn to recognize shared_ptr
|
Chris@16
|
354 template<class T, class VoidAllocator, class Deleter> inline
|
Chris@16
|
355 T * to_raw_pointer(shared_ptr<T, VoidAllocator, Deleter> const & p)
|
Chris@16
|
356 { return p.get(); }
|
Chris@16
|
357
|
Chris@16
|
358 // operator<<
|
Chris@16
|
359 template<class E, class T, class Y, class VoidAllocator, class Deleter> inline
|
Chris@16
|
360 std::basic_ostream<E, T> & operator<<
|
Chris@16
|
361 (std::basic_ostream<E, T> & os, shared_ptr<Y, VoidAllocator, Deleter> const & p)
|
Chris@16
|
362 { os << p.get(); return os; }
|
Chris@16
|
363
|
Chris@16
|
364 //!Returns the type of a shared pointer
|
Chris@16
|
365 //!of type T with the allocator boost::interprocess::allocator allocator
|
Chris@16
|
366 //!and boost::interprocess::deleter deleter
|
Chris@16
|
367 //!that can be constructed in the given managed segment type.
|
Chris@16
|
368 template<class T, class ManagedMemory>
|
Chris@16
|
369 struct managed_shared_ptr
|
Chris@16
|
370 {
|
Chris@16
|
371 typedef typename ManagedMemory::template allocator<void>::type void_allocator;
|
Chris@16
|
372 typedef typename ManagedMemory::template deleter<T>::type deleter;
|
Chris@16
|
373 typedef shared_ptr< T, void_allocator, deleter> type;
|
Chris@16
|
374 };
|
Chris@16
|
375
|
Chris@16
|
376 //!Returns an instance of a shared pointer constructed
|
Chris@16
|
377 //!with the default allocator and deleter from a pointer
|
Chris@16
|
378 //!of type T that has been allocated in the passed managed segment
|
Chris@16
|
379 template<class T, class ManagedMemory>
|
Chris@16
|
380 inline typename managed_shared_ptr<T, ManagedMemory>::type
|
Chris@16
|
381 make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory)
|
Chris@16
|
382 {
|
Chris@16
|
383 return typename managed_shared_ptr<T, ManagedMemory>::type
|
Chris@16
|
384 ( constructed_object
|
Chris@16
|
385 , managed_memory.template get_allocator<void>()
|
Chris@16
|
386 , managed_memory.template get_deleter<T>()
|
Chris@16
|
387 );
|
Chris@16
|
388 }
|
Chris@16
|
389
|
Chris@16
|
390 //!Returns an instance of a shared pointer constructed
|
Chris@16
|
391 //!with the default allocator and deleter from a pointer
|
Chris@16
|
392 //!of type T that has been allocated in the passed managed segment.
|
Chris@16
|
393 //!Does not throw, return null shared pointer in error.
|
Chris@16
|
394 template<class T, class ManagedMemory>
|
Chris@16
|
395 inline typename managed_shared_ptr<T, ManagedMemory>::type
|
Chris@101
|
396 make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory, const std::nothrow_t &)
|
Chris@16
|
397 {
|
Chris@16
|
398 try{
|
Chris@16
|
399 return typename managed_shared_ptr<T, ManagedMemory>::type
|
Chris@16
|
400 ( constructed_object
|
Chris@16
|
401 , managed_memory.template get_allocator<void>()
|
Chris@16
|
402 , managed_memory.template get_deleter<T>()
|
Chris@16
|
403 );
|
Chris@16
|
404 }
|
Chris@16
|
405 catch(...){
|
Chris@16
|
406 return typename managed_shared_ptr<T, ManagedMemory>::type();
|
Chris@16
|
407 }
|
Chris@16
|
408 }
|
Chris@16
|
409
|
Chris@16
|
410
|
Chris@16
|
411 } // namespace interprocess
|
Chris@16
|
412
|
Chris@101
|
413 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
414
|
Chris@16
|
415 #if defined(_MSC_VER) && (_MSC_VER < 1400)
|
Chris@16
|
416 // to_raw_pointer() enables boost::mem_fn to recognize shared_ptr
|
Chris@16
|
417 template<class T, class VoidAllocator, class Deleter> inline
|
Chris@16
|
418 T * to_raw_pointer(boost::interprocess::shared_ptr<T, VoidAllocator, Deleter> const & p)
|
Chris@16
|
419 { return p.get(); }
|
Chris@16
|
420 #endif
|
Chris@16
|
421
|
Chris@101
|
422 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
423
|
Chris@16
|
424 } // namespace boost
|
Chris@16
|
425
|
Chris@16
|
426 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
427
|
Chris@16
|
428 #endif // #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
|