File indexing completed on 2024-11-15 09:14:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
0017 #define BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
0018
0019 #ifndef BOOST_CONFIG_HPP
0020 # include <boost/config.hpp>
0021 #endif
0022 #
0023 #if defined(BOOST_HAS_PRAGMA_ONCE)
0024 # pragma once
0025 #endif
0026
0027 #include <boost/interprocess/detail/config_begin.hpp>
0028 #include <boost/interprocess/detail/workaround.hpp>
0029
0030 #include <boost/interprocess/detail/utilities.hpp>
0031 #include <boost/interprocess/detail/cast_tags.hpp>
0032 #include <boost/assert.hpp>
0033 #include <boost/static_assert.hpp>
0034 #include <boost/interprocess/smart_ptr/detail/shared_count.hpp>
0035 #include <boost/interprocess/detail/mpl.hpp>
0036 #include <boost/interprocess/detail/nothrow.hpp>
0037 #include <boost/move/utility_core.hpp>
0038 #include <boost/interprocess/detail/type_traits.hpp>
0039 #include <boost/interprocess/allocators/allocator.hpp>
0040 #include <boost/interprocess/smart_ptr/deleter.hpp>
0041 #include <boost/intrusive/pointer_traits.hpp>
0042
0043 #include <iosfwd> // for std::basic_ostream
0044
0045
0046
0047
0048 namespace boost{
0049 namespace interprocess{
0050
0051 template<class T, class VoidAllocator, class Deleter> class weak_ptr;
0052 template<class T, class VoidAllocator, class Deleter> class enable_shared_from_this;
0053
0054 namespace ipcdetail{
0055
0056 template<class T, class VoidAllocator, class Deleter>
0057 inline void sp_enable_shared_from_this
0058 (shared_count<T, VoidAllocator, Deleter> const & pn
0059 ,enable_shared_from_this<T, VoidAllocator, Deleter> const*pe
0060 ,T *ptr)
0061
0062 {
0063 (void)ptr;
0064 if(pe != 0){
0065 pe->_internal_weak_this._internal_assign(pn);
0066 }
0067 }
0068
0069 template<class T, class VoidAllocator, class Deleter>
0070 inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> const &, ...)
0071 {}
0072
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template<class T, class VoidAllocator, class Deleter>
0095 class shared_ptr
0096 {
0097 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0098 private:
0099 typedef shared_ptr<T, VoidAllocator, Deleter> this_type;
0100 #endif
0101
0102 public:
0103
0104 typedef T element_type;
0105 typedef T value_type;
0106 typedef typename boost::container::
0107 allocator_traits<VoidAllocator>::pointer void_ptr;
0108 typedef typename boost::intrusive::
0109 pointer_traits<void_ptr>::template
0110 rebind_pointer<T>::type pointer;
0111 typedef typename ipcdetail::add_reference
0112 <value_type>::type reference;
0113 typedef typename ipcdetail::add_reference
0114 <const value_type>::type const_reference;
0115 typedef typename boost::intrusive::
0116 pointer_traits<void_ptr>::template
0117 rebind_pointer<const Deleter>::type const_deleter_pointer;
0118 typedef typename boost::intrusive::
0119 pointer_traits<void_ptr>::template
0120 rebind_pointer<const VoidAllocator>::type const_allocator_pointer;
0121
0122 BOOST_COPYABLE_AND_MOVABLE(shared_ptr)
0123 public:
0124
0125
0126
0127 shared_ptr()
0128 : m_pn()
0129 {}
0130
0131
0132
0133
0134 explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
0135 : m_pn(p, a, d)
0136 {
0137
0138
0139 typedef typename boost::intrusive::
0140 pointer_traits<pointer>::template
0141 rebind_pointer<T>::type ParameterPointer;
0142
0143 BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
0144 (ipcdetail::is_pointer<pointer>::value));
0145 ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) );
0146 }
0147
0148
0149
0150 shared_ptr(const shared_ptr &r)
0151 : m_pn(r.m_pn)
0152 {}
0153
0154
0155
0156
0157 shared_ptr(const shared_ptr &other, const pointer &p)
0158 : m_pn(other.m_pn, p)
0159 {}
0160
0161
0162
0163 template<class Y>
0164 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
0165 : m_pn(r.m_pn)
0166 {}
0167
0168
0169
0170 template<class Y>
0171 explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
0172 : m_pn(r.m_pn)
0173 {}
0174
0175
0176
0177
0178 explicit shared_ptr(BOOST_RV_REF(shared_ptr) other)
0179 : m_pn()
0180 { this->swap(other); }
0181
0182 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0183 template<class Y>
0184 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::static_cast_tag)
0185 : m_pn( pointer(static_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
0186 , r.m_pn)
0187 {}
0188
0189 template<class Y>
0190 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::const_cast_tag)
0191 : m_pn( pointer(const_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
0192 , r.m_pn)
0193 {}
0194
0195 template<class Y>
0196 shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::dynamic_cast_tag)
0197 : m_pn( pointer(dynamic_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
0198 , r.m_pn)
0199 {
0200 if(!m_pn.to_raw_pointer()){
0201 m_pn = ipcdetail::shared_count<T, VoidAllocator, Deleter>();
0202 }
0203 }
0204 #endif
0205
0206
0207
0208 template<class Y>
0209 shared_ptr & operator=(shared_ptr<Y, VoidAllocator, Deleter> const & r)
0210 {
0211 m_pn = r.m_pn;
0212 return *this;
0213 }
0214
0215
0216
0217 shared_ptr & operator=(BOOST_COPY_ASSIGN_REF(shared_ptr) r)
0218 {
0219 m_pn = r.m_pn;
0220 return *this;
0221 }
0222
0223
0224
0225 shared_ptr & operator=(BOOST_RV_REF(shared_ptr) other)
0226 {
0227 this_type(other).swap(*this);
0228 return *this;
0229 }
0230
0231
0232
0233 void reset()
0234 {
0235 this_type().swap(*this);
0236 }
0237
0238
0239
0240 template<class Pointer>
0241 void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
0242 {
0243
0244
0245 typedef typename boost::intrusive::
0246 pointer_traits<Pointer>::template
0247 rebind_pointer<T>::type ParameterPointer;
0248 BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
0249 (ipcdetail::is_pointer<Pointer>::value));
0250 this_type(p, a, d).swap(*this);
0251 }
0252
0253 template<class Y>
0254 void reset(shared_ptr<Y, VoidAllocator, Deleter> const & r, const pointer &p)
0255 {
0256 this_type(r, p).swap(*this);
0257 }
0258
0259
0260
0261 reference operator* () const
0262 { BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return *m_pn.to_raw_pointer(); }
0263
0264
0265
0266 pointer operator-> () const
0267 { BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return m_pn.to_raw_pointer(); }
0268
0269
0270
0271 pointer get() const
0272 { return m_pn.to_raw_pointer(); }
0273
0274 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0275
0276 void unspecified_bool_type_func() const {}
0277 typedef void (this_type::*unspecified_bool_type)() const;
0278
0279 operator unspecified_bool_type() const
0280 { return !m_pn.to_raw_pointer() ? 0 : &this_type::unspecified_bool_type_func; }
0281 #endif
0282
0283
0284
0285 bool operator! () const
0286 { return !m_pn.to_raw_pointer(); }
0287
0288
0289
0290 bool unique() const
0291 { return m_pn.unique(); }
0292
0293
0294
0295
0296
0297
0298 long use_count() const
0299 { return m_pn.use_count(); }
0300
0301
0302
0303 void swap(shared_ptr<T, VoidAllocator, Deleter> & other)
0304 { m_pn.swap(other.m_pn); }
0305
0306 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0307
0308 template<class T2, class A2, class Deleter2>
0309 bool _internal_less(shared_ptr<T2, A2, Deleter2> const & rhs) const
0310 { return m_pn < rhs.m_pn; }
0311
0312 const_deleter_pointer get_deleter() const
0313 { return m_pn.get_deleter(); }
0314
0315
0316
0317
0318 private:
0319
0320 template<class T2, class A2, class Deleter2> friend class shared_ptr;
0321 template<class T2, class A2, class Deleter2> friend class weak_ptr;
0322
0323 ipcdetail::shared_count<T, VoidAllocator, Deleter> m_pn;
0324 #endif
0325 };
0326
0327 template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
0328 bool operator==(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
0329 { return a.get() == b.get(); }
0330
0331 template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
0332 bool operator!=(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
0333 { return a.get() != b.get(); }
0334
0335 template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
0336 bool operator<(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
0337 { return a._internal_less(b); }
0338
0339 template<class T, class VoidAllocator, class Deleter> inline
0340 void swap(shared_ptr<T, VoidAllocator, Deleter> & a, shared_ptr<T, VoidAllocator, Deleter> & b)
0341 { a.swap(b); }
0342
0343 template<class T, class VoidAllocator, class Deleter, class U> inline
0344 shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
0345 { return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::static_cast_tag()); }
0346
0347 template<class T, class VoidAllocator, class Deleter, class U> inline
0348 shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
0349 { return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::const_cast_tag()); }
0350
0351 template<class T, class VoidAllocator, class Deleter, class U> inline
0352 shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
0353 { return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::dynamic_cast_tag()); }
0354
0355
0356 template<class T, class VoidAllocator, class Deleter> inline
0357 T * to_raw_pointer(shared_ptr<T, VoidAllocator, Deleter> const & p)
0358 { return p.get(); }
0359
0360
0361 template<class E, class T, class Y, class VoidAllocator, class Deleter> inline
0362 std::basic_ostream<E, T> & operator<<
0363 (std::basic_ostream<E, T> & os, shared_ptr<Y, VoidAllocator, Deleter> const & p)
0364 { os << p.get(); return os; }
0365
0366
0367
0368
0369
0370 template<class T, class ManagedMemory>
0371 struct managed_shared_ptr
0372 {
0373 typedef typename ManagedMemory::template allocator<void>::type void_allocator;
0374 typedef typename ManagedMemory::template deleter<T>::type deleter;
0375 typedef shared_ptr< T, void_allocator, deleter> type;
0376 };
0377
0378
0379
0380
0381 template<class T, class ManagedMemory>
0382 inline typename managed_shared_ptr<T, ManagedMemory>::type
0383 make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory)
0384 {
0385 return typename managed_shared_ptr<T, ManagedMemory>::type
0386 ( constructed_object
0387 , managed_memory.template get_allocator<void>()
0388 , managed_memory.template get_deleter<T>()
0389 );
0390 }
0391
0392
0393
0394
0395
0396 template<class T, class ManagedMemory>
0397 inline typename managed_shared_ptr<T, ManagedMemory>::type
0398 make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory, const std::nothrow_t &)
0399 {
0400 BOOST_TRY{
0401 return typename managed_shared_ptr<T, ManagedMemory>::type
0402 ( constructed_object
0403 , managed_memory.template get_allocator<void>()
0404 , managed_memory.template get_deleter<T>()
0405 );
0406 }
0407 BOOST_CATCH(...){
0408 return typename managed_shared_ptr<T, ManagedMemory>::type();
0409 } BOOST_CATCH_END
0410 }
0411
0412
0413 }
0414
0415 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0416
0417 #if defined(_MSC_VER) && (_MSC_VER < 1400)
0418
0419 template<class T, class VoidAllocator, class Deleter> inline
0420 T * to_raw_pointer(boost::interprocess::shared_ptr<T, VoidAllocator, Deleter> const & p)
0421 { return p.get(); }
0422 #endif
0423
0424 #endif
0425
0426 }
0427
0428 #include <boost/interprocess/detail/config_end.hpp>
0429
0430 #endif