]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / interprocess / smart_ptr / detail / sp_counted_impl.hpp
1 #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
2 #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
3
4 #ifndef BOOST_CONFIG_HPP
5 # include <boost/config.hpp>
6 #endif
7 #
8 #if defined(BOOST_HAS_PRAGMA_ONCE)
9 # pragma once
10 #endif
11
12 //
13 // This file is the adaptation for shared memory memory mapped
14 // files of boost/detail/sp_counted_impl.hpp
15 //
16 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
17 // Copyright 2004-2005 Peter Dimov
18 // Copyright 2006 Ion Gaztanaga
19 //
20 // Distributed under the Boost Software License, Version 1.0. (See
21 // accompanying file LICENSE_1_0.txt or copy at
22 // http://www.boost.org/LICENSE_1_0.txt)
23 //
24
25 #include <boost/interprocess/detail/config_begin.hpp>
26 #include <boost/interprocess/detail/workaround.hpp>
27
28 #include <boost/interprocess/containers/version_type.hpp>
29 #include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
30 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
31 #include <boost/interprocess/detail/utilities.hpp>
32 #include <boost/container/allocator_traits.hpp>
33 #include <boost/intrusive/pointer_traits.hpp>
34
35 namespace boost {
36
37 namespace interprocess {
38
39 namespace ipcdetail {
40
41 //!A deleter for scoped_ptr that deallocates the memory
42 //!allocated for an object using a STL allocator.
43 template <class Allocator>
44 struct scoped_ptr_dealloc_functor
45 {
46 typedef typename boost::container::
47 allocator_traits<Allocator>::pointer pointer;
48
49 typedef ipcdetail::integral_constant<unsigned,
50 boost::interprocess::version<Allocator>::value> alloc_version;
51 typedef ipcdetail::integral_constant<unsigned, 1> allocator_v1;
52 typedef ipcdetail::integral_constant<unsigned, 2> allocator_v2;
53
54 private:
55 void priv_deallocate(const pointer &p, allocator_v1)
56 { m_alloc.deallocate(p, 1); }
57
58 void priv_deallocate(const pointer &p, allocator_v2)
59 { m_alloc.deallocate_one(p); }
60
61 public:
62 Allocator& m_alloc;
63
64 scoped_ptr_dealloc_functor(Allocator& a)
65 : m_alloc(a) {}
66
67 void operator()(pointer ptr)
68 { if (ptr) priv_deallocate(ptr, alloc_version()); }
69 };
70
71
72
73 template<class A, class D>
74 class sp_counted_impl_pd
75 : public sp_counted_base
76 , boost::container::allocator_traits<A>::template
77 portable_rebind_alloc< sp_counted_impl_pd<A, D> >::type
78 , D // copy constructor must not throw
79 {
80 private:
81 typedef sp_counted_impl_pd<A, D> this_type;
82 typedef typename boost::container::
83 allocator_traits<A>::template
84 portable_rebind_alloc
85 < this_type >::type this_allocator;
86 typedef typename boost::container::
87 allocator_traits<A>::template
88 portable_rebind_alloc
89 < const this_type >::type const_this_allocator;
90 typedef typename boost::container::
91 allocator_traits<this_allocator>
92 ::pointer this_pointer;
93 typedef typename boost::container::
94 allocator_traits<A>::pointer a_pointer;
95 typedef typename boost::intrusive::
96 pointer_traits<this_pointer> this_pointer_traits;
97
98 sp_counted_impl_pd( sp_counted_impl_pd const & );
99 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
100
101 typedef typename boost::intrusive::
102 pointer_traits<a_pointer>::template
103 rebind_pointer<const D>::type const_deleter_pointer;
104 typedef typename boost::intrusive::
105 pointer_traits<a_pointer>::template
106 rebind_pointer<const A>::type const_allocator_pointer;
107
108 typedef typename D::pointer pointer;
109 pointer m_ptr;
110
111 public:
112 // pre: d(p) must not throw
113 template<class Ptr>
114 sp_counted_impl_pd(const Ptr & p, const A &a, const D &d )
115 : this_allocator(a), D(d), m_ptr(p)
116 {}
117
118 const_deleter_pointer get_deleter() const
119 { return const_deleter_pointer(&static_cast<const D&>(*this)); }
120
121 const_allocator_pointer get_allocator() const
122 { return const_allocator_pointer(&static_cast<const A&>(*this)); }
123
124 void dispose() // nothrow
125 { static_cast<D&>(*this)(m_ptr); }
126
127 void destroy() // nothrow
128 {
129 //Self destruction, so move the allocator
130 this_allocator a_copy(::boost::move(static_cast<this_allocator&>(*this)));
131 BOOST_ASSERT(a_copy == *this);
132 this_pointer this_ptr(this_pointer_traits::pointer_to(*this));
133 //Do it now!
134 scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
135 deleter_ptr(this_ptr, a_copy);
136 ipcdetail::to_raw_pointer(this_ptr)->~this_type();
137 }
138
139 void release() // nothrow
140 {
141 if(this->ref_release()){
142 this->dispose();
143 this->weak_release();
144 }
145 }
146
147 void weak_release() // nothrow
148 {
149 if(sp_counted_base::weak_release()){
150 this->destroy();
151 }
152 }
153 };
154
155
156 } // namespace ipcdetail
157
158 } // namespace interprocess
159
160 } // namespace boost
161
162 #include <boost/interprocess/detail/config_end.hpp>
163
164 #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED