17#ifndef TOOLBOX_UTIL_REFCOUNT_HPP
18#define TOOLBOX_UTIL_REFCOUNT_HPP
20#include <boost/intrusive_ptr.hpp>
25inline namespace util {
28 using Type = std::atomic<int>;
29 static void acquire()
noexcept { std::atomic_thread_fence(std::memory_order_acquire); }
32 return ref_count.fetch_add(1, std::memory_order_relaxed);
36 return ref_count.fetch_sub(1, std::memory_order_release);
38 static int load(
const Type& ref_count)
noexcept
40 return ref_count.load(std::memory_order_relaxed);
48#if defined(__GNUC__) && !defined(__clang__)
49#pragma GCC diagnostic push
50#pragma GCC diagnostic ignored "-Wuse-after-free"
53#if defined(__GNUC__) && !defined(__clang__)
54#pragma GCC diagnostic pop
56 static int load(
Type ref_count)
noexcept {
return ref_count; }
60template <
typename DerivedT,
typename PolicyT>
77 if (PolicyT::fetch_sub(refs_) == 1) {
79 delete static_cast<const DerivedT*
>(
this);
85 mutable typename PolicyT::Type refs_{1};
88template <
typename DerivedT,
typename PolicyT>
94template <
typename DerivedT,
typename PolicyT>
103 return {
new ValueT{std::forward<ArgsT>(args)...},
false};