Added boost header
This commit is contained in:
44
test/external/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp
vendored
Normal file
44
test/external/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/detail/bad_weak_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003
|
||||
// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_INTERPROCESS_BAD_WEAK_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_BAD_WEAK_PTR_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
class bad_weak_ptr
|
||||
: public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
virtual char const * what() const throw()
|
||||
{ return "boost::interprocess::bad_weak_ptr"; }
|
||||
};
|
||||
|
||||
} // namespace interprocess
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_BAD_WEAK_PTR_HPP_INCLUDED
|
||||
321
test/external/boost/interprocess/smart_ptr/detail/shared_count.hpp
vendored
Normal file
321
test/external/boost/interprocess/smart_ptr/detail/shared_count.hpp
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/detail/shared_count.hpp
|
||||
//
|
||||
// (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003
|
||||
// (C) Copyright Peter Dimov 2004-2005
|
||||
// (C) Copyright Ion Gaztanaga 2006-2009. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
|
||||
#include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <functional> // std::less
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail{
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter>
|
||||
class weak_count;
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter>
|
||||
class shared_count
|
||||
{
|
||||
public:
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, T>::type pointer;
|
||||
|
||||
private:
|
||||
typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, counted_impl>::type counted_impl_ptr;
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, sp_counted_base>::type counted_base_ptr;
|
||||
typedef typename VoidAllocator::template rebind
|
||||
<counted_impl>::other counted_impl_allocator;
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, const Deleter>::type const_deleter_pointer;
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, const VoidAllocator>::type const_allocator_pointer;
|
||||
|
||||
pointer m_px;
|
||||
counted_impl_ptr m_pi;
|
||||
|
||||
template <class T2, class VoidAllocator2, class Deleter2>
|
||||
friend class weak_count;
|
||||
|
||||
template <class T2, class VoidAllocator2, class Deleter2>
|
||||
friend class shared_count;
|
||||
|
||||
public:
|
||||
|
||||
shared_count()
|
||||
: m_px(0), m_pi(0) // nothrow
|
||||
{}
|
||||
|
||||
template <class Ptr>
|
||||
shared_count(const shared_count &other_shared_count, const Ptr &p)
|
||||
: m_px(p), m_pi(other_shared_count.m_pi)
|
||||
{}
|
||||
|
||||
template <class Ptr>
|
||||
shared_count(const Ptr &p, const VoidAllocator &a, Deleter d)
|
||||
: m_px(p), m_pi(0)
|
||||
{
|
||||
BOOST_TRY{
|
||||
if(p){
|
||||
counted_impl_allocator alloc(a);
|
||||
m_pi = alloc.allocate(1);
|
||||
//Anti-exception deallocator
|
||||
scoped_ptr<counted_impl,
|
||||
scoped_ptr_dealloc_functor<counted_impl_allocator> >
|
||||
deallocator(m_pi, alloc);
|
||||
//It's more correct to use VoidAllocator::construct but
|
||||
//this needs copy constructor and we don't like it
|
||||
new(ipcdetail::get_pointer(m_pi))counted_impl(p, a, d);
|
||||
deallocator.release();
|
||||
}
|
||||
}
|
||||
BOOST_CATCH (...){
|
||||
d(p); // delete p
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
~shared_count() // nothrow
|
||||
{
|
||||
if( m_pi != 0 )
|
||||
m_pi->release();
|
||||
}
|
||||
|
||||
shared_count(shared_count const & r)
|
||||
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
|
||||
{ if( m_pi != 0 ) m_pi->add_ref_copy(); }
|
||||
|
||||
//this is a test
|
||||
template<class Y>
|
||||
explicit shared_count(shared_count<Y, VoidAllocator, Deleter> const & r)
|
||||
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
|
||||
{ if( m_pi != 0 ) m_pi->add_ref_copy(); }
|
||||
|
||||
//this is a test
|
||||
template<class Y>
|
||||
explicit shared_count(const pointer & ptr, shared_count<Y, VoidAllocator, Deleter> const & r)
|
||||
: m_px(ptr), m_pi(r.m_pi) // nothrow
|
||||
{ if( m_pi != 0 ) m_pi->add_ref_copy(); }
|
||||
|
||||
/*
|
||||
explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
|
||||
// throws bad_weak_ptr when r.use_count() == 0
|
||||
: m_pi( r.m_pi )
|
||||
{
|
||||
if( m_pi == 0 || !m_pi->add_ref_lock() ){
|
||||
boost::throw_exception( boost::interprocess::bad_weak_ptr() );
|
||||
}
|
||||
}
|
||||
*/
|
||||
template<class Y>
|
||||
explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
|
||||
// throws bad_weak_ptr when r.use_count() == 0
|
||||
: m_px(r.m_px), m_pi( r.m_pi )
|
||||
{
|
||||
if( m_pi == 0 || !m_pi->add_ref_lock() ){
|
||||
throw( boost::interprocess::bad_weak_ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
const pointer &get_pointer() const
|
||||
{ return m_px; }
|
||||
|
||||
pointer &get_pointer()
|
||||
{ return m_px; }
|
||||
|
||||
shared_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
m_px = r.m_px;
|
||||
counted_impl_ptr tmp = r.m_pi;
|
||||
if( tmp != m_pi ){
|
||||
if(tmp != 0) tmp->add_ref_copy();
|
||||
if(m_pi != 0) m_pi->release();
|
||||
m_pi = tmp;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
|
||||
{
|
||||
m_px = r.m_px;
|
||||
counted_impl_ptr tmp = r.m_pi;
|
||||
if( tmp != m_pi ){
|
||||
if(tmp != 0) tmp->add_ref_copy();
|
||||
if(m_pi != 0) m_pi->release();
|
||||
m_pi = tmp;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(shared_count & r) // nothrow
|
||||
{ ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); }
|
||||
|
||||
long use_count() const // nothrow
|
||||
{ return m_pi != 0? m_pi->use_count(): 0; }
|
||||
|
||||
bool unique() const // nothrow
|
||||
{ return use_count() == 1; }
|
||||
|
||||
const_deleter_pointer get_deleter() const
|
||||
{ return m_pi ? m_pi->get_deleter() : 0; }
|
||||
|
||||
// const_allocator_pointer get_allocator() const
|
||||
// { return m_pi ? m_pi->get_allocator() : 0; }
|
||||
|
||||
template<class T2, class VoidAllocator2, class Deleter2>
|
||||
bool internal_equal (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
|
||||
{ return this->m_pi == other.m_pi; }
|
||||
|
||||
template<class T2, class VoidAllocator2, class Deleter2>
|
||||
bool internal_less (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
|
||||
{ return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
|
||||
};
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator==(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a.internal_equal(b); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator<(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a.internal_less(b); }
|
||||
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter>
|
||||
class weak_count
|
||||
{
|
||||
public:
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, T>::type pointer;
|
||||
|
||||
private:
|
||||
typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, counted_impl>::type counted_impl_ptr;
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename VoidAllocator::pointer, sp_counted_base>::type counted_base_ptr;
|
||||
|
||||
pointer m_px;
|
||||
counted_impl_ptr m_pi;
|
||||
|
||||
template <class T2, class VoidAllocator2, class Deleter2>
|
||||
friend class weak_count;
|
||||
|
||||
template <class T2, class VoidAllocator2, class Deleter2>
|
||||
friend class shared_count;
|
||||
|
||||
public:
|
||||
|
||||
weak_count(): m_px(0), m_pi(0) // nothrow
|
||||
{}
|
||||
|
||||
template <class Y>
|
||||
explicit weak_count(shared_count<Y, VoidAllocator, Deleter> const & r)
|
||||
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
|
||||
{ if(m_pi != 0) m_pi->weak_add_ref(); }
|
||||
|
||||
weak_count(weak_count const & r)
|
||||
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
|
||||
{ if(m_pi != 0) m_pi->weak_add_ref(); }
|
||||
|
||||
template<class Y>
|
||||
weak_count(weak_count<Y, VoidAllocator, Deleter> const & r)
|
||||
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
|
||||
{ if(m_pi != 0) m_pi->weak_add_ref(); }
|
||||
|
||||
~weak_count() // nothrow
|
||||
{ if(m_pi != 0) m_pi->weak_release(); }
|
||||
|
||||
template<class Y>
|
||||
weak_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
|
||||
{
|
||||
m_px = r.m_px;
|
||||
counted_impl_ptr tmp = r.m_pi;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(m_pi != 0) m_pi->weak_release();
|
||||
m_pi = tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
weak_count & operator= (weak_count const & r) // nothrow
|
||||
{
|
||||
counted_impl_ptr tmp = r.m_pi;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(m_pi != 0) m_pi->weak_release();
|
||||
m_pi = tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set_pointer(const pointer &ptr)
|
||||
{ m_px = ptr; }
|
||||
|
||||
template<class Y>
|
||||
weak_count & operator= (weak_count<Y, VoidAllocator, Deleter> const& r) // nothrow
|
||||
{
|
||||
counted_impl_ptr tmp = r.m_pi;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(m_pi != 0) m_pi->weak_release();
|
||||
m_pi = tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(weak_count & r) // nothrow
|
||||
{ ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); }
|
||||
|
||||
long use_count() const // nothrow
|
||||
{ return m_pi != 0? m_pi->use_count() : 0; }
|
||||
|
||||
template<class T2, class VoidAllocator2, class Deleter2>
|
||||
bool internal_equal (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
|
||||
{ return this->m_pi == other.m_pi; }
|
||||
|
||||
template<class T2, class VoidAllocator2, class Deleter2>
|
||||
bool internal_less (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
|
||||
{ return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
|
||||
};
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator==(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a.internal_equal(b); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator<(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a.internal_less(b); }
|
||||
|
||||
} // namespace ipcdetail
|
||||
} // namespace interprocess
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
18
test/external/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp
vendored
Normal file
18
test/external/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2009.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
|
||||
# include <boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
|
||||
92
test/external/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
vendored
Normal file
92
test/external/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2007-2009 Ion Gaztanaga
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace interprocess {
|
||||
|
||||
namespace ipcdetail {
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
boost::uint32_t use_count_; // #shared
|
||||
boost::uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{}
|
||||
|
||||
~sp_counted_base() // nothrow
|
||||
{}
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
ipcdetail::atomic_inc32( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ );
|
||||
if( tmp == 0 ) return false;
|
||||
if( ipcdetail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ref_release() // nothrow
|
||||
{ return 1 == ipcdetail::atomic_dec32( &use_count_ ); }
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{ ipcdetail::atomic_inc32( &weak_count_ ); }
|
||||
|
||||
bool weak_release() // nothrow
|
||||
{ return 1 == ipcdetail::atomic_dec32( &weak_count_ ); }
|
||||
|
||||
long use_count() const // nothrow
|
||||
{ return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }
|
||||
};
|
||||
|
||||
} // namespace ipcdetail
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
|
||||
146
test/external/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
vendored
Normal file
146
test/external/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// This file is the adaptation for shared memory memory mapped
|
||||
// files of boost/detail/sp_counted_impl.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Ion Gaztanaga
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
|
||||
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace interprocess {
|
||||
|
||||
namespace ipcdetail {
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_ptr_dealloc_functor
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef ipcdetail::integral_constant<unsigned,
|
||||
boost::interprocess::version<Allocator>::value> alloc_version;
|
||||
typedef ipcdetail::integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef ipcdetail::integral_constant<unsigned, 2> allocator_v2;
|
||||
|
||||
private:
|
||||
void priv_deallocate(const typename Allocator::pointer &p, allocator_v1)
|
||||
{ m_alloc.deallocate(p, 1); }
|
||||
|
||||
void priv_deallocate(const typename Allocator::pointer &p, allocator_v2)
|
||||
{ m_alloc.deallocate_one(p); }
|
||||
|
||||
public:
|
||||
Allocator& m_alloc;
|
||||
|
||||
scoped_ptr_dealloc_functor(Allocator& a)
|
||||
: m_alloc(a) {}
|
||||
|
||||
void operator()(pointer ptr)
|
||||
{ if (ptr) priv_deallocate(ptr, alloc_version()); }
|
||||
};
|
||||
|
||||
template<class A, class D>
|
||||
class sp_counted_impl_pd
|
||||
: public sp_counted_base
|
||||
, A::template rebind< sp_counted_impl_pd<A, D> >::other
|
||||
, D // copy constructor must not throw
|
||||
{
|
||||
private:
|
||||
typedef sp_counted_impl_pd<A, D> this_type;
|
||||
typedef typename A::template rebind
|
||||
<this_type>::other this_allocator;
|
||||
typedef typename A::template rebind
|
||||
<const this_type>::other const_this_allocator;
|
||||
typedef typename this_allocator::pointer this_pointer;
|
||||
|
||||
sp_counted_impl_pd( sp_counted_impl_pd const & );
|
||||
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
|
||||
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename A::pointer, const D>::type const_deleter_pointer;
|
||||
|
||||
typedef typename boost::pointer_to_other
|
||||
<typename A::pointer, const A>::type const_allocator_pointer;
|
||||
|
||||
typedef typename D::pointer pointer;
|
||||
pointer m_ptr;
|
||||
|
||||
public:
|
||||
// pre: d(p) must not throw
|
||||
template<class Ptr>
|
||||
sp_counted_impl_pd(const Ptr & p, const A &a, const D &d )
|
||||
: this_allocator(a), D(d), m_ptr(p)
|
||||
{}
|
||||
|
||||
const_deleter_pointer get_deleter() const
|
||||
{ return const_deleter_pointer(&static_cast<const D&>(*this)); }
|
||||
|
||||
const_allocator_pointer get_allocator() const
|
||||
{ return const_allocator_pointer(&static_cast<const A&>(*this)); }
|
||||
|
||||
void dispose() // nothrow
|
||||
{ static_cast<D&>(*this)(m_ptr); }
|
||||
|
||||
void destroy() // nothrow
|
||||
{
|
||||
//Self destruction, so get a copy of the allocator
|
||||
//(in the future we could move it)
|
||||
this_allocator a_copy(*this);
|
||||
BOOST_ASSERT(a_copy == *this);
|
||||
this_pointer this_ptr (this);
|
||||
//Do it now!
|
||||
scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
|
||||
deleter(this_ptr, a_copy);
|
||||
typedef typename this_allocator::value_type value_type;
|
||||
ipcdetail::get_pointer(this_ptr)->~value_type();
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if(this->ref_release()){
|
||||
this->dispose();
|
||||
this->weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if(sp_counted_base::weak_release()){
|
||||
this->destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace ipcdetail
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
Reference in New Issue
Block a user