Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:46:56

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // This file is the adaptation for Interprocess of boost/shared_ptr.hpp
0004 //
0005 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
0006 // (C) Copyright Peter Dimov 2001, 2002, 2003
0007 // (C) Copyright Ion Gaztanaga 2006-2012.
0008 // Distributed under the Boost Software License, Version 1.0.
0009 // (See accompanying file LICENSE_1_0.txt or copy at
0010 // http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // See http://www.boost.org/libs/interprocess for documentation.
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 //!\file
0045 //!Describes the smart pointer shared_ptr
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 } // namespace ipcdetail
0073 
0074 //!shared_ptr stores a pointer to a dynamically allocated object.
0075 //!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
0076 //!it is destroyed or reset.
0077 //!
0078 //!shared_ptr is parameterized on
0079 //!T (the type of the object pointed to), VoidAllocator (the void allocator to be used
0080 //!to allocate the auxiliary data) and Deleter (the deleter whose
0081 //!operator() will be used to delete the object.
0082 //!
0083 //!The internal pointer will be of the same pointer type as typename
0084 //!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is
0085 //!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
0086 //!
0087 //!Because the implementation uses reference counting, cycles of shared_ptr
0088 //!instances will not be reclaimed. For example, if main() holds a
0089 //!shared_ptr to A, which directly or indirectly holds a shared_ptr back
0090 //!to A, A's use count will be 2. Destruction of the original shared_ptr
0091 //!will leave A dangling with a use count of 1.
0092 //!Use weak_ptr to "break cycles."
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   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
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    //!Constructs an empty shared_ptr.
0125    //!Use_count() == 0 && get()== 0.
0126    shared_ptr()
0127       :  m_pn() // never throws
0128    {}
0129 
0130    //!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated
0131    //!with a copy of a and the object will be deleted with a copy of d.
0132    //!Requirements: Deleter and A's copy constructor must not throw.
0133    explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
0134       :  m_pn(p, a, d)
0135    {
0136       //Check that the pointer passed is of the same type that
0137       //the pointer the allocator defines or it's a raw pointer
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    //!Copy constructs a shared_ptr. If r is empty, constructs an empty shared_ptr. Otherwise, constructs
0148    //!a shared_ptr that shares ownership with r. Never throws.
0149    shared_ptr(const shared_ptr &r)
0150       :  m_pn(r.m_pn) // never throws
0151    {}
0152 
0153    //!Constructs a shared_ptr that shares ownership with other and stores p.
0154    //!Postconditions: get() == p && use_count() == r.use_count().
0155    //!Throws: nothing.
0156    shared_ptr(const shared_ptr &other, const pointer &p)
0157       :  m_pn(other.m_pn, p)
0158    {}
0159 
0160    //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
0161    //!a shared_ptr that shares ownership with r. Never throws.
0162    template<class Y>
0163    shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
0164       :  m_pn(r.m_pn) // never throws
0165    {}
0166 
0167    //!Constructs a shared_ptr that shares ownership with r and stores
0168    //!a copy of the pointer stored in r.
0169    template<class Y>
0170    explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
0171       :  m_pn(r.m_pn) // may throw
0172    {}
0173 
0174    //!Move-Constructs a shared_ptr that takes ownership of other resource and
0175    //!other is put in default-constructed state.
0176    //!Throws: nothing.
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()){ // need to allocate new counter -- the cast failed
0200          m_pn = ipcdetail::shared_count<T, VoidAllocator, Deleter>();
0201       }
0202    }
0203    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0204 
0205    //!Equivalent to shared_ptr(r).swap(*this).
0206    //!Never throws
0207    template<class Y>
0208    shared_ptr & operator=(shared_ptr<Y, VoidAllocator, Deleter> const & r)
0209    {
0210       m_pn = r.m_pn; // shared_count::op= doesn't throw
0211       return *this;
0212    }
0213 
0214    //!Equivalent to shared_ptr(r).swap(*this).
0215    //!Never throws
0216    shared_ptr & operator=(BOOST_COPY_ASSIGN_REF(shared_ptr) r)
0217    {
0218       m_pn = r.m_pn; // shared_count::op= doesn't throw
0219       return *this;
0220    }
0221 
0222    //!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
0223    //!Never throws
0224    shared_ptr & operator=(BOOST_RV_REF(shared_ptr) other) // never throws
0225    {
0226       this_type(other).swap(*this);
0227       return *this;
0228    }
0229 
0230    //!This is equivalent to:
0231    //!this_type().swap(*this);
0232    void reset()
0233    {
0234       this_type().swap(*this);
0235    }
0236 
0237    //!This is equivalent to:
0238    //!this_type(p, a, d).swap(*this);
0239    template<class Pointer>
0240    void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
0241    {
0242       //Check that the pointer passed is of the same type that
0243       //the pointer the allocator defines or it's a raw pointer
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    //!Returns a reference to the
0259    //!pointed type
0260    reference operator* () const // never throws
0261    {  BOOST_ASSERT(m_pn.to_raw_pointer() != 0);  return *m_pn.to_raw_pointer(); }
0262 
0263    //!Returns the pointer pointing
0264    //!to the owned object
0265    pointer operator-> () const // never throws
0266    {  BOOST_ASSERT(m_pn.to_raw_pointer() != 0);  return m_pn.to_raw_pointer();  }
0267 
0268    //!Returns the pointer pointing
0269    //!to the owned object
0270    pointer get() const  // never throws
0271    {  return m_pn.to_raw_pointer();  }
0272 
0273    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0274    // implicit conversion to "bool"
0275    void unspecified_bool_type_func() const {}
0276    typedef void (this_type::*unspecified_bool_type)() const;
0277 
0278    operator unspecified_bool_type() const // never throws
0279    {  return !m_pn.to_raw_pointer() ? 0 : &this_type::unspecified_bool_type_func;  }
0280    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0281 
0282    //!Not operator.
0283    //!Returns true if this->get() != 0, false otherwise
0284    bool operator! () const // never throws
0285    {  return !m_pn.to_raw_pointer();   }
0286 
0287    //!Returns use_count() == 1.
0288    //!unique() might be faster than use_count()
0289    bool unique() const // never throws
0290    {  return m_pn.unique();  }
0291 
0292    //!Returns the number of shared_ptr objects, *this included,
0293    //!that share ownership with *this, or an unspecified nonnegative
0294    //!value when *this is empty.
0295    //!use_count() is not necessarily efficient. Use only for
0296    //!debugging and testing purposes, not for production code.
0297    long use_count() const // never throws
0298    {  return m_pn.use_count();  }
0299 
0300    //!Exchanges the contents of the two
0301    //!smart pointers.
0302    void swap(shared_ptr<T, VoidAllocator, Deleter> & other) // never throws
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 //   const_allocator_pointer get_allocator() const
0315 //   {  return m_pn.get_allocator(); }
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;    // reference counter
0323    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0324 };  // shared_ptr
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 // to_raw_pointer() enables boost::mem_fn to recognize shared_ptr
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 // operator<<
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 //!Returns the type of a shared pointer
0366 //!of type T with the allocator boost::interprocess::allocator allocator
0367 //!and boost::interprocess::deleter deleter
0368 //!that can be constructed in the given managed segment type.
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 //!Returns an instance of a shared pointer constructed
0378 //!with the default allocator and deleter from a pointer
0379 //!of type T that has been allocated in the passed managed segment
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 //!Returns an instance of a shared pointer constructed
0392 //!with the default allocator and deleter from a pointer
0393 //!of type T that has been allocated in the passed managed segment.
0394 //!Does not throw, return null shared pointer in error.
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 } // namespace interprocess
0413 
0414 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0415 
0416 #if defined(_MSC_VER) && (_MSC_VER < 1400)
0417 // to_raw_pointer() enables boost::mem_fn to recognize shared_ptr
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   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0424 
0425 } // namespace boost
0426 
0427 #include <boost/interprocess/detail/config_end.hpp>
0428 
0429 #endif  // #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED