1#ifndef _RHEOLEF_HEAP_ALLOCATOR_H
2#define _RHEOLEF_HEAP_ALLOCATOR_H
26#include "rheolef/compiler.h"
27#include "rheolef/pretty_name.h"
63#ifndef _RHEOLEF_USE_HEAP_ALLOCATOR
81 typedef std::ptrdiff_t difference_type;
83 typedef const T* const_pointer;
85 typedef const T& const_reference;
90 heap_allocator()
throw()
91 : handler (
new handler_type)
94 heap_allocator (
const heap_allocator& ha)
throw()
95 : handler (ha.handler)
97 ++handler->reference_count;
100 heap_allocator (
const heap_allocator<U>& ha)
throw()
101 : handler ((
typename heap_allocator<T>::handler_type*)(ha.handler))
103 ++handler->reference_count;
105 ~heap_allocator()
throw()
107 check_macro (handler != NULL,
"unexpected null mem_info");
108 if (--handler->reference_count == 0)
delete handler;
111 template <
typename U>
113 typedef heap_allocator<U> other;
118 heap_allocator& operator= (
const heap_allocator& ha)
120 handler = ha.handler;
121 ++handler->reference_count;
127 pointer address (reference r)
const {
return &r; }
128 const_pointer address (const_reference c)
const {
return &c; }
129 size_type max_size()
const {
return std::numeric_limits<size_t>::max() /
sizeof(
T); }
133 void construct (pointer
p, const_reference c)
136 new(
reinterpret_cast<void*
>(
p) )
T(c);
139 void construct (pointer
p) {
new (
reinterpret_cast<void*
>(
p) )
T(); }
141 void destroy (pointer
p)
149 pointer allocate (
size_type n,
const void* = NULL)
151 return pointer (handler->raw_allocate (n*
sizeof(
T)));
157 const handler_type* get_handler()
const {
164 handler_type* handler;
165 template <
typename U>
friend class heap_allocator;
170template <
typename T1>
171bool operator== (
const heap_allocator<T1>& lhs,
const heap_allocator<T1>& rhs)
throw()
173 return lhs.get_handler() == rhs.get_handler();
175template <
typename T1>
176bool operator!= (
const heap_allocator<T1>& lhs,
const heap_allocator<T1>& rhs)
throw()
178 return lhs.get_handler() != rhs.get_handler();
191 unsigned char* raw_allocate (
size_type size);
193 std::list<std::vector<unsigned char> > heap;
197 static const size_type heap_block_size_init = 512*
sizeof(
T);
201heap_allocator<T>::handler_type::handler_type()
203 heap_block_size (heap_block_size_init),
204 heap_block_last_free (0),
207 heap.push_front (std::vector<unsigned char>(heap_block_size));
212heap_allocator<T>::handler_type::raw_allocate (
size_type size)
214 if (heap_block_last_free + size > heap_block_size) {
215 heap_block_size = std::max (size, 2*heap_block_size);
216 heap.push_front (std::vector<unsigned char>(heap_block_size));
217 heap_block_last_free = 0;
219 std::vector<unsigned char>& block = *(heap.begin());
220 unsigned char*
p = &(block [heap_block_last_free]);
221 heap_block_last_free += size;
226heap_allocator<T>::handler_type::~handler_type()
228 heap.erase (heap.begin(), heap.end());
239struct allocator_traits<rheolef::heap_allocator<T>> {
242 using allocator_type = rheolef::heap_allocator<T>;
243 using value_type =
T;
245 using const_pointer =
typename std::pointer_traits<pointer>::rebind<
const value_type>;
246 using void_pointer =
typename std::pointer_traits<pointer>::rebind<
void>;
247 using const_void_pointer =
typename std::pointer_traits<pointer>::rebind<
const void>;
248 using difference_type =
typename std::pointer_traits<pointer>::difference_type;
249 using size_type =
typename std::make_unsigned<difference_type>::type;
250 using propagate_on_container_copy_assignment = std::false_type;
251 using propagate_on_container_move_assignment = std::false_type;
252 using propagate_on_container_swap = std::false_type;
253 using is_always_equal =
typename std::is_empty<rheolef::heap_allocator<T>>::type;
255 using rebind_alloc = rheolef::heap_allocator<U>;
259 static pointer allocate (allocator_type& a,
size_type n) {
return a.allocate(n); }
260 static void deallocate (allocator_type& a, pointer p,
size_type n) {
a.deallocate (p, n); }
261 static void construct (allocator_type& a, pointer p) {
a.construct (p); }
262 static void construct (allocator_type& a, pointer p,
const T& c) {
a.construct (p,c); }
264 static void destroy (allocator_type& a, U* p) {}
265 static size_type max_size(
const allocator_type& a ) {
return std::numeric_limits<size_type>::mqx(); }allocator_type&
field::size_type size_type
std::allocator< T > heap_allocator
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
This file is part of Rheolef.
bool operator!=(const stack_allocator< T1 > &lhs, const stack_allocator< T1 > &rhs)
bool operator==(const stack_allocator< T1 > &lhs, const stack_allocator< T1 > &rhs)