Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
heap_allocator.h
Go to the documentation of this file.
1#ifndef _RHEOLEF_HEAP_ALLOCATOR_H
2#define _RHEOLEF_HEAP_ALLOCATOR_H
23
24#include <memory>
25#include <limits>
26#include "rheolef/compiler.h"
27#include "rheolef/pretty_name.h"
28
29namespace rheolef {
30
31/*Class:man
32NAME: heap_allocator - heap-based allocator
33DESCRIPTION:
34 Heap allocators are generally used when there is a lot of allocation and deallocation
35 of small objects.
36 For instance, this is often the case when dealing with @code{std::list} and @code{std::map}.
37
38 Heap-based allocator is conform to the STL specification of allocators.
39 It does not "free" the memory until the heap is destroyed.
40
41 This allocator handles an a priori unlimited area of memory: a sequence
42 of growing chunks are allocated.
43 For a limited memory handler in the same spirit, see "stack_allocator"(9).
44EXAMPLE:
45 @example
46 typedef map <size_t, double, less<size_t>, heap_allocator<pair<size_t,double> > > map_type;
47 map_type a;
48 a.insert (make_pair (0, 3.14));
49 a.insert (make_pair (1, 1.17));
50 for (map_type::iterator iter = a.begin(), last = a.end(); iter != last; iter++) @{
51 cout << (*iter).first << " " << (*iter).second << endl;
52 @}
53 @end example
54SEE ALSO: "stack_allocator"(9).
55AUTHORS:
56 LJK-IMAG, 38041 Grenoble cedex 9, France
57 | Pierre.Saramito@imag.fr
58DATE: 15 december 2010
59End:
60*/
61} // namespace rheolef
62
63#ifndef _RHEOLEF_USE_HEAP_ALLOCATOR
64namespace rheolef {
65template<class T> using heap_allocator = std::allocator<T>;
66} // namespace rheolef
67#else // _RHEOLEF_USE_HEAP_ALLOCATOR
68
69namespace rheolef {
70
71//<verbatim:
72template <typename T>
74protected:
75 struct handler_type; // forward declaration:
76public:
77
78// typedefs:
79
80 typedef size_t size_type;
81 typedef std::ptrdiff_t difference_type;
82 typedef T* pointer;
83 typedef const T* const_pointer;
84 typedef T& reference;
85 typedef const T& const_reference;
86 typedef T value_type;
87
88// constructors:
89
91 : handler (new handler_type)
92 {
93 }
94 heap_allocator (const heap_allocator& ha) throw()
95 : handler (ha.handler)
96 {
98 }
99 template <typename U>
101 : handler ((typename heap_allocator<T>::handler_type*)(ha.handler))
102 {
104 }
106 {
107 check_macro (handler != NULL, "unexpected null mem_info");
108 if (--handler->reference_count == 0) delete handler;
109 }
110 // Rebind to allocators of other types
111 template <typename U>
112 struct rebind {
114 };
115
116// assignment:
117
119 {
120 handler = ha.handler;
122 return *this;
123 }
124
125// utility functions:
126
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); }
130
131// in-place construction/destruction
132
134 {
135 // placement new operator:
136 new( reinterpret_cast<void*>(p) ) T(c);
137 }
138 // C++ 2011: default construct a value of type T at the location referenced by p
139 void construct (pointer p) { new ( reinterpret_cast<void*>(p) ) T(); }
140
142 {
143 // call destructor directly:
144 (p)->~T();
145 }
146
147// allocate raw memory
148
149 pointer allocate (size_type n, const void* = NULL)
150 {
151 return pointer (handler->raw_allocate (n*sizeof(T)));
152 }
154 {
155 // No need to free heap memory
156 }
157 const handler_type* get_handler() const {
158 return handler;
159 }
160
161// data:
162
163protected:
165 template <typename U> friend class heap_allocator;
166};
167//>verbatim:
168
169// Comparison
170template <typename T1>
171bool operator== (const heap_allocator<T1>& lhs, const heap_allocator<T1>& rhs) throw()
172{
173 return lhs.get_handler() == rhs.get_handler();
174}
175template <typename T1>
176bool operator!= (const heap_allocator<T1>& lhs, const heap_allocator<T1>& rhs) throw()
177{
178 return lhs.get_handler() != rhs.get_handler();
179}
180
181// ==========================================================================
182// heap_allocation::handler class implementation
183// ==========================================================================
184template<class T>
186
187// cstors:
188 handler_type ();
190// modifier:
191 unsigned char* raw_allocate (size_type size);
192// data:
193 std::list<std::vector<unsigned char> > heap;
197 static const size_type heap_block_size_init = 512*sizeof(T);
198};
199template<class T>
200inline
202 : heap (),
203 heap_block_size (heap_block_size_init),
204 heap_block_last_free (0),
205 reference_count (1)
206{
207 heap.push_front (std::vector<unsigned char>(heap_block_size));
208}
209template<class T>
210inline
211unsigned char*
213{
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;
218 }
219 std::vector<unsigned char>& block = *(heap.begin());
220 unsigned char* p = &(block [heap_block_last_free]);
221 heap_block_last_free += size;
222 return p;
223}
224template<class T>
225inline
227{
228 heap.erase (heap.begin(), heap.end());
229}
230
231}// namespace rheolef
232
233// ==========================================================================
234// std::allocator_traits
235// ==========================================================================
236namespace std {
237
238template <class T>
239struct allocator_traits<rheolef::heap_allocator<T>> {
240// typedefs
241
243 using value_type = T;
244 using pointer = 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;
252 using propagate_on_container_swap = std::false_type;
253 using is_always_equal = typename std::is_empty<rheolef::heap_allocator<T>>::type;
254 template <class U>
256
257// members
258
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); }
263 template <class U>
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&
266};
267
268} // namespace std
269#endif // _RHEOLEF_USE_HEAP_ALLOCATOR
270#endif // _RHEOLEF_HEAP_ALLOCATOR_H
heap_allocator(const heap_allocator &ha)
const handler_type * get_handler() const
heap_allocator & operator=(const heap_allocator &ha)
pointer allocate(size_type n, const void *=NULL)
pointer address(reference r) const
void construct(pointer p, const_reference c)
void construct(pointer p)
size_type max_size() const
heap_allocator(const heap_allocator< U > &ha)
std::ptrdiff_t difference_type
void deallocate(pointer p, size_type n)
const_pointer address(const_reference c) const
Expr1::float_type T
Definition field_expr.h:230
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 heap_allocator< T1 > &lhs, const heap_allocator< T1 > &rhs)
bool operator==(const heap_allocator< T1 > &lhs, const heap_allocator< T1 > &rhs)
STL namespace.
Definition sphere.icc:25
unsigned char * raw_allocate(size_type size)
std::list< std::vector< unsigned char > > heap
typename std::pointer_traits< pointer >::difference_type difference_type
typename std::pointer_traits< pointer >::rebind< const void > const_void_pointer
typename std::pointer_traits< pointer >::rebind< const value_type > const_pointer
static void deallocate(allocator_type &a, pointer p, size_type n)
typename std::pointer_traits< pointer >::rebind< void > void_pointer
static void construct(allocator_type &a, pointer p, const T &c)
static pointer allocate(allocator_type &a, size_type n)
typename std::make_unsigned< difference_type >::type size_type
static size_type max_size(const allocator_type &a)
static void construct(allocator_type &a, pointer p)
typename std::is_empty< rheolef::heap_allocator< T > >::type is_always_equal
static void destroy(allocator_type &a, U *p)