Embedded Template Library 1.0
Loading...
Searching...
No Matches
ipool.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_IPOOL_INCLUDED
32#define ETL_IPOOL_INCLUDED
33
34#include "platform.h"
35#include "error_handler.h"
36#include "exception.h"
37#include "static_assert.h"
38#include "utility.h"
39#include "memory.h"
40#include "placement_new.h"
41
42#define ETL_POOL_CPP03_CODE 0
43
44namespace etl
45{
46 //***************************************************************************
49 //***************************************************************************
58
59 //***************************************************************************
62 //***************************************************************************
64 {
65 public:
66
68 : pool_exception(ETL_ERROR_TEXT("pool:allocation", ETL_POOL_FILE_ID"A"), file_name_, line_number_)
69 {}
70 };
71
72 //***************************************************************************
75 //***************************************************************************
77 {
78 public:
79
81 : pool_exception(ETL_ERROR_TEXT("pool:not in pool", ETL_POOL_FILE_ID"B"), file_name_, line_number_)
82 {}
83 };
84
85 //***************************************************************************
88 //***************************************************************************
90 {
91 public:
92
94 : pool_exception(ETL_ERROR_TEXT("pool:element size", ETL_POOL_FILE_ID"C"), file_name_, line_number_)
95 {}
96 };
97
98 //***************************************************************************
100 //***************************************************************************
101 class ipool
102 {
103 public:
104
105 typedef size_t size_type;
106
107 //*************************************************************************
111 //*************************************************************************
112 template <typename T>
114 {
115 if (sizeof(T) > Item_Size)
116 {
117 ETL_ASSERT(false, ETL_ERROR(etl::pool_element_size));
118 }
119
120 return reinterpret_cast<T*>(allocate_item());
121 }
122
123#if ETL_CPP11_NOT_SUPPORTED || ETL_POOL_CPP03_CODE || ETL_USING_STLPORT
124 //*************************************************************************
128 //*************************************************************************
129 template <typename T>
131 {
132 T* p = allocate<T>();
133
134 if (p)
135 {
136 ::new (p) T();
137 }
138
139 return p;
140 }
141
142 //*************************************************************************
146 //*************************************************************************
147 template <typename T, typename T1>
148 T* create(const T1& value1)
149 {
150 T* p = allocate<T>();
151
152 if (p)
153 {
154 ::new (p) T(value1);
155 }
156
157 return p;
158 }
159
160 template <typename T, typename T1, typename T2>
161 T* create(const T1& value1, const T2& value2)
162 {
163 T* p = allocate<T>();
164
165 if (p)
166 {
167 ::new (p) T(value1, value2);
168 }
169
170 return p;
171 }
172
173 template <typename T, typename T1, typename T2, typename T3>
174 T* create(const T1& value1, const T2& value2, const T3& value3)
175 {
176 T* p = allocate<T>();
177
178 if (p)
179 {
180 ::new (p) T(value1, value2, value3);
181 }
182
183 return p;
184 }
185
186 template <typename T, typename T1, typename T2, typename T3, typename T4>
187 T* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
188 {
189 T* p = allocate<T>();
190
191 if (p)
192 {
193 ::new (p) T(value1, value2, value3, value4);
194 }
195
196 return p;
197 }
198#else
199 //*************************************************************************
201 //*************************************************************************
202 template <typename T, typename... Args>
203 T* create(Args&&... args)
204 {
205 T* p = allocate<T>();
206
207 if (p)
208 {
209 ::new (p) T(etl::forward<Args>(args)...);
210 }
211
212 return p;
213 }
214#endif
215
216 //*************************************************************************
220 //*************************************************************************
221 template <typename T>
222 void destroy(const T* const p_object)
223 {
224 if (sizeof(T) > Item_Size)
225 {
226 ETL_ASSERT(false, ETL_ERROR(etl::pool_element_size));
227 }
228
229 p_object->~T();
230 release(p_object);
231 }
232
233 //*************************************************************************
238 //*************************************************************************
239 void release(const void* const p_object)
240 {
241 const uintptr_t p = uintptr_t(p_object);
242 release_item((char*)p);
243 }
244
245 //*************************************************************************
247 //*************************************************************************
249 {
250 items_allocated = 0;
251 items_initialised = 0;
252 p_next = p_buffer;
253 }
254
255 //*************************************************************************
259 //*************************************************************************
260 bool is_in_pool(const void* const p_object) const
261 {
262 const uintptr_t p = uintptr_t(p_object);
263 return is_item_in_pool((const char*)p);
264 }
265
266 //*************************************************************************
268 //*************************************************************************
269 size_t max_size() const
270 {
271 return Max_Size;
272 }
273
274 //*************************************************************************
276 //*************************************************************************
277 size_t max_item_size() const
278 {
279 return Item_Size;
280 }
281
282 //*************************************************************************
284 //*************************************************************************
285 size_t capacity() const
286 {
287 return Max_Size;
288 }
289
290 //*************************************************************************
292 //*************************************************************************
293 size_t available() const
294 {
295 return Max_Size - items_allocated;
296 }
297
298 //*************************************************************************
300 //*************************************************************************
301 size_t size() const
302 {
303 return items_allocated;
304 }
305
306 //*************************************************************************
309 //*************************************************************************
310 bool empty() const
311 {
312 return items_allocated == 0;
313 }
314
315 //*************************************************************************
318 //*************************************************************************
319 bool full() const
320 {
321 return items_allocated == Max_Size;
322 }
323
324 protected:
325
326 //*************************************************************************
328 //*************************************************************************
330 : p_buffer(p_buffer_),
331 p_next(p_buffer_),
332 items_allocated(0),
333 items_initialised(0),
334 Item_Size(item_size_),
335 Max_Size(max_size_)
336 {
337 }
338
339 private:
340
341 //*************************************************************************
343 //*************************************************************************
344 char* allocate_item()
345 {
346 char* p_value = ETL_NULLPTR;
347
348 // Any free space left?
349 if (items_allocated < Max_Size)
350 {
351 // Initialise another one if necessary.
352 if (items_initialised < Max_Size)
353 {
354 char* p = p_buffer + (items_initialised * Item_Size);
355 char* np = p + Item_Size;
356 *reinterpret_cast<char**>(p) = np;
357 ++items_initialised;
358 }
359
360 // Get the address of new allocated item.
361 p_value = p_next;
362
363 ++items_allocated;
364 if (items_allocated < Max_Size)
365 {
366 // Set up the pointer to the next free item
367 p_next = *reinterpret_cast<char**>(p_next);
368 }
369 else
370 {
371 // No more left!
372 p_next = ETL_NULLPTR;
373 }
374 }
375 else
376 {
377 ETL_ASSERT(false, ETL_ERROR(pool_no_allocation));
378 }
379
380 return p_value;
381 }
382
383 //*************************************************************************
385 //*************************************************************************
386 void release_item(char* p_value)
387 {
388 // Does it belong to us?
389 ETL_ASSERT(is_item_in_pool(p_value), ETL_ERROR(pool_object_not_in_pool));
390
391 if (items_allocated > 0)
392 {
393 // Point it to the current free item.
394 *(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
395
396 p_next = p_value;
397
398 --items_allocated;
399 }
400 else
401 {
402 ETL_ASSERT_FAIL(ETL_ERROR(pool_no_allocation));
403 }
404 }
405
406 //*************************************************************************
408 //*************************************************************************
409 bool is_item_in_pool(const char* p) const
410 {
411 // Within the range of the buffer?
412 intptr_t distance = p - p_buffer;
413 bool is_within_range = (distance >= 0) && (distance <= intptr_t((Item_Size * Max_Size) - Item_Size));
414
415 // Modulus and division can be slow on some architectures, so only do this in debug.
416#if ETL_IS_DEBUG_BUILD
417 // Is the address on a valid object boundary?
418 bool is_valid_address = ((distance % Item_Size) == 0);
419#else
420 bool is_valid_address = true;
421#endif
422
423 return is_within_range && is_valid_address;
424 }
425
426 // Disable copy construction and assignment.
427 ipool(const ipool&);
428 ipool& operator =(const ipool&);
429
430 char* p_buffer;
431 char* p_next;
432
433 uint32_t items_allocated;
434 uint32_t items_initialised;
435
436 const uint32_t Item_Size;
437 const uint32_t Max_Size;
438
439 //*************************************************************************
441 //*************************************************************************
442#if defined(ETL_POLYMORPHIC_POOL) || defined(ETL_POLYMORPHIC_CONTAINERS)
443 public:
444 virtual ~ipool()
445 {
446 }
447#else
448 protected:
450 {
451 }
452#endif
453 };
454}
455
456#endif
457
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition exception.h:47
size_t size() const
Returns the number of allocated items in the pool.
Definition ipool.h:301
~ipool()
Destructor.
Definition ipool.h:449
bool empty() const
Definition ipool.h:310
void release_all()
Release all objects in the pool.
Definition ipool.h:248
bool full() const
Definition ipool.h:319
size_t max_size() const
Returns the maximum number of items in the pool.
Definition ipool.h:269
T * allocate()
Definition ipool.h:113
void release(const void *const p_object)
Definition ipool.h:239
size_t capacity() const
Returns the maximum number of items in the pool.
Definition ipool.h:285
ipool(char *p_buffer_, uint32_t item_size_, uint32_t max_size_)
Constructor.
Definition ipool.h:329
size_t max_item_size() const
Returns the maximum size of an item in the pool.
Definition ipool.h:277
bool is_in_pool(const void *const p_object) const
Definition ipool.h:260
size_t available() const
Returns the number of free items in the pool.
Definition ipool.h:293
T * create()
Definition ipool.h:130
void destroy(const T *const p_object)
Definition ipool.h:222
T * create(const T1 &value1)
Definition ipool.h:148
Definition ipool.h:102
Definition ipool.h:90
Definition ipool.h:51
Definition ipool.h:64
Definition ipool.h:77
bitset_ext
Definition absolute.h:38
pair holds two objects of arbitrary type
Definition utility.h:164