Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:14:19

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