Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:30

0001 #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
0002 #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
0003 
0004 #ifndef BOOST_CONFIG_HPP
0005 #  include <boost/config.hpp>
0006 #endif
0007 #
0008 #if defined(BOOST_HAS_PRAGMA_ONCE)
0009 # pragma once
0010 #endif
0011 
0012 //
0013 //  This file is the adaptation for shared memory memory mapped
0014 //  files of boost/detail/sp_counted_impl.hpp
0015 //
0016 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
0017 //  Copyright 2004-2005 Peter Dimov
0018 //  Copyright 2006      Ion Gaztanaga
0019 //
0020 // Distributed under the Boost Software License, Version 1.0. (See
0021 // accompanying file LICENSE_1_0.txt or copy at
0022 // http://www.boost.org/LICENSE_1_0.txt)
0023 //
0024 
0025 #include <boost/interprocess/detail/config_begin.hpp>
0026 #include <boost/interprocess/detail/workaround.hpp>
0027 
0028 #include <boost/interprocess/containers/version_type.hpp>
0029 #include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
0030 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
0031 #include <boost/interprocess/detail/utilities.hpp>
0032 #include <boost/container/allocator_traits.hpp>
0033 #include <boost/intrusive/pointer_traits.hpp>
0034 
0035 namespace boost {
0036 
0037 namespace interprocess {
0038 
0039 namespace ipcdetail {
0040 
0041 //!A deleter for scoped_ptr that deallocates the memory
0042 //!allocated for an object using a STL allocator.
0043 template <class Allocator>
0044 struct scoped_ptr_dealloc_functor
0045 {
0046    typedef typename boost::container::
0047       allocator_traits<Allocator>::pointer pointer;
0048 
0049    typedef ipcdetail::integral_constant<unsigned,
0050       boost::interprocess::version<Allocator>::value>                   alloc_version;
0051    typedef ipcdetail::integral_constant<unsigned, 1>     allocator_v1;
0052    typedef ipcdetail::integral_constant<unsigned, 2>     allocator_v2;
0053 
0054    private:
0055    void priv_deallocate(const pointer &p, allocator_v1)
0056    {  m_alloc.deallocate(p, 1); }
0057 
0058    void priv_deallocate(const pointer &p, allocator_v2)
0059    {  m_alloc.deallocate_one(p); }
0060 
0061    public:
0062    Allocator& m_alloc;
0063 
0064    scoped_ptr_dealloc_functor(Allocator& a)
0065       : m_alloc(a) {}
0066 
0067    void operator()(pointer ptr)
0068    {  if (ptr) priv_deallocate(ptr, alloc_version());  }
0069 };
0070 
0071 
0072 
0073 template<class A, class D>
0074 class sp_counted_impl_pd
0075    :  public sp_counted_base
0076    ,  boost::container::allocator_traits<A>::template
0077          portable_rebind_alloc< sp_counted_impl_pd<A, D> >::type
0078    ,  D  // copy constructor must not throw
0079 {
0080    private:
0081    typedef sp_counted_impl_pd<A, D>          this_type;
0082    typedef typename boost::container::
0083       allocator_traits<A>::template
0084          portable_rebind_alloc
0085             < this_type >::type              this_allocator;
0086    typedef typename boost::container::
0087       allocator_traits<A>::template
0088          portable_rebind_alloc
0089             < const this_type >::type        const_this_allocator;
0090    typedef typename boost::container::
0091       allocator_traits<this_allocator>
0092          ::pointer                           this_pointer;
0093    typedef typename boost::container::
0094       allocator_traits<A>::pointer           a_pointer;
0095    typedef typename boost::intrusive::
0096       pointer_traits<this_pointer>           this_pointer_traits;
0097 
0098    sp_counted_impl_pd( sp_counted_impl_pd const & );
0099    sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
0100 
0101    typedef typename boost::intrusive::
0102       pointer_traits<a_pointer>::template
0103          rebind_pointer<const D>::type                   const_deleter_pointer;
0104    typedef typename boost::intrusive::
0105       pointer_traits<a_pointer>::template
0106          rebind_pointer<const A>::type                   const_allocator_pointer;
0107 
0108    typedef typename D::pointer   pointer;
0109    pointer m_ptr;
0110 
0111    public:
0112    // pre: d(p) must not throw
0113    template<class Ptr>
0114    sp_counted_impl_pd(const Ptr & p, const A &a, const D &d )
0115       :  this_allocator(a), D(d), m_ptr(p)
0116    {}
0117 
0118    const_deleter_pointer get_deleter() const
0119    {  return const_deleter_pointer(&static_cast<const D&>(*this)); }
0120 
0121    const_allocator_pointer get_allocator() const
0122    {  return const_allocator_pointer(&static_cast<const A&>(*this)); }
0123 
0124    void dispose() // nothrow
0125    {  static_cast<D&>(*this)(m_ptr);   }
0126 
0127    void destroy() // nothrow
0128    {
0129       //Self destruction, so move the allocator
0130       this_allocator a_copy(::boost::move(static_cast<this_allocator&>(*this)));
0131       BOOST_ASSERT(a_copy == *this);
0132       this_pointer this_ptr(this_pointer_traits::pointer_to(*this));
0133       //Do it now!
0134       scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
0135          deleter_ptr(this_ptr, a_copy);
0136       ipcdetail::to_raw_pointer(this_ptr)->~this_type();
0137    }
0138 
0139    void release() // nothrow
0140    {
0141       if(this->ref_release()){
0142          this->dispose();
0143          this->weak_release();
0144       }
0145    }
0146 
0147    void weak_release() // nothrow
0148    {
0149       if(sp_counted_base::weak_release()){
0150          this->destroy();
0151       }
0152    }
0153 };
0154 
0155 
0156 } // namespace ipcdetail
0157 
0158 } // namespace interprocess
0159 
0160 } // namespace boost
0161 
0162 #include <boost/interprocess/detail/config_end.hpp>
0163 
0164 #endif  // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED