stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012.
|
||||
//
|
||||
// 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_DELETER_HPP
|
||||
#define BOOST_INTERPROCESS_DELETER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes the functor to delete objects from the segment.
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
//!A deleter that uses the segment manager's destroy_ptr
|
||||
//!function to destroy the passed pointer resource.
|
||||
//!
|
||||
//!This deleter is used
|
||||
template<class T, class SegmentManager>
|
||||
class deleter
|
||||
{
|
||||
public:
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename SegmentManager::void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
|
||||
private:
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<pointer>::template
|
||||
rebind_pointer<SegmentManager>::type segment_manager_pointer;
|
||||
|
||||
segment_manager_pointer mp_mngr;
|
||||
|
||||
public:
|
||||
deleter(segment_manager_pointer pmngr)
|
||||
: mp_mngr(pmngr)
|
||||
{}
|
||||
|
||||
void operator()(const pointer &p)
|
||||
{ mp_mngr->destroy_ptr(ipcdetail::to_raw_pointer(p)); }
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DELETER_HPP
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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-2012. 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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/intrusive/pointer_traits.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/container/allocator_traits.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
|
||||
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::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
|
||||
private:
|
||||
typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
|
||||
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<counted_impl>::type counted_impl_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<sp_counted_base>::type counted_base_ptr;
|
||||
|
||||
typedef boost::container::allocator_traits<VoidAllocator> vallocator_traits;
|
||||
|
||||
typedef typename vallocator_traits::template
|
||||
portable_rebind_alloc<counted_impl>::type counted_impl_allocator;
|
||||
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<const Deleter>::type const_deleter_pointer;
|
||||
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_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::to_raw_pointer(m_pi), boost_container_new_t())counted_impl(p, a, d);
|
||||
deallocator.release();
|
||||
}
|
||||
}
|
||||
BOOST_CATCH (...){
|
||||
d(p); // delete p
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
~shared_count() // nothrow
|
||||
{
|
||||
if(m_pi)
|
||||
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 &to_raw_pointer() const
|
||||
{ return m_px; }
|
||||
|
||||
pointer &to_raw_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
|
||||
{ ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_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::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
|
||||
private:
|
||||
|
||||
typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
|
||||
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<counted_impl>::type counted_impl_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{ ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_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
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012.
|
||||
//
|
||||
// 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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
# include <boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2007-2012 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
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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/containers/version_type.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/container/allocator_traits.hpp>
|
||||
#include <boost/intrusive/pointer_traits.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
|
||||
, boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< sp_counted_impl_pd<A, D> >::type
|
||||
, D // copy constructor must not throw
|
||||
{
|
||||
private:
|
||||
typedef sp_counted_impl_pd<A, D> this_type;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::template
|
||||
portable_rebind_alloc
|
||||
< this_type >::type this_allocator;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::template
|
||||
portable_rebind_alloc
|
||||
< const this_type >::type const_this_allocator;
|
||||
typedef typename this_allocator::pointer this_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<this_pointer> this_pointer_traits;
|
||||
|
||||
sp_counted_impl_pd( sp_counted_impl_pd const & );
|
||||
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
|
||||
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename A::pointer>::template
|
||||
rebind_pointer<const D>::type const_deleter_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename A::pointer>::template
|
||||
rebind_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 move the allocator
|
||||
this_allocator a_copy(::boost::move(static_cast<this_allocator&>(*this)));
|
||||
BOOST_ASSERT(a_copy == *this);
|
||||
this_pointer this_ptr(this_pointer_traits::pointer_to(*this));
|
||||
//Do it now!
|
||||
scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
|
||||
deleter_ptr(this_ptr, a_copy);
|
||||
typedef typename this_allocator::value_type value_type;
|
||||
ipcdetail::to_raw_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
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/enable_shared_from_this.hpp
|
||||
//
|
||||
// (C) Copyright Peter Dimov 2002
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012. 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_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/interprocess/smart_ptr/weak_ptr.hpp>
|
||||
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes an utility to form a shared pointer from this
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
//!This class is used as a base class that allows a shared_ptr to the current
|
||||
//!object to be obtained from within a member function.
|
||||
//!enable_shared_from_this defines two member functions called shared_from_this
|
||||
//!that return a shared_ptr<T> and shared_ptr<T const>, depending on constness, to this.
|
||||
template<class T, class A, class D>
|
||||
class enable_shared_from_this
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
protected:
|
||||
enable_shared_from_this()
|
||||
{}
|
||||
|
||||
enable_shared_from_this(enable_shared_from_this const &)
|
||||
{}
|
||||
|
||||
enable_shared_from_this & operator=(enable_shared_from_this const &)
|
||||
{ return *this; }
|
||||
|
||||
~enable_shared_from_this()
|
||||
{}
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
shared_ptr<T, A, D> shared_from_this()
|
||||
{
|
||||
shared_ptr<T, A, D> p(_internal_weak_this);
|
||||
BOOST_ASSERT(ipcdetail::to_raw_pointer(p.get()) == this);
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<T const, A, D> shared_from_this() const
|
||||
{
|
||||
shared_ptr<T const, A, D> p(_internal_weak_this);
|
||||
BOOST_ASSERT(ipcdetail::to_raw_pointer(p.get()) == this);
|
||||
return p;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
typedef T element_type;
|
||||
mutable weak_ptr<element_type, A, D> _internal_weak_this;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
} // namespace interprocess
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/intrusive_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Peter Dimov 2001, 2002
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012. 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_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//!\file
|
||||
//!Describes an intrusive ownership pointer.
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
|
||||
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
//!The intrusive_ptr class template stores a pointer to an object
|
||||
//!with an embedded reference count. intrusive_ptr is parameterized on
|
||||
//!T (the type of the object pointed to) and VoidPointer(a void pointer type
|
||||
//!that defines the type of pointer that intrusive_ptr will store).
|
||||
//!intrusive_ptr<T, void *> defines a class with a T* member whereas
|
||||
//!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.
|
||||
//!Relies on unqualified calls to:
|
||||
//!
|
||||
//! void intrusive_ptr_add_ref(T * p);
|
||||
//! void intrusive_ptr_release(T * p);
|
||||
//!
|
||||
//! with (p != 0)
|
||||
//!
|
||||
//!The object is responsible for destroying itself.
|
||||
template<class T, class VoidPointer>
|
||||
class intrusive_ptr
|
||||
{
|
||||
public:
|
||||
//!Provides the type of the internal stored pointer.
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<VoidPointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
//!Provides the type of the stored pointer.
|
||||
typedef T element_type;
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
private:
|
||||
typedef VoidPointer VP;
|
||||
typedef intrusive_ptr this_type;
|
||||
typedef pointer this_type::*unspecified_bool_type;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//!Constructor. Initializes internal pointer to 0.
|
||||
//!Does not throw
|
||||
intrusive_ptr(): m_ptr(0)
|
||||
{}
|
||||
|
||||
//!Constructor. Copies pointer and if "p" is not zero and
|
||||
//!"add_ref" is true calls intrusive_ptr_add_ref(to_raw_pointer(p)).
|
||||
//!Does not throw
|
||||
intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p)
|
||||
{
|
||||
if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
|
||||
}
|
||||
|
||||
//!Copy constructor. Copies the internal pointer and if "p" is not
|
||||
//!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw
|
||||
intrusive_ptr(intrusive_ptr const & rhs)
|
||||
: m_ptr(rhs.m_ptr)
|
||||
{
|
||||
if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
|
||||
}
|
||||
|
||||
//!Constructor from related. Copies the internal pointer and if "p" is not
|
||||
//!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw
|
||||
template<class U> intrusive_ptr
|
||||
(intrusive_ptr<U, VP> const & rhs)
|
||||
: m_ptr(rhs.get())
|
||||
{
|
||||
if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
|
||||
}
|
||||
|
||||
//!Destructor. If internal pointer is not 0, calls
|
||||
//!intrusive_ptr_release(to_raw_pointer(m_ptr)). Does not throw
|
||||
~intrusive_ptr()
|
||||
{
|
||||
if(m_ptr != 0) intrusive_ptr_release(ipcdetail::to_raw_pointer(m_ptr));
|
||||
}
|
||||
|
||||
//!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
|
||||
//!Does not throw
|
||||
intrusive_ptr & operator=(intrusive_ptr const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
|
||||
//!Does not throw
|
||||
template<class U> intrusive_ptr & operator=
|
||||
(intrusive_ptr<U, VP> const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
|
||||
//!Does not throw
|
||||
intrusive_ptr & operator=(pointer rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Returns a reference to the internal pointer.
|
||||
//!Does not throw
|
||||
pointer &get()
|
||||
{ return m_ptr; }
|
||||
|
||||
//!Returns a reference to the internal pointer.
|
||||
//!Does not throw
|
||||
const pointer &get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
//!Returns *get().
|
||||
//!Does not throw
|
||||
T & operator*() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
//!Returns *get().
|
||||
//!Does not throw
|
||||
const pointer &operator->() const
|
||||
{ return m_ptr; }
|
||||
|
||||
//!Returns get().
|
||||
//!Does not throw
|
||||
pointer &operator->()
|
||||
{ return m_ptr; }
|
||||
|
||||
//!Conversion to boolean.
|
||||
//!Does not throw
|
||||
operator unspecified_bool_type () const
|
||||
{ return m_ptr == 0? 0: &this_type::m_ptr; }
|
||||
|
||||
//!Not operator.
|
||||
//!Does not throw
|
||||
bool operator! () const
|
||||
{ return m_ptr == 0; }
|
||||
|
||||
//!Exchanges the contents of the two smart pointers.
|
||||
//!Does not throw
|
||||
void swap(intrusive_ptr & rhs)
|
||||
{ ::boost::adl_move_swap(m_ptr, rhs.m_ptr); }
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
private:
|
||||
pointer m_ptr;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
//!Returns a.get() == b.get().
|
||||
//!Does not throw
|
||||
template<class T, class U, class VP> inline
|
||||
bool operator==(intrusive_ptr<T, VP> const & a,
|
||||
intrusive_ptr<U, VP> const & b)
|
||||
{ return a.get() == b.get(); }
|
||||
|
||||
//!Returns a.get() != b.get().
|
||||
//!Does not throw
|
||||
template<class T, class U, class VP> inline
|
||||
bool operator!=(intrusive_ptr<T, VP> const & a,
|
||||
intrusive_ptr<U, VP> const & b)
|
||||
{ return a.get() != b.get(); }
|
||||
|
||||
//!Returns a.get() == b.
|
||||
//!Does not throw
|
||||
template<class T, class VP> inline
|
||||
bool operator==(intrusive_ptr<T, VP> const & a,
|
||||
const typename intrusive_ptr<T, VP>::pointer &b)
|
||||
{ return a.get() == b; }
|
||||
|
||||
//!Returns a.get() != b.
|
||||
//!Does not throw
|
||||
template<class T, class VP> inline
|
||||
bool operator!=(intrusive_ptr<T, VP> const & a,
|
||||
const typename intrusive_ptr<T, VP>::pointer &b)
|
||||
{ return a.get() != b; }
|
||||
|
||||
//!Returns a == b.get().
|
||||
//!Does not throw
|
||||
template<class T, class VP> inline
|
||||
bool operator==(const typename intrusive_ptr<T, VP>::pointer &a,
|
||||
intrusive_ptr<T, VP> const & b)
|
||||
{ return a == b.get(); }
|
||||
|
||||
//!Returns a != b.get().
|
||||
//!Does not throw
|
||||
template<class T, class VP> inline
|
||||
bool operator!=(const typename intrusive_ptr<T, VP>::pointer &a,
|
||||
intrusive_ptr<T, VP> const & b)
|
||||
{ return a != b.get(); }
|
||||
|
||||
//!Returns a.get() < b.get().
|
||||
//!Does not throw
|
||||
template<class T, class VP> inline
|
||||
bool operator<(intrusive_ptr<T, VP> const & a,
|
||||
intrusive_ptr<T, VP> const & b)
|
||||
{
|
||||
return std::less<typename intrusive_ptr<T, VP>::pointer>()
|
||||
(a.get(), b.get());
|
||||
}
|
||||
|
||||
//!Exchanges the contents of the two intrusive_ptrs.
|
||||
//!Does not throw
|
||||
template<class T, class VP> inline
|
||||
void swap(intrusive_ptr<T, VP> & lhs,
|
||||
intrusive_ptr<T, VP> & rhs)
|
||||
{ lhs.swap(rhs); }
|
||||
|
||||
// operator<<
|
||||
template<class E, class T, class Y, class VP>
|
||||
inline std::basic_ostream<E, T> & operator<<
|
||||
(std::basic_ostream<E, T> & os, intrusive_ptr<Y, VP> const & p)
|
||||
{ os << p.get(); return os; }
|
||||
|
||||
//!Returns p.get().
|
||||
//!Does not throw
|
||||
template<class T, class VP>
|
||||
inline typename boost::interprocess::intrusive_ptr<T, VP>::pointer
|
||||
to_raw_pointer(intrusive_ptr<T, VP> p)
|
||||
{ return p.get(); }
|
||||
|
||||
/*Emulates static cast operator. Does not throw*/
|
||||
/*
|
||||
template<class T, class U, class VP>
|
||||
inline boost::interprocess::intrusive_ptr<T, VP> static_pointer_cast
|
||||
(boost::interprocess::intrusive_ptr<U, VP> const & p)
|
||||
{ return do_static_cast<U>(p.get()); }
|
||||
*/
|
||||
/*Emulates const cast operator. Does not throw*/
|
||||
/*
|
||||
template<class T, class U, class VP>
|
||||
inline boost::interprocess::intrusive_ptr<T, VP> const_pointer_cast
|
||||
(boost::interprocess::intrusive_ptr<U, VP> const & p)
|
||||
{ return do_const_cast<U>(p.get()); }
|
||||
*/
|
||||
|
||||
/*Emulates dynamic cast operator. Does not throw*/
|
||||
/*
|
||||
template<class T, class U, class VP>
|
||||
inline boost::interprocess::intrusive_ptr<T, VP> dynamic_pointer_cast
|
||||
(boost::interprocess::intrusive_ptr<U, VP> const & p)
|
||||
{ return do_dynamic_cast<U>(p.get()); }
|
||||
*/
|
||||
|
||||
/*Emulates reinterpret cast operator. Does not throw*/
|
||||
/*
|
||||
template<class T, class U, class VP>
|
||||
inline boost::interprocess::intrusive_ptr<T, VP>reinterpret_pointer_cast
|
||||
(boost::interprocess::intrusive_ptr<U, VP> const & p)
|
||||
{ return do_reinterpret_cast<U>(p.get()); }
|
||||
*/
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
//!Returns p.get().
|
||||
//!Does not throw
|
||||
template<class T, class VP>
|
||||
inline T *to_raw_pointer(boost::interprocess::intrusive_ptr<T, VP> p)
|
||||
{ return p.get(); }
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
@@ -0,0 +1,176 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/scoped_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// (C) Copyright Peter Dimov 2001, 2002
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012. 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_SCOPED_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_SCOPED_PTR_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/pointer_type.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes the smart pointer scoped_ptr
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
//!scoped_ptr stores a pointer to a dynamically allocated object.
|
||||
//!The object pointed to is guaranteed to be deleted, either on destruction
|
||||
//!of the scoped_ptr, or via an explicit reset. The user can avoid this
|
||||
//!deletion using release().
|
||||
//!scoped_ptr is parameterized on T (the type of the object pointed to) and
|
||||
//!Deleter (the functor to be executed to delete the internal pointer).
|
||||
//!The internal pointer will be of the same pointer type as typename
|
||||
//!Deleter::pointer type (that is, if typename Deleter::pointer is
|
||||
//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
|
||||
template<class T, class Deleter>
|
||||
class scoped_ptr
|
||||
: private Deleter
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
scoped_ptr(scoped_ptr const &);
|
||||
scoped_ptr & operator=(scoped_ptr const &);
|
||||
|
||||
typedef scoped_ptr<T, Deleter> this_type;
|
||||
typedef typename ipcdetail::add_reference<T>::type reference;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef Deleter deleter_type;
|
||||
typedef typename ipcdetail::pointer_type<T, Deleter>::type pointer;
|
||||
|
||||
//!Constructs a scoped_ptr, storing a copy of p(which can be 0) and d.
|
||||
//!Does not throw.
|
||||
explicit scoped_ptr(const pointer &p = 0, const Deleter &d = Deleter())
|
||||
: Deleter(d), m_ptr(p) // throws if pointer/Deleter copy ctor throws
|
||||
{}
|
||||
|
||||
//!If the stored pointer is not 0, destroys the object pointed to by the stored pointer.
|
||||
//!calling the operator() of the stored deleter. Never throws
|
||||
~scoped_ptr()
|
||||
{
|
||||
if(m_ptr){
|
||||
Deleter &del = static_cast<Deleter&>(*this);
|
||||
del(m_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deletes the object pointed to by the stored pointer and then
|
||||
//!stores a copy of p. Never throws
|
||||
void reset(const pointer &p = 0) // never throws
|
||||
{ BOOST_ASSERT(p == 0 || p != m_ptr); this_type(p).swap(*this); }
|
||||
|
||||
//!Deletes the object pointed to by the stored pointer and then
|
||||
//!stores a copy of p and a copy of d.
|
||||
void reset(const pointer &p, const Deleter &d) // never throws
|
||||
{ BOOST_ASSERT(p == 0 || p != m_ptr); this_type(p, d).swap(*this); }
|
||||
|
||||
//!Assigns internal pointer as 0 and returns previous pointer. This will
|
||||
//!avoid deletion on destructor
|
||||
pointer release()
|
||||
{ pointer tmp(m_ptr); m_ptr = 0; return tmp; }
|
||||
|
||||
//!Returns a reference to the object pointed to by the stored pointer.
|
||||
//!Never throws.
|
||||
reference operator*() const
|
||||
{ BOOST_ASSERT(m_ptr != 0); return *m_ptr; }
|
||||
|
||||
//!Returns the internal stored pointer.
|
||||
//!Never throws.
|
||||
pointer &operator->()
|
||||
{ BOOST_ASSERT(m_ptr != 0); return m_ptr; }
|
||||
|
||||
//!Returns the internal stored pointer.
|
||||
//!Never throws.
|
||||
const pointer &operator->() const
|
||||
{ BOOST_ASSERT(m_ptr != 0); return m_ptr; }
|
||||
|
||||
//!Returns the stored pointer.
|
||||
//!Never throws.
|
||||
pointer & get()
|
||||
{ return m_ptr; }
|
||||
|
||||
//!Returns the stored pointer.
|
||||
//!Never throws.
|
||||
const pointer & get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
typedef pointer this_type::*unspecified_bool_type;
|
||||
|
||||
//!Conversion to bool
|
||||
//!Never throws
|
||||
operator unspecified_bool_type() const
|
||||
{ return m_ptr == 0? 0: &this_type::m_ptr; }
|
||||
|
||||
//!Returns true if the stored pointer is 0.
|
||||
//!Never throws.
|
||||
bool operator! () const // never throws
|
||||
{ return m_ptr == 0; }
|
||||
|
||||
//!Exchanges the internal pointer and deleter with other scoped_ptr
|
||||
//!Never throws.
|
||||
void swap(scoped_ptr & b) // never throws
|
||||
{
|
||||
::boost::adl_move_swap(static_cast<Deleter&>(*this), static_cast<Deleter&>(b));
|
||||
::boost::adl_move_swap(m_ptr, b.m_ptr);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
private:
|
||||
pointer m_ptr;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
//!Exchanges the internal pointer and deleter with other scoped_ptr
|
||||
//!Never throws.
|
||||
template<class T, class D> inline
|
||||
void swap(scoped_ptr<T, D> & a, scoped_ptr<T, D> & b)
|
||||
{ a.swap(b); }
|
||||
|
||||
//!Returns a copy of the stored pointer
|
||||
//!Never throws
|
||||
template<class T, class D> inline
|
||||
typename scoped_ptr<T, D>::pointer to_raw_pointer(scoped_ptr<T, D> const & p)
|
||||
{ return p.get(); }
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
template<class T, class D> inline
|
||||
T *to_raw_pointer(boost::interprocess::scoped_ptr<T, D> const & p)
|
||||
{ return p.get(); }
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_SCOPED_PTR_HPP_INCLUDED
|
||||
@@ -0,0 +1,428 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/shared_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// (C) Copyright Peter Dimov 2001, 2002, 2003
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012.
|
||||
// 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_SHARED_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/cast_tags.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/interprocess/smart_ptr/detail/shared_count.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/detail/nothrow.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
#include <boost/interprocess/allocators/allocator.hpp>
|
||||
#include <boost/interprocess/smart_ptr/deleter.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
|
||||
//!\file
|
||||
//!Describes the smart pointer shared_ptr
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter> class weak_ptr;
|
||||
template<class T, class VoidAllocator, class Deleter> class enable_shared_from_this;
|
||||
|
||||
namespace ipcdetail{
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter>
|
||||
inline void sp_enable_shared_from_this
|
||||
(shared_count<T, VoidAllocator, Deleter> const & pn
|
||||
,enable_shared_from_this<T, VoidAllocator, Deleter> *pe
|
||||
,T *ptr)
|
||||
|
||||
{
|
||||
(void)ptr;
|
||||
if(pe != 0){
|
||||
pe->_internal_weak_this._internal_assign(pn);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter>
|
||||
inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> const &, ...)
|
||||
{}
|
||||
|
||||
} // namespace ipcdetail
|
||||
|
||||
//!shared_ptr stores a pointer to a dynamically allocated object.
|
||||
//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
|
||||
//!it is destroyed or reset.
|
||||
//!
|
||||
//!shared_ptr is parameterized on
|
||||
//!T (the type of the object pointed to), VoidAllocator (the void allocator to be used
|
||||
//!to allocate the auxiliary data) and Deleter (the deleter whose
|
||||
//!operator() will be used to delete the object.
|
||||
//!
|
||||
//!The internal pointer will be of the same pointer type as typename
|
||||
//!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is
|
||||
//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
|
||||
//!
|
||||
//!Because the implementation uses reference counting, cycles of shared_ptr
|
||||
//!instances will not be reclaimed. For example, if main() holds a
|
||||
//!shared_ptr to A, which directly or indirectly holds a shared_ptr back
|
||||
//!to A, A's use count will be 2. Destruction of the original shared_ptr
|
||||
//!will leave A dangling with a use count of 1.
|
||||
//!Use weak_ptr to "break cycles."
|
||||
template<class T, class VoidAllocator, class Deleter>
|
||||
class shared_ptr
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
private:
|
||||
typedef shared_ptr<T, VoidAllocator, Deleter> this_type;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef T value_type;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<const Deleter>::type const_deleter_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename VoidAllocator::pointer>::template
|
||||
rebind_pointer<const VoidAllocator>::type const_allocator_pointer;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(shared_ptr)
|
||||
public:
|
||||
|
||||
//!Constructs an empty shared_ptr.
|
||||
//!Use_count() == 0 && get()== 0.
|
||||
shared_ptr()
|
||||
: m_pn() // never throws
|
||||
{}
|
||||
|
||||
//!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated
|
||||
//!with a copy of a and the object will be deleted with a copy of d.
|
||||
//!Requirements: Deleter and A's copy constructor must not throw.
|
||||
explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
|
||||
: m_pn(p, a, d)
|
||||
{
|
||||
//Check that the pointer passed is of the same type that
|
||||
//the pointer the allocator defines or it's a raw pointer
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<pointer>::template
|
||||
rebind_pointer<T>::type ParameterPointer;
|
||||
|
||||
BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
|
||||
(ipcdetail::is_pointer<pointer>::value));
|
||||
ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) );
|
||||
}
|
||||
|
||||
//!Copy constructs a shared_ptr. If r is empty, constructs an empty shared_ptr. Otherwise, constructs
|
||||
//!a shared_ptr that shares ownership with r. Never throws.
|
||||
shared_ptr(const shared_ptr &r)
|
||||
: m_pn(r.m_pn) // never throws
|
||||
{}
|
||||
|
||||
//!Constructs a shared_ptr that shares ownership with other and stores p.
|
||||
//!Postconditions: get() == p && use_count() == r.use_count().
|
||||
//!Throws: nothing.
|
||||
shared_ptr(const shared_ptr &other, const pointer &p)
|
||||
: m_pn(other.m_pn, p)
|
||||
{}
|
||||
|
||||
//!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
|
||||
//!a shared_ptr that shares ownership with r. Never throws.
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
|
||||
: m_pn(r.m_pn) // never throws
|
||||
{}
|
||||
|
||||
//!Constructs a shared_ptr that shares ownership with r and stores
|
||||
//!a copy of the pointer stored in r.
|
||||
template<class Y>
|
||||
explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
|
||||
: m_pn(r.m_pn) // may throw
|
||||
{}
|
||||
|
||||
//!Move-Constructs a shared_ptr that takes ownership of other resource and
|
||||
//!other is put in default-constructed state.
|
||||
//!Throws: nothing.
|
||||
explicit shared_ptr(BOOST_RV_REF(shared_ptr) other)
|
||||
: m_pn()
|
||||
{ this->swap(other); }
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::static_cast_tag)
|
||||
: m_pn( pointer(static_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
|
||||
, r.m_pn)
|
||||
{}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::const_cast_tag)
|
||||
: m_pn( pointer(const_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
|
||||
, r.m_pn)
|
||||
{}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::dynamic_cast_tag)
|
||||
: m_pn( pointer(dynamic_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
|
||||
, r.m_pn)
|
||||
{
|
||||
if(!m_pn.to_raw_pointer()){ // need to allocate new counter -- the cast failed
|
||||
m_pn = ipcdetail::shared_count<T, VoidAllocator, Deleter>();
|
||||
}
|
||||
}
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
//!Equivalent to shared_ptr(r).swap(*this).
|
||||
//!Never throws
|
||||
template<class Y>
|
||||
shared_ptr & operator=(shared_ptr<Y, VoidAllocator, Deleter> const & r)
|
||||
{
|
||||
m_pn = r.m_pn; // shared_count::op= doesn't throw
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Equivalent to shared_ptr(r).swap(*this).
|
||||
//!Never throws
|
||||
shared_ptr & operator=(BOOST_COPY_ASSIGN_REF(shared_ptr) r)
|
||||
{
|
||||
m_pn = r.m_pn; // shared_count::op= doesn't throw
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
|
||||
//!Never throws
|
||||
shared_ptr & operator=(BOOST_RV_REF(shared_ptr) other) // never throws
|
||||
{
|
||||
this_type(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!This is equivalent to:
|
||||
//!this_type().swap(*this);
|
||||
void reset()
|
||||
{
|
||||
this_type().swap(*this);
|
||||
}
|
||||
|
||||
//!This is equivalent to:
|
||||
//!this_type(p, a, d).swap(*this);
|
||||
template<class Pointer>
|
||||
void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
|
||||
{
|
||||
//Check that the pointer passed is of the same type that
|
||||
//the pointer the allocator defines or it's a raw pointer
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::template
|
||||
rebind_pointer<T>::type ParameterPointer;
|
||||
BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
|
||||
(ipcdetail::is_pointer<Pointer>::value));
|
||||
this_type(p, a, d).swap(*this);
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
void reset(shared_ptr<Y, VoidAllocator, Deleter> const & r, const pointer &p)
|
||||
{
|
||||
this_type(r, p).swap(*this);
|
||||
}
|
||||
|
||||
//!Returns a reference to the
|
||||
//!pointed type
|
||||
reference operator* () const // never throws
|
||||
{ BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return *m_pn.to_raw_pointer(); }
|
||||
|
||||
//!Returns the pointer pointing
|
||||
//!to the owned object
|
||||
pointer operator-> () const // never throws
|
||||
{ BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return m_pn.to_raw_pointer(); }
|
||||
|
||||
//!Returns the pointer pointing
|
||||
//!to the owned object
|
||||
pointer get() const // never throws
|
||||
{ return m_pn.to_raw_pointer(); }
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
// implicit conversion to "bool"
|
||||
void unspecified_bool_type_func() const {}
|
||||
typedef void (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{ return !m_pn.to_raw_pointer() ? 0 : &this_type::unspecified_bool_type_func; }
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
//!Not operator.
|
||||
//!Returns true if this->get() != 0, false otherwise
|
||||
bool operator! () const // never throws
|
||||
{ return !m_pn.to_raw_pointer(); }
|
||||
|
||||
//!Returns use_count() == 1.
|
||||
//!unique() might be faster than use_count()
|
||||
bool unique() const // never throws
|
||||
{ return m_pn.unique(); }
|
||||
|
||||
//!Returns the number of shared_ptr objects, *this included,
|
||||
//!that share ownership with *this, or an unspecified nonnegative
|
||||
//!value when *this is empty.
|
||||
//!use_count() is not necessarily efficient. Use only for
|
||||
//!debugging and testing purposes, not for production code.
|
||||
long use_count() const // never throws
|
||||
{ return m_pn.use_count(); }
|
||||
|
||||
//!Exchanges the contents of the two
|
||||
//!smart pointers.
|
||||
void swap(shared_ptr<T, VoidAllocator, Deleter> & other) // never throws
|
||||
{ m_pn.swap(other.m_pn); }
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
template<class T2, class A2, class Deleter2>
|
||||
bool _internal_less(shared_ptr<T2, A2, Deleter2> const & rhs) const
|
||||
{ return m_pn < rhs.m_pn; }
|
||||
|
||||
const_deleter_pointer get_deleter() const
|
||||
{ return m_pn.get_deleter(); }
|
||||
|
||||
// const_allocator_pointer get_allocator() const
|
||||
// { return m_pn.get_allocator(); }
|
||||
|
||||
private:
|
||||
|
||||
template<class T2, class A2, class Deleter2> friend class shared_ptr;
|
||||
template<class T2, class A2, class Deleter2> friend class weak_ptr;
|
||||
|
||||
ipcdetail::shared_count<T, VoidAllocator, Deleter> m_pn; // reference counter
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
}; // shared_ptr
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator==(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a.get() == b.get(); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator!=(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a.get() != b.get(); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
|
||||
bool operator<(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
|
||||
{ return a._internal_less(b); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter> inline
|
||||
void swap(shared_ptr<T, VoidAllocator, Deleter> & a, shared_ptr<T, VoidAllocator, Deleter> & b)
|
||||
{ a.swap(b); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class U> inline
|
||||
shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
|
||||
{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::static_cast_tag()); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class U> inline
|
||||
shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
|
||||
{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::const_cast_tag()); }
|
||||
|
||||
template<class T, class VoidAllocator, class Deleter, class U> inline
|
||||
shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
|
||||
{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::dynamic_cast_tag()); }
|
||||
|
||||
// to_raw_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||
template<class T, class VoidAllocator, class Deleter> inline
|
||||
T * to_raw_pointer(shared_ptr<T, VoidAllocator, Deleter> const & p)
|
||||
{ return p.get(); }
|
||||
|
||||
// operator<<
|
||||
template<class E, class T, class Y, class VoidAllocator, class Deleter> inline
|
||||
std::basic_ostream<E, T> & operator<<
|
||||
(std::basic_ostream<E, T> & os, shared_ptr<Y, VoidAllocator, Deleter> const & p)
|
||||
{ os << p.get(); return os; }
|
||||
|
||||
//!Returns the type of a shared pointer
|
||||
//!of type T with the allocator boost::interprocess::allocator allocator
|
||||
//!and boost::interprocess::deleter deleter
|
||||
//!that can be constructed in the given managed segment type.
|
||||
template<class T, class ManagedMemory>
|
||||
struct managed_shared_ptr
|
||||
{
|
||||
typedef typename ManagedMemory::template allocator<void>::type void_allocator;
|
||||
typedef typename ManagedMemory::template deleter<T>::type deleter;
|
||||
typedef shared_ptr< T, void_allocator, deleter> type;
|
||||
};
|
||||
|
||||
//!Returns an instance of a shared pointer constructed
|
||||
//!with the default allocator and deleter from a pointer
|
||||
//!of type T that has been allocated in the passed managed segment
|
||||
template<class T, class ManagedMemory>
|
||||
inline typename managed_shared_ptr<T, ManagedMemory>::type
|
||||
make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory)
|
||||
{
|
||||
return typename managed_shared_ptr<T, ManagedMemory>::type
|
||||
( constructed_object
|
||||
, managed_memory.template get_allocator<void>()
|
||||
, managed_memory.template get_deleter<T>()
|
||||
);
|
||||
}
|
||||
|
||||
//!Returns an instance of a shared pointer constructed
|
||||
//!with the default allocator and deleter from a pointer
|
||||
//!of type T that has been allocated in the passed managed segment.
|
||||
//!Does not throw, return null shared pointer in error.
|
||||
template<class T, class ManagedMemory>
|
||||
inline typename managed_shared_ptr<T, ManagedMemory>::type
|
||||
make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory, const std::nothrow_t &)
|
||||
{
|
||||
try{
|
||||
return typename managed_shared_ptr<T, ManagedMemory>::type
|
||||
( constructed_object
|
||||
, managed_memory.template get_allocator<void>()
|
||||
, managed_memory.template get_deleter<T>()
|
||||
);
|
||||
}
|
||||
catch(...){
|
||||
return typename managed_shared_ptr<T, ManagedMemory>::type();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
// to_raw_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||
template<class T, class VoidAllocator, class Deleter> inline
|
||||
T * to_raw_pointer(boost::interprocess::shared_ptr<T, VoidAllocator, Deleter> const & p)
|
||||
{ return p.get(); }
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
|
||||
@@ -0,0 +1,63 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2014. 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_UNIQUE_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
|
||||
//!\file
|
||||
//!This header provides utilities to define a unique_ptr that plays nicely with managed segments.
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
//For backwards compatibility
|
||||
using ::boost::movelib::unique_ptr;
|
||||
|
||||
//!Returns the type of a unique pointer
|
||||
//!of type T with boost::interprocess::deleter deleter
|
||||
//!that can be constructed in the given managed segment type.
|
||||
template<class T, class ManagedMemory>
|
||||
struct managed_unique_ptr
|
||||
{
|
||||
typedef boost::movelib::unique_ptr
|
||||
< T
|
||||
, typename ManagedMemory::template deleter<T>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
//!Returns an instance of a unique pointer constructed
|
||||
//!with boost::interproces::deleter from a pointer
|
||||
//!of type T that has been allocated in the passed managed segment
|
||||
template<class T, class ManagedMemory>
|
||||
inline typename managed_unique_ptr<T, ManagedMemory>::type
|
||||
make_managed_unique_ptr(T *constructed_object, ManagedMemory &managed_memory)
|
||||
{
|
||||
return typename managed_unique_ptr<T, ManagedMemory>::type
|
||||
(constructed_object, managed_memory.template get_deleter<T>());
|
||||
}
|
||||
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED
|
||||
@@ -0,0 +1,269 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file is the adaptation for Interprocess of boost/weak_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Peter Dimov 2001, 2002, 2003
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012.
|
||||
// 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_WEAK_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/interprocess/allocators/allocator.hpp>
|
||||
#include <boost/interprocess/smart_ptr/deleter.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes the smart pointer weak_ptr.
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
//!The weak_ptr class template stores a "weak reference" to an object
|
||||
//!that's already managed by a shared_ptr. To access the object, a weak_ptr
|
||||
//!can be converted to a shared_ptr using the shared_ptr constructor or the
|
||||
//!member function lock. When the last shared_ptr to the object goes away
|
||||
//!and the object is deleted, the attempt to obtain a shared_ptr from the
|
||||
//!weak_ptr instances that refer to the deleted object will fail: the constructor
|
||||
//!will throw an exception of type bad_weak_ptr, and weak_ptr::lock will
|
||||
//!return an empty shared_ptr.
|
||||
//!
|
||||
//!Every weak_ptr meets the CopyConstructible and Assignable requirements
|
||||
//!of the C++ Standard Library, and so can be used in standard library containers.
|
||||
//!Comparison operators are supplied so that weak_ptr works with the standard
|
||||
//!library's associative containers.
|
||||
//!
|
||||
//!weak_ptr operations never throw exceptions.
|
||||
//!
|
||||
//!The class template is parameterized on T, the type of the object pointed to.
|
||||
template<class T, class A, class D>
|
||||
class weak_ptr
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
private:
|
||||
// Borland 5.5.1 specific workarounds
|
||||
typedef weak_ptr<T, A, D> this_type;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<typename A::pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename ipcdetail::add_reference
|
||||
<T>::type reference;
|
||||
typedef typename ipcdetail::add_reference
|
||||
<T>::type const_reference;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef T value_type;
|
||||
|
||||
//!Effects: Constructs an empty weak_ptr.
|
||||
//!Postconditions: use_count() == 0.
|
||||
weak_ptr()
|
||||
: m_pn() // never throws
|
||||
{}
|
||||
// generated copy constructor, assignment, destructor are fine
|
||||
//
|
||||
// The "obvious" converting constructor implementation:
|
||||
//
|
||||
// template<class Y>
|
||||
// weak_ptr(weak_ptr<Y> const & r): m_px(r.m_px), m_pn(r.m_pn) // never throws
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// has a serious problem.
|
||||
//
|
||||
// r.m_px may already have been invalidated. The m_px(r.m_px)
|
||||
// conversion may require access to *r.m_px (virtual inheritance).
|
||||
//
|
||||
// It is not possible to avoid spurious access violations since
|
||||
// in multithreaded programs r.m_px may be invalidated at any point.
|
||||
|
||||
//!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
|
||||
//!constructs a weak_ptr that shares ownership with r as if by storing a
|
||||
//!copy of the pointer stored in r.
|
||||
//!
|
||||
//!Postconditions: use_count() == r.use_count().
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
template<class Y>
|
||||
weak_ptr(weak_ptr<Y, A, D> const & r)
|
||||
: m_pn(r.m_pn) // never throws
|
||||
{
|
||||
//Construct a temporary shared_ptr so that nobody
|
||||
//can destroy the value while constructing this
|
||||
const shared_ptr<T, A, D> &ref = r.lock();
|
||||
m_pn.set_pointer(ref.get());
|
||||
}
|
||||
|
||||
//!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
|
||||
//!constructs a weak_ptr that shares ownership with r as if by storing a
|
||||
//!copy of the pointer stored in r.
|
||||
//!
|
||||
//!Postconditions: use_count() == r.use_count().
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
template<class Y>
|
||||
weak_ptr(shared_ptr<Y, A, D> const & r)
|
||||
: m_pn(r.m_pn) // never throws
|
||||
{}
|
||||
|
||||
//!Effects: Equivalent to weak_ptr(r).swap(*this).
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
//!
|
||||
//!Notes: The implementation is free to meet the effects (and the
|
||||
//!implied guarantees) via different means, without creating a temporary.
|
||||
template<class Y>
|
||||
weak_ptr & operator=(weak_ptr<Y, A, D> const & r) // never throws
|
||||
{
|
||||
//Construct a temporary shared_ptr so that nobody
|
||||
//can destroy the value while constructing this
|
||||
const shared_ptr<T, A, D> &ref = r.lock();
|
||||
m_pn = r.m_pn;
|
||||
m_pn.set_pointer(ref.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Effects: Equivalent to weak_ptr(r).swap(*this).
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
//!
|
||||
//!Notes: The implementation is free to meet the effects (and the
|
||||
//!implied guarantees) via different means, without creating a temporary.
|
||||
template<class Y>
|
||||
weak_ptr & operator=(shared_ptr<Y, A, D> const & r) // never throws
|
||||
{ m_pn = r.m_pn; return *this; }
|
||||
|
||||
//!Returns: expired()? shared_ptr<T>(): shared_ptr<T>(*this).
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
shared_ptr<T, A, D> lock() const // never throws
|
||||
{
|
||||
// optimization: avoid throw overhead
|
||||
if(expired()){
|
||||
return shared_ptr<element_type, A, D>();
|
||||
}
|
||||
BOOST_TRY{
|
||||
return shared_ptr<element_type, A, D>(*this);
|
||||
}
|
||||
BOOST_CATCH(bad_weak_ptr const &){
|
||||
// Q: how can we get here?
|
||||
// A: another thread may have invalidated r after the use_count test above.
|
||||
return shared_ptr<element_type, A, D>();
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
//!Returns: 0 if *this is empty; otherwise, the number of shared_ptr objects
|
||||
//!that share ownership with *this.
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
//!
|
||||
//!Notes: use_count() is not necessarily efficient. Use only for debugging and
|
||||
//!testing purposes, not for production code.
|
||||
long use_count() const // never throws
|
||||
{ return m_pn.use_count(); }
|
||||
|
||||
//!Returns: Returns: use_count() == 0.
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
//!
|
||||
//!Notes: expired() may be faster than use_count().
|
||||
bool expired() const // never throws
|
||||
{ return m_pn.use_count() == 0; }
|
||||
|
||||
//!Effects: Equivalent to:
|
||||
//!weak_ptr().swap(*this).
|
||||
void reset() // never throws in 1.30+
|
||||
{ this_type().swap(*this); }
|
||||
|
||||
//!Effects: Exchanges the contents of the two
|
||||
//!smart pointers.
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
void swap(this_type & other) // never throws
|
||||
{ ::boost::adl_move_swap(m_pn, other.m_pn); }
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
template<class T2, class A2, class D2>
|
||||
bool _internal_less(weak_ptr<T2, A2, D2> const & rhs) const
|
||||
{ return m_pn < rhs.m_pn; }
|
||||
|
||||
template<class Y>
|
||||
void _internal_assign(const ipcdetail::shared_count<Y, A, D> & pn2)
|
||||
{
|
||||
|
||||
m_pn = pn2;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<class T2, class A2, class D2> friend class shared_ptr;
|
||||
template<class T2, class A2, class D2> friend class weak_ptr;
|
||||
|
||||
ipcdetail::weak_count<T, A, D> m_pn; // reference counter
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
}; // weak_ptr
|
||||
|
||||
template<class T, class A, class D, class U, class A2, class D2> inline
|
||||
bool operator<(weak_ptr<T, A, D> const & a, weak_ptr<U, A2, D2> const & b)
|
||||
{ return a._internal_less(b); }
|
||||
|
||||
template<class T, class A, class D> inline
|
||||
void swap(weak_ptr<T, A, D> & a, weak_ptr<T, A, D> & b)
|
||||
{ a.swap(b); }
|
||||
|
||||
//!Returns the type of a weak pointer
|
||||
//!of type T with the allocator boost::interprocess::allocator allocator
|
||||
//!and boost::interprocess::deleter deleter
|
||||
//!that can be constructed in the given managed segment type.
|
||||
template<class T, class ManagedMemory>
|
||||
struct managed_weak_ptr
|
||||
{
|
||||
typedef weak_ptr
|
||||
< T
|
||||
, typename ManagedMemory::template allocator<void>::type
|
||||
, typename ManagedMemory::template deleter<T>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
//!Returns an instance of a weak pointer constructed
|
||||
//!with the default allocator and deleter from a pointer
|
||||
//!of type T that has been allocated in the passed managed segment
|
||||
template<class T, class ManagedMemory>
|
||||
inline typename managed_weak_ptr<T, ManagedMemory>::type
|
||||
make_managed_weak_ptr(T *constructed_object, ManagedMemory &managed_memory)
|
||||
{
|
||||
return typename managed_weak_ptr<T, ManagedMemory>::type
|
||||
( constructed_object
|
||||
, managed_memory.template get_allocator<void>()
|
||||
, managed_memory.template get_deleter<T>()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace interprocess
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED
|
||||
Reference in New Issue
Block a user