25 #ifndef __TPIE_MEMORY_H__
26 #define __TPIE_MEMORY_H__
28 #include <tpie/tpie_export.h>
29 #include <tpie/config.h>
31 #include <tpie/resource_manager.h>
33 #include <unordered_map>
34 #include <type_traits>
50 std::atomic_size_t bytes;
51 std::atomic_size_t count;
74 std::pair<uint8_t *, size_t> __allocate_consecutive(
size_t upper_bound,
size_t granularity);
76 void register_typed_allocation(
size_t bytes,
const std::type_info & t);
77 void register_typed_deallocation(
size_t bytes,
const std::type_info & t);
79 void register_allocation(
size_t bytes,
const std::type_info & t) {
80 register_increased_usage(bytes);
82 register_typed_allocation(bytes, t);
88 void register_deallocation(
size_t bytes,
const std::type_info & t) {
89 register_decreased_usage(bytes);
91 register_typed_deallocation(bytes, t);
97 std::string amount_with_unit(
size_t amount)
const override {
101 void complain_about_unfreed_memory();
102 std::unordered_map<std::type_index, memory_digest_item> memory_digest();
104 void throw_out_of_resource_error(
const std::string & s)
override;
106 std::atomic_size_t m_mutex;
107 std::unordered_map<std::type_index, type_allocations> m_allocations;
128 template <
typename T,
132 bool x=std::is_polymorphic<T>::value
134 struct __object_addr {
135 void * operator()(T * o) {
return const_cast<void*
>(
static_cast<const void*
>(o));}
141 template <
typename T>
142 struct __object_addr<T, true> {
143 void * operator()(T * o) {
return const_cast<void*
>(
dynamic_cast<const void *
>(o));}
154 template <
typename D,
typename T>
155 inline D
ptr_cast(T * t) {
return reinterpret_cast<D
>(__object_addr<T>()(t)); }
158 template <
typename T>
159 inline T * __allocate() {
160 if(!std::is_polymorphic<T>::value)
return reinterpret_cast<T *
>(
new uint8_t[
sizeof(T)]);
161 uint8_t * x =
new uint8_t[
sizeof(T)+
sizeof(
size_t)];
162 *
reinterpret_cast<size_t*
>(x) =
sizeof(T);
163 return reinterpret_cast<T*
>(x +
sizeof(size_t));
166 template <
typename T>
167 inline size_t tpie_size(T * p) {
168 if(!std::is_polymorphic<T>::value)
return sizeof(T);
169 uint8_t * x = ptr_cast<uint8_t *>(p);
170 return *
reinterpret_cast<size_t *
>(x -
sizeof(size_t));
178 template <
typename T>
208 template <
typename T>
216 deregister =
sizeof(T);
217 data = __allocate<T>();
229 delete[]
reinterpret_cast<uint8_t*
>(data);
239 template <
typename T>
259 template <
typename T,
typename ... Args>
262 new(m.allocate()) T(std::forward<Args>(args)...);
270 template <
typename T>
274 uint8_t * pp = ptr_cast<uint8_t *>(p);
276 if(!std::is_polymorphic<T>::value)
279 delete[] (pp -
sizeof(size_t));
287 template <
typename T>
295 template <
typename T>
296 void operator()(T * t) {
305 template <
typename T>
312 template <
typename T,
typename ... TT>
324 std::atomic_size_t count;
337 explicit operator bool()
const noexcept {
return bucket !=
nullptr;}
343 const memory_bucket & operator*()
const noexcept {
return *bucket;}
345 const memory_bucket * operator->()
const noexcept {
return bucket;}
360 typedef std::allocator<T> a_t;
365 typedef typename a_t::size_type size_type;
366 typedef typename a_t::difference_type difference_type;
367 typedef typename a_t::pointer pointer;
368 typedef typename a_t::const_pointer const_pointer;
369 typedef typename a_t::reference reference;
370 typedef typename a_t::const_reference const_reference;
371 typedef typename a_t::value_type value_type;
373 typedef std::true_type propagate_on_container_copy_assignment;
374 typedef std::true_type propagate_on_container_move_assignment;
375 typedef std::true_type propagate_on_container_swap;
380 template <
typename T2>
383 template <
typename T2>
386 allocator & operator=(
const allocator & o) noexcept {bucket = o.bucket;
return *
this;}
387 template <
typename T2>
389 allocator & operator=(
allocator && o) noexcept {bucket = std::move(o.bucket);
return *
this;}
390 template <
typename T2>
395 T * allocate(
size_t size,
const void * hint=0) {
397 if (bucket) bucket->count += size *
sizeof(T);
398 T * res = a.allocate(size, hint);
402 void deallocate(T * p,
size_t n) {
404 if (bucket) bucket->count -= n *
sizeof(T);
406 return a.deallocate(p, n);
408 size_t max_size() const noexcept {
return a.max_size();}
410 template <
typename U,
typename ...TT>
411 void construct(U * p, TT &&...x) {a.construct(p, std::forward<TT>(x)...);}
417 template <
typename U>
418 void destroy(U * p) {
421 pointer address(reference x)
const noexcept {
return &x;}
422 const_pointer address(const_reference x)
const noexcept {
return &x;}
425 friend bool operator==(
const allocator & l,
const allocator & r) noexcept {
return l.bucket == r.bucket;}
426 friend bool operator!=(
const allocator & l,
const allocator & r) noexcept {
return l.bucket != r.bucket;}
428 template <
typename U>
429 friend class allocator;
442 #endif //__TPIE_MEMORY_H__