71 using holder =
typename capped_allocator::allocator_holder;
72 using traits = std::allocator_traits<Alloc>;
75 using value_type =
typename traits::value_type;
76 using pointer =
typename traits::pointer;
77 using const_pointer =
typename traits::const_pointer;
78 using void_pointer =
typename traits::void_pointer;
79 using const_void_pointer =
typename traits::const_void_pointer;
82 using size_type =
typename traits::size_type;
83 using difference_type =
typename traits::difference_type;
84 using propagate_on_container_copy_assignment =
typename traits::propagate_on_container_copy_assignment;
85 using propagate_on_container_move_assignment =
typename traits::propagate_on_container_move_assignment;
86 using propagate_on_container_swap =
typename traits::propagate_on_container_swap;
87#if __cplusplus >= 201703L
88 using is_always_equal =
typename traits::is_always_equal;
94 using other = capped_allocator<typename traits::template rebind_alloc<U>, Counter>;
121 const Alloc& alloc = {},
122 bool subtract_on_deallocate =
true)
125 _subtract_on_deallocate{ subtract_on_deallocate }
139 template <
typename C = Counter,
140 typename boost::enable_if<std::uses_allocator<C, Alloc>>::type* =
nullptr>
142 typename C::value_type max_value,
143 const Alloc& alloc = {},
144 bool subtract_on_deallocate =
true)
145 :
capped_allocator{ Counter{ max_value, alloc }, alloc, subtract_on_deallocate }
149 template <
typename OtherAlloc,
150 typename boost::enable_if<std::is_convertible<OtherAlloc, Alloc>>::type* =
nullptr>
152 : capped_allocator{ other._count, other.get_allocator(), other._subtract_on_deallocate }
155 pointer allocate(size_type n)
157 const auto size = n *
sizeof(value_type);
159 if (_count.get().try_add(size))
163 return traits::allocate(get_allocator(), n);
167 _count.get().subtract(size);
172 throw std::bad_alloc{};
175 pointer allocate(size_type n, const_void_pointer hint)
177 const auto size = n *
sizeof(value_type);
179 if (_count.get().try_add(size))
183 return traits::allocate(get_allocator(), n, hint);
187 _count.get().subtract(size);
192 throw std::bad_alloc{};
195 void deallocate(pointer ptr, size_type n)
197 traits::deallocate(get_allocator(), ptr, n);
199 if (_subtract_on_deallocate)
201 _count.get().subtract(n *
sizeof(value_type));
205 template <
typename T,
typename... Args>
206 void construct(T* ptr, Args&&... args)
208 traits::construct(get_allocator(), ptr, std::forward<Args>(args)...);
211 template <
typename T>
214 traits::destroy(get_allocator(), ptr);
217 size_type max_size() const BOND_NOEXCEPT
220 _count.get().max_value() /
sizeof(value_type),
221 traits::max_size(get_allocator()));
224 capped_allocator select_on_container_copy_construction()
226 return capped_allocator{
228 traits::select_on_container_copy_construction(get_allocator()),
229 _subtract_on_deallocate };
232 const Alloc& get_allocator() const BOND_NOEXCEPT
234 return holder::get();
237 Alloc& get_allocator() BOND_NOEXCEPT
239 return holder::get();
242 const Counter& get_counter() const BOND_NOEXCEPT
247 Counter& get_counter() BOND_NOEXCEPT
253 template <
typename OtherAlloc,
typename OtherCounter>
254 friend class capped_allocator;
256 detail::value_or_reference<Counter> _count;
257 bool _subtract_on_deallocate;
capped_allocator(detail::value_or_reference< Counter > count, const Alloc &alloc={}, bool subtract_on_deallocate=true)
Constructs capped allocator adapter.
Definition capped_allocator.h:119
capped_allocator(typename C::value_type max_value, const Alloc &alloc={}, bool subtract_on_deallocate=true)
Constructs capped allocator adapter.
Definition capped_allocator.h:141