Subject: Re: [Boost-bugs] [Boost C++ Libraries] #1109: intrusive_ptr needs a helper base class
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-11-07 09:03:47
#1109: intrusive_ptr needs a helper base class
-------------------------------+-----------------------
Reporter: pdimov | Owner: pdimov
Type: Feature Requests | Status: new
Milestone: To Be Determined | Component: smart_ptr
Version: | Severity: Problem
Resolution: | Keywords:
-------------------------------+-----------------------
Comment (by JiÅà Havel <JSH@â¦>):
I use this base class. It is inspired by boost.intrusive and uses the
example reference counter from boost.atomic.
If you want, I can improve this a bit. I think, it should be possible to
select atomic/nonatomic internal counter and some checking policy (again
inspired by boost.atomic).
{{{
#ifndef INTRUSIVE_PTR_BASE_HOOK_H_INCLUDED
#define INTRUSIVE_PTR_BASE_HOOK_H_INCLUDED
#include <memory>
#include <utility>
#include <boost/assert.hpp>
#include <boost/atomic.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/parameters.hpp>
namespace utils {
BOOST_PARAMETER_TEMPLATE_KEYWORD(deleter)
BOOST_PARAMETER_TEMPLATE_KEYWORD(count_type)
typedef boost::parameter::parameters<
boost::parameter::optional<tag::deleter>,
boost::parameter::optional<tag::count_type>
> intrusive_ptr_base_hook_signature;
template<typename Derived, typename ... Params>
class intrusive_ptr_base_hook
{
typedef typename
intrusive_ptr_base_hook_signature::bind<Params...>::type args;
protected :
typedef Derived derived_type;
typedef typename boost::parameter::binding<
args, tag::deleter, std::default_delete<derived_type>
>::type deleter_type;
typedef typename boost::parameter::binding<
args, tag::count_type, unsigned
>::type count_type;
private:
struct Data
: public deleter_type
{
boost::atomic<count_type> count;
constexpr Data(count_type c, deleter_type const & d)
: deleter_type(d)
, count(c)
{}
} m_data;
protected :
constexpr intrusive_ptr_base_hook()
: m_data(0, deleter_type())
{}
intrusive_ptr_base_hook(intrusive_ptr_base_hook const &) = delete;
intrusive_ptr_base_hook & operator=(intrusive_ptr_base_hook const &) =
delete;
~intrusive_ptr_base_hook() noexcept
{
BOOST_ASSERT(m_count.load(boost::memory_order::memory_order_relaxed) ==
0);
}
public :
friend void intrusive_ptr_add_ref(
intrusive_ptr_base_hook const * p)
{
const_cast<intrusive_ptr_base_hook*>(p)
->m_data.count.fetch_add(1, boost::memory_order_relaxed);
}
friend void intrusive_ptr_release(
intrusive_ptr_base_hook const * pc)
{
intrusive_ptr_base_hook * p =
const_cast<intrusive_ptr_base_hook*>(pc);
if(p->m_data.count.fetch_sub(1, boost::memory_order_release) == 1)
{
boost::atomic_thread_fence(boost::memory_order_acquire);
// call deleter hidden in m_data
p->m_data(static_cast<derived_type*>(p));
}
}
};
template<typename T, typename ... Args>
inline boost::intrusive_ptr<T> make_intrusive(Args && ... args)
{
return boost::intrusive_ptr<T>(new T(std::forward<Args>(args)...));
}
}//namespace utils
#endif//INTRUSIVE_PTR_BASE_HOOK_H_INCLUDED
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/1109#comment:9> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:14 UTC