6#include <bond/core/config.h>
8#include "capped_allocator_fwd.h"
10#include <boost/assert.hpp>
11#include <boost/intrusive_ptr.hpp>
16namespace bond {
namespace ext
21 template <
typename Counter>
25 using value_type =
typename Counter::value_type;
29 : _value{ new internal_counter{ max_value } }
35 template <
typename Alloc>
40 bool try_add(value_type val) BOND_NOEXCEPT
42 return _value->try_add(val);
45 void subtract(value_type val) BOND_NOEXCEPT
47 _value->subtract(val);
50 value_type max_value() const BOND_NOEXCEPT
52 return _value->max_value();
55 value_type value() const BOND_NOEXCEPT
57 return _value->value();
62 class internal_counter :
public Counter
65 using Counter::Counter;
67 friend void intrusive_ptr_add_ref(internal_counter* p) BOND_NOEXCEPT
72 friend void intrusive_ptr_release(internal_counter* p)
81 virtual ~internal_counter() =
default;
84 virtual void delete_this()
90 typename std::conditional<
91 Counter::is_thread_safe::value,
92 std::atomic<value_type>,
93 value_type>::type _refs{};
98 template <
typename Alloc>
99 class internal_counter_with_allocator :
public internal_counter
101 using char_alloc =
typename std::allocator_traits<Alloc>::template rebind_alloc<char>;
107 template <
typename C>
108 static internal_counter* allocate_counter(value_type max_value, capped_allocator<Alloc, C>& capped_alloc)
110 capped_allocator<char_alloc, C> capped_char_alloc{ capped_alloc };
111 return new (capped_char_alloc)
112 internal_counter_with_allocator{
114 capped_char_alloc.get_allocator() };
122 static void operator delete(
void* )
130 internal_counter_with_allocator(value_type max_value,
const char_alloc& alloc)
131 : internal_counter{ max_value },
136 template <
typename C>
137 static void*
operator new(std::size_t size, capped_allocator<char_alloc, C>& alloc)
139 BOOST_ASSERT(size ==
sizeof(internal_counter_with_allocator));
140 return alloc.allocate(size);
146 template <
typename C>
147 static void operator delete(
void* ptr, capped_allocator<char_alloc, C>& alloc)
149 operator delete(ptr, alloc.get_allocator());
153 static void operator delete(
void* ptr, char_alloc& alloc)
155 return alloc.deallocate(
static_cast<char*
>(ptr),
sizeof(internal_counter_with_allocator));
159 void delete_this()
override
162 this->~internal_counter_with_allocator();
163 operator delete(
this, alloc);
173 template <
typename Alloc,
typename C>
174 shared_counter(value_type max_value, capped_allocator<Alloc, C>& capped_alloc)
175 : _value{ internal_counter_with_allocator<Alloc>::allocate_counter(max_value, capped_alloc) }
181 template <
typename Alloc>
182 static shared_counter allocate_counter(value_type max_value,
const Alloc& alloc)
184 single_threaded_counter<value_type> counter{ max_value };
185 capped_allocator<Alloc,
decltype(counter)&> capped_alloc{ std::ref(counter), alloc };
194 boost::intrusive_ptr<internal_counter> _value;
201 template <
typename Counter,
typename Alloc>
202 struct uses_allocator<
bond::ext::shared_counter<Counter>, Alloc> : std::true_type
Shared counter to be used with capped_allocator.
Definition: shared_counter.h:23
shared_counter(value_type max_value, const Alloc &alloc)
Allocates counter using the provided allocator.
Definition: shared_counter.h:36
shared_counter(value_type max_value)
Constructs counter using default "operator new".
Definition: shared_counter.h:28
namespace bond
Definition: apply.h:17