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