Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
rw_allocator.h
Go to the documentation of this file.
1
29#ifndef RW_ALLOCATOR_INCLUDED
30#define RW_ALLOCATOR_INCLUDED
31
32
33#include <rw_testdefs.h>
34
35
37
38// declare to avoid dragging in all of <memory>
39// (yes, it is undefined for programs to do that)
40template <class T>
41class allocator;
42
43} // namespace std
44
45
47{
48 // identifies each member function of a standard allocator class
49 enum MemFun {
50 m_ctor, // ordinary constructor
51 m_cpy_ctor, // copy constructor
52 m_cvt_ctor, // converting (template) constructor
53 m_cpy_assign, // ordinary assignment operator
54 m_cvt_assign, // converting (template) assignment operator
55 m_dtor, // destructor
56 m_allocate, m_deallocate,
57 m_construct, m_destroy,
58 m_address, m_max_size,
59 n_funs
60 };
61
62 // constructs an allocator object managing a memory pool
63 // of the specified size (bytes and blocks)
64 SharedAlloc (_RWSTD_SIZE_T /* max_bytes */ = _RWSTD_SIZE_MAX,
65 _RWSTD_SIZE_T /* max_blocks */ = _RWSTD_SIZE_MAX);
66
67 virtual ~SharedAlloc ();
68
69 // attempts to allocate storage for nelems objects of elemsize
70 // bytes each and returns a pointer to the allocated storage
71 // on success; throws std::bad_alloc on failure
72 virtual void*
73 allocate (_RWSTD_SIZE_T /* nelems */,
74 _RWSTD_SIZE_T /* elemsize */,
75 const void* /* hint */);
76
77 // deallocates storage at ptr allocated by a call to allocate
78 // for nelems objects of elemsize bytes each
79 virtual void
80 deallocate (void* /* ptr */,
81 _RWSTD_SIZE_T /* nelems */,
82 _RWSTD_SIZE_T /* elemsize */);
83
84 // returns the maximum number of objects of elemsize each
85 // that can be allocated from the pool managed by *this
86 virtual _RWSTD_SIZE_T
87 max_size (_RWSTD_SIZE_T /* elemsize */ = 1);
88
89 // records a call to the allocator member function fun and
90 // throws an exception derived from std::bad_alloc if the
91 // number of calls to the member function reaches the limit
92 // specified by throw_at_calls_
93 virtual void
94 funcall (MemFun /* fun */, const SharedAlloc* = 0);
95
96 // gets or sets a pointer to the global allocator object
97 static SharedAlloc*
98 instance (SharedAlloc* = 0);
99
100 // returns a unique id of this allocator object
101 int id () const { return id_; }
102
103 // resets the n_calls_ array to all zeros
104 void reset_call_counters ();
105
106 // returns the name of the member function
107 static const char* func_name (MemFun);
108
109 _RWSTD_SIZE_T max_bytes_; // memory pool size in bytes
110 _RWSTD_SIZE_T max_blocks_; // memory pool size in blocks
111
112 _RWSTD_SIZE_T n_bytes_; // number of allocated bytes
113 _RWSTD_SIZE_T n_blocks_; // number of allocated blocks
114
115 _RWSTD_SIZE_T n_refs_; // number of references
116
117 // counter of the number of calls to each allocator member function
118 // made throughout the lifetime of this object
119 _RWSTD_SIZE_T n_calls_ [n_funs];
120
121 // counter of the number of exceptions thrown by each member function
122 // throughout the lifetime of this object
123 _RWSTD_SIZE_T n_throws_ [n_funs];
124
125 // member function counter value that, when reached, will cause
126 // an exception derived from std::bad_alloc to be thrown
127 _RWSTD_SIZE_T throw_at_calls_ [n_funs];
128
129private:
130 int id_;
131};
132
133
134// allocator types for easy specialization
135template <class T>
137{
138 typedef _RWSTD_SIZE_T size_type;
139 typedef _RWSTD_PTRDIFF_T difference_type;
140 typedef T* pointer;
141 typedef const T* const_pointer;
142 typedef T& reference;
143 typedef const T& const_reference;
144};
145
146
147template <class T, class Types = AllocTypes<T> >
149{
150// private:
152
153public:
154 typedef T value_type;
155 typedef typename Types::size_type size_type;
156 typedef typename Types::difference_type difference_type;
157 typedef typename Types::pointer pointer;
158 typedef typename Types::const_pointer const_pointer;
159 typedef typename Types::reference reference;
160 typedef typename Types::const_reference const_reference;
161
163 : pal_ (pal ? pal : SharedAlloc::instance ()) {
164 RW_ASSERT (0 != pal_);
166 }
167
169 : pal_ (rhs.pal_) {
170 RW_ASSERT (0 != pal_);
172 }
173
174 template <class U>
176 : pal_ (rhs.pal_) {
177 RW_ASSERT (0 != pal_);
179 }
180
181 template <class U>
183 pal_->funcall (pal_->m_cvt_assign, rhs.pal_);
184 pal_ = rhs.pal_;
185 }
186
187 template <class U>
188 struct rebind { typedef UserAlloc<U> other; };
189
190 void operator= (const UserAlloc &rhs) {
191 pal_->funcall (pal_->m_cpy_assign, rhs.pal_);
192 pal_ = rhs.pal_;
193 }
194
197 }
198
199 pointer allocate (size_type nelems, const void *hint = 0) {
200 void* const ptr = pal_->allocate (nelems, sizeof (value_type), hint);
202 }
203
205 pal_->deallocate (ptr, nelems, sizeof (value_type));
206 }
207
210 new (ptr) value_type (val);
211 }
212
215 ptr->~T ();
216 }
217
220 return &ref;
221 }
222
225 return &ref;
226 }
227
228 size_type max_size () const _THROWS (()) {
229 return pal_->max_size (sizeof (value_type));
230 }
231
232 bool operator== (const UserAlloc &rhs) const {
233 return pal_->id () == rhs.pal_->id ();
234 }
235
236 bool operator!= (const UserAlloc &rhs) const {
237 return !operator== (rhs);
238 }
239};
240
241
242// when (line <= 0) establishes a new check point for memory leaks
243// by storing the number and size of blocks of storage currently
244// allocated by operator new and by the SharedAlloc object pointed
245// to by palloc (when non-zero)
246// when (line > 0) reports the difference between the the number
247// and size of blocks of storage allocated at the last checkpoint
248// and the values specified by expect_blocks and expect_bytes
249_TEST_EXPORT void
250rw_check_leaks (const SharedAlloc* /* palloc */ = 0,
251 int /* line */ = 0,
252 _RWSTD_SIZE_T /* expect_blocks */ = 0,
253 _RWSTD_SIZE_T /* expect_bytes */ = _RWSTD_SIZE_MAX);
254
255
256// when (line <= 0) establishes a new check point for memory leaks
257// by storing the number and size of blocks of storage currently
258// allocated by operator new
259// when (line > 0) reports the difference between the the number
260// and size of blocks of storage allocated at the last checkpoint
261// and the values specified by expect_blocks and expect_bytes
262template <class charT>
263inline void
264rw_check_leaks (const std::allocator<charT>& /* unused */,
265 int line = 0,
266 _RWSTD_SIZE_T expect_blocks = 0,
267 _RWSTD_SIZE_T expect_bytes = _RWSTD_SIZE_MAX)
268{
269 // can't track memory leaks here
270 rw_check_leaks ((SharedAlloc*)0, line, expect_blocks, expect_bytes);
271}
272
273
274// when (line <= 0) establishes a new check point for memory leaks
275// by storing the number and size of blocks of storage currently
276// allocated by operator new and by the user-defined allocator
277// specified by the first argument
278// when (line > 0) reports the difference between the the number
279// and size of blocks of storage allocated at the last checkpoint
280// and the values specified by expect_blocks and expect_bytes
281template <class charT, class Types>
282inline void
284 int line = 0,
285 _RWSTD_SIZE_T expect_blocks = 0,
286 _RWSTD_SIZE_T expect_bytes = _RWSTD_SIZE_MAX)
287{
288 // track memory leaks via SharedAlloc
289 rw_check_leaks (alloc.pal_, line, expect_blocks, expect_bytes);
290}
291
292#endif // RW_ALLOCATOR_INCLUDED
#define T
Definition 17.names.cpp:163
#define rhs
Definition 17.names.cpp:536
#define hint
Definition 17.names.cpp:473
#define alloc
Definition 17.names.cpp:441
#define line
Definition 17.names.cpp:490
#define ptr
Definition 17.names.cpp:525
#define val
Definition 17.names.cpp:570
#define _THROWS()
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
Definition json.h:5363
_TEST_EXPORT void rw_check_leaks(const SharedAlloc *=0, int=0, _RWSTD_SIZE_T=0, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
MemFun
#define _TEST_EXPORT
Definition rw_testdefs.h:55
#define RW_ASSERT(expr)
_RWSTD_PTRDIFF_T difference_type
_RWSTD_SIZE_T size_type
const T * const_pointer
const T & const_reference
virtual void deallocate(void *, _RWSTD_SIZE_T, _RWSTD_SIZE_T)
virtual void funcall(MemFun, const SharedAlloc *=0)
_RWSTD_SIZE_T max_blocks_
virtual _RWSTD_SIZE_T max_size(_RWSTD_SIZE_T=1)
int id() const
_RWSTD_SIZE_T n_blocks_
_RWSTD_SIZE_T max_bytes_
virtual void * allocate(_RWSTD_SIZE_T, _RWSTD_SIZE_T, const void *)
_RWSTD_SIZE_T n_refs_
_RWSTD_SIZE_T n_bytes_
UserAlloc< U > other
UserAlloc(const UserAlloc< U > &rhs) _THROWS(())
size_type max_size() const _THROWS(())
const_pointer address(const_reference ref) const
bool operator!=(const UserAlloc &rhs) const
Types::size_type size_type
Types::pointer pointer
SharedAlloc * pal_
void operator=(const UserAlloc< U > &rhs)
UserAlloc(const UserAlloc &rhs) _THROWS(())
UserAlloc(SharedAlloc *pal=0) _THROWS(())
void destroy(pointer ptr)
Types::difference_type difference_type
void deallocate(pointer ptr, size_type nelems)
void construct(pointer ptr, const_reference val)
Types::const_pointer const_pointer
Types::reference reference
Types::const_reference const_reference
pointer allocate(size_type nelems, const void *hint=0)
pointer address(reference ref) const
bool operator==(const UserAlloc &rhs) const