rheolef
6.3
Main Page
Namespaces
Classes
Files
Examples
File List
File Members
util
lib
stack_allocator.h
Go to the documentation of this file.
1
#ifndef _RHEOLEF_STACK_ALLOCATOR_H
2
#define _RHEOLEF_STACK_ALLOCATOR_H
3
4
#include <memory>
5
#include <limits>
6
#include "rheolef/compiler.h"
7
#include "rheolef/pretty_name.h"
8
9
namespace
rheolef {
10
44
//<begin_verbatim:
45
template
<
typename
T>
46
class
stack_allocator
{
47
protected
:
48
struct
handler_type
;
// forward declaration:
49
public
:
50
51
52
typedef
size_t
size_type
;
53
typedef
std::ptrdiff_t
difference_type
;
54
typedef
T*
pointer
;
55
typedef
const
T*
const_pointer
;
56
typedef
T&
reference
;
57
typedef
const
T&
const_reference
;
58
typedef
T
value_type
;
59
60
61
stack_allocator
() throw()
62
:
handler
(new
handler_type
)
63
{
64
}
65
stack_allocator
(
unsigned
char
* stack,
size_t
stack_size)
throw
()
66
:
handler
(
new
handler_type
(stack, stack_size))
67
{
68
warning_macro
(
"stack_allocator cstor"
);
69
}
70
stack_allocator
(
const
stack_allocator
& sa)
throw
()
71
:
handler
(sa.handler)
72
{
73
++
handler
->
reference_count
;
74
}
75
template
<
typename
U>
76
stack_allocator
(
const
stack_allocator<U>
& sa)
throw
()
77
:
handler
((
typename
stack_allocator<T>::handler_type
*)(sa.handler))
78
{
79
++
handler
->
reference_count
;
80
}
81
~stack_allocator
() throw()
82
{
83
warning_macro
(
"stack_allocator dstor"
);
84
check_macro
(
handler
!= NULL,
"unexpected null mem_info"
);
85
if
(--
handler
->
reference_count
== 0)
delete
handler
;
86
}
87
template
<
typename
U>
88
struct
rebind
{
89
typedef
stack_allocator<U>
other
;
90
};
91
92
93
stack_allocator
&
operator=
(
const
stack_allocator
& sa)
94
{
95
handler
= sa.
handler
;
96
++
handler
->
reference_count
;
97
return
*
this
;
98
}
99
100
101
pointer
address
(
reference
r)
const
{
return
&r; }
102
const_pointer
address
(
const_reference
c)
const
{
return
&c; }
103
size_type
max_size
()
const
{
return
std::numeric_limits<size_t>::max
() /
sizeof
(T); }
104
105
// in-place construction/destruction
106
107
void
construct
(
pointer
p,
const_reference
c)
108
{
109
new
(
reinterpret_cast<
void
*
>
(p) ) T(c);
110
}
111
void
construct
(
pointer
p) {
new
(
reinterpret_cast<
void
*
>
(p) ) T(); }
112
113
void
destroy
(
pointer
p)
114
{
115
(p)->~T();
116
}
117
118
119
pointer
allocate
(
size_type
n,
const
void
* = NULL)
120
{
121
warning_macro
(
"allocate "
<<n<<
" type "
<<
typename_macro
(T));
122
check_macro
(
handler
->
stack
!= NULL,
"unexpected null stack"
);
123
void
* p =
handler
->
stack
+
handler
->
allocated_size
;
124
handler
->
allocated_size
+= n*
sizeof
(T);
125
126
if
(
handler
->
allocated_size
+ 1 >
handler
->
max_size
) {
127
warning_macro
(
"stack is full: throwing..."
);
128
throw
std::bad_alloc();
129
}
130
return
pointer
(p);
131
}
132
void
deallocate
(
pointer
p,
size_type
n)
133
{
134
warning_macro
(
"deallocate "
<<n<<
" type "
<<
typename_macro
(T));
135
}
136
const
handler_type
*
get_handler
()
const
{
137
return
handler
;
138
}
139
140
141
protected
:
142
struct
handler_type
{
143
unsigned
char
*
stack
;
144
size_t
allocated_size
;
145
size_t
max_size
;
146
size_t
reference_count
;
147
148
handler_type
()
149
:
stack
(NULL),
150
allocated_size
(0),
151
max_size
(0),
152
reference_count
(1)
153
{
154
warning_macro
(
"stack_allocator::mem_info cstor NULL"
);
155
}
156
handler_type
(
unsigned
char
* stack1,
size_t
size1)
157
:
stack
(stack1),
158
allocated_size
(0),
159
max_size
(size1),
160
reference_count
(1)
161
{
162
warning_macro
(
"stack_allocator::mem_info cstori: size="
<<
max_size
);
163
}
164
~handler_type
()
165
{
166
warning_macro
(
"stack_allocator::mem_info dstor: size="
<<
max_size
);
167
}
168
};
169
handler_type
*
handler
;
170
template
<
typename
U>
friend
class
stack_allocator
;
171
};
172
template
<
typename
T1>
173
bool
operator==
(
const
stack_allocator<T1>
& lhs,
const
stack_allocator<T1>
& rhs)
throw
()
174
{
175
return
lhs.get_handler() == rhs.get_handler();
176
}
177
template
<
typename
T1>
178
bool
operator!=
(
const
stack_allocator<T1>
& lhs,
const
stack_allocator<T1>
& rhs)
throw
()
179
{
180
return
lhs.get_handler() != rhs.get_handler();
181
}
182
//>end_verbatim:
183
184
}
// namespace rheolef
185
#endif // STACK_ALLOCATOR_H
186