Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:53:28

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // This file is the adaptation for Interprocess of boost/detail/shared_count.hpp
0004 //
0005 // (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003
0006 // (C) Copyright Peter Dimov 2004-2005
0007 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
0008 // Software License, Version 1.0. (See accompanying file
0009 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // See http://www.boost.org/libs/interprocess for documentation.
0012 //
0013 //////////////////////////////////////////////////////////////////////////////
0014 #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
0015 #define BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
0016 
0017 #ifndef BOOST_CONFIG_HPP
0018 #  include <boost/config.hpp>
0019 #endif
0020 #
0021 #if defined(BOOST_HAS_PRAGMA_ONCE)
0022 # pragma once
0023 #endif
0024 
0025 #include <boost/interprocess/detail/config_begin.hpp>
0026 #include <boost/interprocess/detail/workaround.hpp>
0027 
0028 #include <boost/intrusive/pointer_traits.hpp>
0029 #include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
0030 #include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
0031 #include <boost/interprocess/detail/utilities.hpp>
0032 #include <boost/container/allocator_traits.hpp>
0033 #include <boost/move/adl_move_swap.hpp>
0034 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>   //std::less
0035 #include <boost/container/detail/placement_new.hpp>
0036 
0037 namespace boost {
0038 namespace interprocess {
0039 namespace ipcdetail{
0040 
0041 template<class T, class VoidAllocator, class Deleter>
0042 class weak_count;
0043 
0044 template<class T, class VoidAllocator, class Deleter>
0045 class shared_count
0046 {
0047    public:
0048 
0049    typedef typename boost::container::
0050       allocator_traits<VoidAllocator>::pointer              void_ptr;
0051    typedef typename boost::intrusive::
0052       pointer_traits<void_ptr>::template
0053          rebind_pointer<T>::type                            pointer;
0054 
0055    private:
0056    typedef sp_counted_impl_pd<VoidAllocator, Deleter>       counted_impl;
0057 
0058    typedef typename boost::intrusive::
0059       pointer_traits<void_ptr>::template
0060          rebind_pointer<counted_impl>::type                         counted_impl_ptr;
0061    typedef typename boost::intrusive::
0062       pointer_traits<void_ptr>::template
0063          rebind_pointer<sp_counted_base>::type                       counted_base_ptr;
0064 
0065    typedef boost::container::allocator_traits<VoidAllocator>         vallocator_traits;
0066 
0067    typedef typename vallocator_traits::template
0068       portable_rebind_alloc<counted_impl>::type                      counted_impl_allocator;
0069 
0070    typedef typename boost::intrusive::
0071       pointer_traits<void_ptr>::template
0072          rebind_pointer<const Deleter>::type                         const_deleter_pointer;
0073 
0074    typedef typename boost::intrusive::
0075       pointer_traits<void_ptr>::template
0076          rebind_pointer<const VoidAllocator>::type                   const_allocator_pointer;
0077 
0078    pointer           m_px;
0079    counted_impl_ptr  m_pi;
0080 
0081    template <class T2, class VoidAllocator2, class Deleter2>
0082    friend class weak_count;
0083 
0084    template <class T2, class VoidAllocator2, class Deleter2>
0085    friend class shared_count;
0086 
0087    public:
0088 
0089    shared_count()
0090       :  m_px(0), m_pi(0) // nothrow
0091    {}
0092 
0093    template <class Ptr>
0094    shared_count(const shared_count &other_shared_count, const Ptr &p)
0095       :  m_px(p), m_pi(other_shared_count.m_pi)
0096    {}
0097 
0098    template <class Ptr>
0099    shared_count(const Ptr &p, const VoidAllocator &a, Deleter d)
0100       :  m_px(p), m_pi(0)
0101    {
0102       BOOST_INTERPROCESS_TRY{
0103          if(p){
0104             counted_impl_allocator alloc(a);
0105             m_pi = alloc.allocate(1);
0106             //Anti-exception deallocator
0107             scoped_ptr<counted_impl,
0108                      scoped_ptr_dealloc_functor<counted_impl_allocator> >
0109                         deallocator(m_pi, alloc);
0110             //It's more correct to use VoidAllocator::construct but
0111             //this needs copy constructor and we don't like it
0112             ::new(ipcdetail::to_raw_pointer(m_pi), boost_container_new_t())counted_impl(p, a, d);
0113             deallocator.release();
0114          }
0115       }
0116       BOOST_INTERPROCESS_CATCH (...){
0117          d(p); // delete p
0118          BOOST_INTERPROCESS_RETHROW
0119       }
0120       BOOST_INTERPROCESS_CATCH_END
0121    }
0122 
0123    ~shared_count() // nothrow
0124    {
0125       if(m_pi)
0126          m_pi->release();
0127    }
0128 
0129    shared_count(shared_count const & r)
0130       :  m_px(r.m_px), m_pi(r.m_pi) // nothrow
0131    { if( m_pi != 0 ) m_pi->add_ref_copy(); }
0132 
0133    //this is a test
0134    template<class Y>
0135    explicit shared_count(shared_count<Y, VoidAllocator, Deleter> const & r)
0136       :  m_px(r.m_px), m_pi(r.m_pi) // nothrow
0137    {  if( m_pi != 0 ) m_pi->add_ref_copy();  }
0138 
0139    //this is a test
0140    template<class Y>
0141    explicit shared_count(const pointer & ptr, shared_count<Y, VoidAllocator, Deleter> const & r)
0142       :  m_px(ptr), m_pi(r.m_pi) // nothrow
0143    {  if( m_pi != 0 ) m_pi->add_ref_copy();  }
0144 
0145 /*
0146    explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
0147       // throws bad_weak_ptr when r.use_count() == 0
0148       : m_pi( r.m_pi )
0149    {
0150       if( m_pi == 0 || !m_pi->add_ref_lock() ){
0151          boost::throw_exception( boost::interprocess::bad_weak_ptr() );
0152       }
0153    }
0154 */
0155    template<class Y>
0156    explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
0157       // throws bad_weak_ptr when r.use_count() == 0
0158       : m_px(r.m_px), m_pi( r.m_pi )
0159    {
0160       if( m_pi == 0 || !m_pi->add_ref_lock() ){
0161          throw( boost::interprocess::bad_weak_ptr() );
0162       }
0163    }
0164 
0165    const pointer &to_raw_pointer() const
0166    {  return m_px;   }
0167 
0168    pointer &to_raw_pointer()
0169    {  return m_px;   }
0170 
0171    shared_count & operator= (shared_count const & r) // nothrow
0172    {
0173       m_px = r.m_px;
0174       counted_impl_ptr tmp = r.m_pi;
0175       if( tmp != m_pi ){
0176          if(tmp != 0)   tmp->add_ref_copy();
0177          if(m_pi != 0)  m_pi->release();
0178          m_pi = tmp;
0179       }
0180       return *this;
0181    }
0182 
0183    template<class Y>
0184    shared_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
0185    {
0186       m_px = r.m_px;
0187       counted_impl_ptr tmp = r.m_pi;
0188       if( tmp != m_pi ){
0189          if(tmp != 0)   tmp->add_ref_copy();
0190          if(m_pi != 0)  m_pi->release();
0191          m_pi = tmp;
0192       }
0193       return *this;
0194    }
0195 
0196    void swap(shared_count & r) // nothrow
0197    {  ::boost::adl_move_swap(m_px, r.m_px);  ::boost::adl_move_swap(m_pi, r.m_pi);   }
0198 
0199    long use_count() const // nothrow
0200    {  return m_pi != 0? m_pi->use_count(): 0;  }
0201 
0202    bool unique() const // nothrow
0203    {  return use_count() == 1;   }
0204 
0205    const_deleter_pointer get_deleter() const
0206    {  return m_pi ? m_pi->get_deleter() : 0; }
0207 
0208 //   const_allocator_pointer get_allocator() const
0209 //   {  return m_pi ? m_pi->get_allocator() : 0; }
0210 
0211    template<class T2, class VoidAllocator2, class Deleter2>
0212    bool internal_equal (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
0213    {  return this->m_pi == other.m_pi;   }
0214 
0215    template<class T2, class VoidAllocator2, class Deleter2>
0216    bool internal_less  (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
0217    {  return std::less<counted_base_ptr>()(this->m_pi, other.m_pi);  }
0218 };
0219 
0220 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
0221 bool operator==(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
0222 {  return a.internal_equal(b);  }
0223 
0224 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
0225 bool operator<(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
0226 {  return a.internal_less(b);   }
0227 
0228 
0229 template<class T, class VoidAllocator, class Deleter>
0230 class weak_count
0231 {
0232    public:
0233    typedef typename boost::container::
0234       allocator_traits<VoidAllocator>::pointer           void_ptr;
0235    typedef typename boost::intrusive::
0236       pointer_traits<void_ptr>::template
0237          rebind_pointer<T>::type                         pointer;
0238 
0239    private:
0240 
0241    typedef sp_counted_impl_pd<VoidAllocator, Deleter>                counted_impl;
0242 
0243    typedef typename boost::intrusive::
0244       pointer_traits<void_ptr>::template
0245          rebind_pointer<counted_impl>::type                          counted_impl_ptr;
0246    typedef typename boost::intrusive::
0247       pointer_traits<void_ptr>::template
0248          rebind_pointer<sp_counted_base>::type                       counted_base_ptr;
0249 
0250    pointer           m_px;
0251    counted_impl_ptr  m_pi;
0252 
0253    template <class T2, class VoidAllocator2, class Deleter2>
0254    friend class weak_count;
0255 
0256    template <class T2, class VoidAllocator2, class Deleter2>
0257    friend class shared_count;
0258 
0259    public:
0260 
0261    weak_count(): m_px(0), m_pi(0) // nothrow
0262    {}
0263 
0264    template <class Y>
0265    explicit weak_count(shared_count<Y, VoidAllocator, Deleter> const & r)
0266       :  m_px(r.m_px), m_pi(r.m_pi) // nothrow
0267    {  if(m_pi != 0) m_pi->weak_add_ref(); }
0268 
0269    weak_count(weak_count const & r)
0270       :  m_px(r.m_px), m_pi(r.m_pi) // nothrow
0271    {  if(m_pi != 0) m_pi->weak_add_ref(); }
0272 
0273    template<class Y>
0274    weak_count(weak_count<Y, VoidAllocator, Deleter> const & r)
0275       : m_px(r.m_px), m_pi(r.m_pi) // nothrow
0276    {  if(m_pi != 0) m_pi->weak_add_ref(); }
0277 
0278    ~weak_count() // nothrow
0279    {  if(m_pi != 0) m_pi->weak_release(); }
0280 
0281    template<class Y>
0282    weak_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
0283    {
0284       m_px = r.m_px;
0285       counted_impl_ptr tmp = r.m_pi;
0286       if(tmp != 0)   tmp->weak_add_ref();
0287       if(m_pi != 0)  m_pi->weak_release();
0288       m_pi = tmp;
0289       return *this;
0290    }
0291 
0292    weak_count & operator= (weak_count const & r) // nothrow
0293    {
0294       m_px = r.m_px;
0295       counted_impl_ptr tmp = r.m_pi;
0296       if(tmp != 0) tmp->weak_add_ref();
0297       if(m_pi != 0) m_pi->weak_release();
0298       m_pi = tmp;
0299       return *this;
0300    }
0301 
0302    void set_pointer(const pointer &ptr)
0303    {  m_px = ptr; }
0304 
0305    template<class Y>
0306    weak_count & operator= (weak_count<Y, VoidAllocator, Deleter> const& r) // nothrow
0307    {
0308       counted_impl_ptr tmp = r.m_pi;
0309       if(tmp != 0) tmp->weak_add_ref();
0310       if(m_pi != 0) m_pi->weak_release();
0311       m_pi = tmp;
0312       return *this;
0313    }
0314 
0315    void swap(weak_count & r) // nothrow
0316    {  ::boost::adl_move_swap(m_px, r.m_px);  ::boost::adl_move_swap(m_pi, r.m_pi);   }
0317 
0318    long use_count() const // nothrow
0319    {  return m_pi != 0? m_pi->use_count() : 0;   }
0320 
0321    template<class T2, class VoidAllocator2, class Deleter2>
0322    bool internal_equal (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
0323    {  return this->m_pi == other.m_pi;   }
0324 
0325    template<class T2, class VoidAllocator2, class Deleter2>
0326    bool internal_less (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
0327    {  return std::less<counted_base_ptr>()(this->m_pi, other.m_pi);  }
0328 };
0329 
0330 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
0331 bool operator==(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
0332 {  return a.internal_equal(b);  }
0333 
0334 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
0335 bool operator<(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
0336 {  return a.internal_less(b);   }
0337 
0338 } // namespace ipcdetail
0339 } // namespace interprocess
0340 } // namespace boost
0341 
0342 
0343 #include <boost/interprocess/detail/config_end.hpp>
0344 
0345 
0346 #endif  // #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED