annotate DEPENDENCIES/generic/include/boost/interprocess/smart_ptr/detail/shared_count.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // This file is the adaptation for Interprocess of boost/detail/shared_count.hpp
Chris@16 4 //
Chris@16 5 // (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003
Chris@16 6 // (C) Copyright Peter Dimov 2004-2005
Chris@16 7 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
Chris@16 8 // Software License, Version 1.0. (See accompanying file
Chris@16 9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10 //
Chris@16 11 // See http://www.boost.org/libs/interprocess for documentation.
Chris@16 12 //
Chris@16 13 //////////////////////////////////////////////////////////////////////////////
Chris@16 14 #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
Chris@16 15 #define BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
Chris@16 16
Chris@101 17 #ifndef BOOST_CONFIG_HPP
Chris@101 18 # include <boost/config.hpp>
Chris@101 19 #endif
Chris@101 20 #
Chris@101 21 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@16 22 # pragma once
Chris@16 23 #endif
Chris@16 24
Chris@16 25 #include <boost/interprocess/detail/config_begin.hpp>
Chris@16 26 #include <boost/interprocess/detail/workaround.hpp>
Chris@16 27
Chris@16 28 #include <boost/checked_delete.hpp>
Chris@16 29 #include <boost/intrusive/pointer_traits.hpp>
Chris@16 30 #include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
Chris@16 31 #include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
Chris@16 32 #include <boost/interprocess/detail/utilities.hpp>
Chris@16 33 #include <boost/container/allocator_traits.hpp>
Chris@101 34 #include <boost/core/no_exceptions_support.hpp>
Chris@101 35 #include <boost/move/adl_move_swap.hpp>
Chris@101 36 #include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
Chris@101 37 #include <boost/container/detail/placement_new.hpp>
Chris@16 38
Chris@16 39 namespace boost {
Chris@16 40 namespace interprocess {
Chris@16 41 namespace ipcdetail{
Chris@16 42
Chris@16 43 template<class T, class VoidAllocator, class Deleter>
Chris@16 44 class weak_count;
Chris@16 45
Chris@16 46 template<class T, class VoidAllocator, class Deleter>
Chris@16 47 class shared_count
Chris@16 48 {
Chris@16 49 public:
Chris@16 50 typedef typename boost::intrusive::
Chris@16 51 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 52 rebind_pointer<T>::type pointer;
Chris@16 53
Chris@16 54 private:
Chris@16 55 typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
Chris@16 56
Chris@16 57 typedef typename boost::intrusive::
Chris@16 58 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 59 rebind_pointer<counted_impl>::type counted_impl_ptr;
Chris@16 60 typedef typename boost::intrusive::
Chris@16 61 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 62 rebind_pointer<sp_counted_base>::type counted_base_ptr;
Chris@16 63
Chris@16 64 typedef boost::container::allocator_traits<VoidAllocator> vallocator_traits;
Chris@16 65
Chris@16 66 typedef typename vallocator_traits::template
Chris@16 67 portable_rebind_alloc<counted_impl>::type counted_impl_allocator;
Chris@16 68
Chris@16 69 typedef typename boost::intrusive::
Chris@16 70 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 71 rebind_pointer<const Deleter>::type const_deleter_pointer;
Chris@16 72
Chris@16 73 typedef typename boost::intrusive::
Chris@16 74 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 75 rebind_pointer<const VoidAllocator>::type const_allocator_pointer;
Chris@16 76
Chris@16 77 pointer m_px;
Chris@16 78 counted_impl_ptr m_pi;
Chris@16 79
Chris@16 80 template <class T2, class VoidAllocator2, class Deleter2>
Chris@16 81 friend class weak_count;
Chris@16 82
Chris@16 83 template <class T2, class VoidAllocator2, class Deleter2>
Chris@16 84 friend class shared_count;
Chris@16 85
Chris@16 86 public:
Chris@16 87
Chris@16 88 shared_count()
Chris@16 89 : m_px(0), m_pi(0) // nothrow
Chris@16 90 {}
Chris@16 91
Chris@16 92 template <class Ptr>
Chris@16 93 shared_count(const shared_count &other_shared_count, const Ptr &p)
Chris@16 94 : m_px(p), m_pi(other_shared_count.m_pi)
Chris@16 95 {}
Chris@16 96
Chris@16 97 template <class Ptr>
Chris@16 98 shared_count(const Ptr &p, const VoidAllocator &a, Deleter d)
Chris@16 99 : m_px(p), m_pi(0)
Chris@16 100 {
Chris@16 101 BOOST_TRY{
Chris@16 102 if(p){
Chris@16 103 counted_impl_allocator alloc(a);
Chris@16 104 m_pi = alloc.allocate(1);
Chris@16 105 //Anti-exception deallocator
Chris@16 106 scoped_ptr<counted_impl,
Chris@16 107 scoped_ptr_dealloc_functor<counted_impl_allocator> >
Chris@16 108 deallocator(m_pi, alloc);
Chris@16 109 //It's more correct to use VoidAllocator::construct but
Chris@16 110 //this needs copy constructor and we don't like it
Chris@101 111 ::new(ipcdetail::to_raw_pointer(m_pi), boost_container_new_t())counted_impl(p, a, d);
Chris@16 112 deallocator.release();
Chris@16 113 }
Chris@16 114 }
Chris@16 115 BOOST_CATCH (...){
Chris@16 116 d(p); // delete p
Chris@16 117 BOOST_RETHROW
Chris@16 118 }
Chris@16 119 BOOST_CATCH_END
Chris@16 120 }
Chris@16 121
Chris@16 122 ~shared_count() // nothrow
Chris@16 123 {
Chris@16 124 if(m_pi)
Chris@16 125 m_pi->release();
Chris@16 126 }
Chris@16 127
Chris@16 128 shared_count(shared_count const & r)
Chris@16 129 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
Chris@16 130 { if( m_pi != 0 ) m_pi->add_ref_copy(); }
Chris@16 131
Chris@16 132 //this is a test
Chris@16 133 template<class Y>
Chris@16 134 explicit shared_count(shared_count<Y, VoidAllocator, Deleter> const & r)
Chris@16 135 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
Chris@16 136 { if( m_pi != 0 ) m_pi->add_ref_copy(); }
Chris@16 137
Chris@16 138 //this is a test
Chris@16 139 template<class Y>
Chris@16 140 explicit shared_count(const pointer & ptr, shared_count<Y, VoidAllocator, Deleter> const & r)
Chris@16 141 : m_px(ptr), m_pi(r.m_pi) // nothrow
Chris@16 142 { if( m_pi != 0 ) m_pi->add_ref_copy(); }
Chris@16 143
Chris@16 144 /*
Chris@16 145 explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
Chris@16 146 // throws bad_weak_ptr when r.use_count() == 0
Chris@16 147 : m_pi( r.m_pi )
Chris@16 148 {
Chris@16 149 if( m_pi == 0 || !m_pi->add_ref_lock() ){
Chris@16 150 boost::throw_exception( boost::interprocess::bad_weak_ptr() );
Chris@16 151 }
Chris@16 152 }
Chris@16 153 */
Chris@16 154 template<class Y>
Chris@16 155 explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
Chris@16 156 // throws bad_weak_ptr when r.use_count() == 0
Chris@16 157 : m_px(r.m_px), m_pi( r.m_pi )
Chris@16 158 {
Chris@16 159 if( m_pi == 0 || !m_pi->add_ref_lock() ){
Chris@16 160 throw( boost::interprocess::bad_weak_ptr() );
Chris@16 161 }
Chris@16 162 }
Chris@16 163
Chris@16 164 const pointer &to_raw_pointer() const
Chris@16 165 { return m_px; }
Chris@16 166
Chris@16 167 pointer &to_raw_pointer()
Chris@16 168 { return m_px; }
Chris@16 169
Chris@16 170 shared_count & operator= (shared_count const & r) // nothrow
Chris@16 171 {
Chris@16 172 m_px = r.m_px;
Chris@16 173 counted_impl_ptr tmp = r.m_pi;
Chris@16 174 if( tmp != m_pi ){
Chris@16 175 if(tmp != 0) tmp->add_ref_copy();
Chris@16 176 if(m_pi != 0) m_pi->release();
Chris@16 177 m_pi = tmp;
Chris@16 178 }
Chris@16 179 return *this;
Chris@16 180 }
Chris@16 181
Chris@16 182 template<class Y>
Chris@16 183 shared_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
Chris@16 184 {
Chris@16 185 m_px = r.m_px;
Chris@16 186 counted_impl_ptr tmp = r.m_pi;
Chris@16 187 if( tmp != m_pi ){
Chris@16 188 if(tmp != 0) tmp->add_ref_copy();
Chris@16 189 if(m_pi != 0) m_pi->release();
Chris@16 190 m_pi = tmp;
Chris@16 191 }
Chris@16 192 return *this;
Chris@16 193 }
Chris@16 194
Chris@16 195 void swap(shared_count & r) // nothrow
Chris@101 196 { ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_swap(m_pi, r.m_pi); }
Chris@16 197
Chris@16 198 long use_count() const // nothrow
Chris@16 199 { return m_pi != 0? m_pi->use_count(): 0; }
Chris@16 200
Chris@16 201 bool unique() const // nothrow
Chris@16 202 { return use_count() == 1; }
Chris@16 203
Chris@16 204 const_deleter_pointer get_deleter() const
Chris@16 205 { return m_pi ? m_pi->get_deleter() : 0; }
Chris@16 206
Chris@16 207 // const_allocator_pointer get_allocator() const
Chris@16 208 // { return m_pi ? m_pi->get_allocator() : 0; }
Chris@16 209
Chris@16 210 template<class T2, class VoidAllocator2, class Deleter2>
Chris@16 211 bool internal_equal (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
Chris@16 212 { return this->m_pi == other.m_pi; }
Chris@16 213
Chris@16 214 template<class T2, class VoidAllocator2, class Deleter2>
Chris@16 215 bool internal_less (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
Chris@16 216 { return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
Chris@16 217 };
Chris@16 218
Chris@16 219 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
Chris@16 220 bool operator==(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
Chris@16 221 { return a.internal_equal(b); }
Chris@16 222
Chris@16 223 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
Chris@16 224 bool operator<(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
Chris@16 225 { return a.internal_less(b); }
Chris@16 226
Chris@16 227
Chris@16 228 template<class T, class VoidAllocator, class Deleter>
Chris@16 229 class weak_count
Chris@16 230 {
Chris@16 231 public:
Chris@16 232 typedef typename boost::intrusive::
Chris@16 233 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 234 rebind_pointer<T>::type pointer;
Chris@16 235
Chris@16 236 private:
Chris@16 237
Chris@16 238 typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
Chris@16 239
Chris@16 240 typedef typename boost::intrusive::
Chris@16 241 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 242 rebind_pointer<counted_impl>::type counted_impl_ptr;
Chris@16 243 typedef typename boost::intrusive::
Chris@16 244 pointer_traits<typename VoidAllocator::pointer>::template
Chris@16 245 rebind_pointer<sp_counted_base>::type counted_base_ptr;
Chris@16 246
Chris@16 247 pointer m_px;
Chris@16 248 counted_impl_ptr m_pi;
Chris@16 249
Chris@16 250 template <class T2, class VoidAllocator2, class Deleter2>
Chris@16 251 friend class weak_count;
Chris@16 252
Chris@16 253 template <class T2, class VoidAllocator2, class Deleter2>
Chris@16 254 friend class shared_count;
Chris@16 255
Chris@16 256 public:
Chris@16 257
Chris@16 258 weak_count(): m_px(0), m_pi(0) // nothrow
Chris@16 259 {}
Chris@16 260
Chris@16 261 template <class Y>
Chris@16 262 explicit weak_count(shared_count<Y, VoidAllocator, Deleter> const & r)
Chris@16 263 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
Chris@16 264 { if(m_pi != 0) m_pi->weak_add_ref(); }
Chris@16 265
Chris@16 266 weak_count(weak_count const & r)
Chris@16 267 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
Chris@16 268 { if(m_pi != 0) m_pi->weak_add_ref(); }
Chris@16 269
Chris@16 270 template<class Y>
Chris@16 271 weak_count(weak_count<Y, VoidAllocator, Deleter> const & r)
Chris@16 272 : m_px(r.m_px), m_pi(r.m_pi) // nothrow
Chris@16 273 { if(m_pi != 0) m_pi->weak_add_ref(); }
Chris@16 274
Chris@16 275 ~weak_count() // nothrow
Chris@16 276 { if(m_pi != 0) m_pi->weak_release(); }
Chris@16 277
Chris@16 278 template<class Y>
Chris@16 279 weak_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
Chris@16 280 {
Chris@16 281 m_px = r.m_px;
Chris@16 282 counted_impl_ptr tmp = r.m_pi;
Chris@16 283 if(tmp != 0) tmp->weak_add_ref();
Chris@16 284 if(m_pi != 0) m_pi->weak_release();
Chris@16 285 m_pi = tmp;
Chris@16 286 return *this;
Chris@16 287 }
Chris@16 288
Chris@16 289 weak_count & operator= (weak_count const & r) // nothrow
Chris@16 290 {
Chris@16 291 m_px = r.m_px;
Chris@16 292 counted_impl_ptr tmp = r.m_pi;
Chris@16 293 if(tmp != 0) tmp->weak_add_ref();
Chris@16 294 if(m_pi != 0) m_pi->weak_release();
Chris@16 295 m_pi = tmp;
Chris@16 296 return *this;
Chris@16 297 }
Chris@16 298
Chris@16 299 void set_pointer(const pointer &ptr)
Chris@16 300 { m_px = ptr; }
Chris@16 301
Chris@16 302 template<class Y>
Chris@16 303 weak_count & operator= (weak_count<Y, VoidAllocator, Deleter> const& r) // nothrow
Chris@16 304 {
Chris@16 305 counted_impl_ptr tmp = r.m_pi;
Chris@16 306 if(tmp != 0) tmp->weak_add_ref();
Chris@16 307 if(m_pi != 0) m_pi->weak_release();
Chris@16 308 m_pi = tmp;
Chris@16 309 return *this;
Chris@16 310 }
Chris@16 311
Chris@16 312 void swap(weak_count & r) // nothrow
Chris@101 313 { ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_swap(m_pi, r.m_pi); }
Chris@16 314
Chris@16 315 long use_count() const // nothrow
Chris@16 316 { return m_pi != 0? m_pi->use_count() : 0; }
Chris@16 317
Chris@16 318 template<class T2, class VoidAllocator2, class Deleter2>
Chris@16 319 bool internal_equal (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
Chris@16 320 { return this->m_pi == other.m_pi; }
Chris@16 321
Chris@16 322 template<class T2, class VoidAllocator2, class Deleter2>
Chris@16 323 bool internal_less (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
Chris@16 324 { return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
Chris@16 325 };
Chris@16 326
Chris@16 327 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
Chris@16 328 bool operator==(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
Chris@16 329 { return a.internal_equal(b); }
Chris@16 330
Chris@16 331 template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
Chris@16 332 bool operator<(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
Chris@16 333 { return a.internal_less(b); }
Chris@16 334
Chris@16 335 } // namespace ipcdetail
Chris@16 336 } // namespace interprocess
Chris@16 337 } // namespace boost
Chris@16 338
Chris@16 339
Chris@16 340 #include <boost/interprocess/detail/config_end.hpp>
Chris@16 341
Chris@16 342
Chris@16 343 #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED