BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlma_pool.h
Go to the documentation of this file.
1/// @file bdlma_pool.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlma_pool.h -*-C++-*-
8#ifndef INCLUDED_BDLMA_POOL
9#define INCLUDED_BDLMA_POOL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlma_pool bdlma_pool
15/// @brief Provide efficient allocation of memory blocks of uniform size.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlma
19/// @{
20/// @addtogroup bdlma_pool
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlma_pool-purpose"> Purpose</a>
25/// * <a href="#bdlma_pool-classes"> Classes </a>
26/// * <a href="#bdlma_pool-description"> Description </a>
27/// * <a href="#bdlma_pool-configuration-at-construction"> Configuration at Construction </a>
28/// * <a href="#bdlma_pool-overloaded-global-operator-new"> Overloaded Global Operator new </a>
29/// * <a href="#bdlma_pool-usage"> Usage </a>
30/// * <a href="#bdlma_pool-example-1-using-a-bdlma-pool-for-efficient-memory-allocation"> Example 1: Using a bdlma::Pool for Efficient Memory Allocation </a>
31///
32/// # Purpose {#bdlma_pool-purpose}
33/// Provide efficient allocation of memory blocks of uniform size.
34///
35/// # Classes {#bdlma_pool-classes}
36///
37/// - bdlma::Pool: memory manager that allocates memory blocks of uniform size
38///
39/// # Description {#bdlma_pool-description}
40/// This component implements a memory pool, `bdlma::Pool`, that
41/// allocates and manages maximally-aligned memory blocks of some uniform size
42/// specified at construction. A `bdlma::Pool` object maintains an internal
43/// linked list of free memory blocks, and dispenses one block for each
44/// `allocate` method invocation. When a memory block is deallocated, it is
45/// returned to the free list for potential reuse.
46///
47/// Whenever the linked list of free memory blocks is depleted, the
48/// `bdlma::Pool` replenishes the list by first allocating a large, contiguous
49/// "chunk" of memory, then splitting the chunk into multiple memory blocks. A
50/// chunk and its constituent memory blocks can be depicted visually:
51/// @code
52/// +-----+--- memory blocks of uniform size
53/// | |
54/// ----- ----- ------------
55/// | | | ... |
56/// =====^=====^============
57///
58/// \___________ __________/
59/// V
60/// a "chunk"
61/// @endcode
62/// Note that the size of the allocated chunk is determined by both the growth
63/// strategy and maximum blocks per chunk, either of which can be optionally
64/// specified at construction (see the "Configuration at Construction" section).
65///
66/// ## Configuration at Construction {#bdlma_pool-configuration-at-construction}
67///
68///
69/// When creating a `bdlma::Pool`, clients must specify the specific block size
70/// managed and dispensed by the pool. Furthermore, clients can optionally
71/// configure:
72///
73/// 1. GROWTH STRATEGY -- geometrically growing chunk size starting from 1 (in
74/// terms of the number of memory blocks per chunk), or fixed chunk size. If
75/// the growth strategy is not specified, geometric growth is used.
76/// 2. MAX BLOCKS PER CHUNK -- the maximum number of memory blocks within a
77/// chunk. If the maximum blocks per chunk is not specified, an
78/// implementation-defined default value is used.
79/// 3. BASIC ALLOCATOR -- the allocator used to supply memory to replenish the
80/// internal pool. If not specified, the currently installed default
81/// allocator is used (see @ref bslma_default ).
82///
83/// For example, if geometric growth is used and the maximum blocks per chunk is
84/// specified as 30, the chunk size grows geometrically, starting from 1, until
85/// the specified maximum blocks per chunk, as follows:
86/// @code
87/// 1, 2, 4, 8, 16, 30, 30, 30 ...
88/// @endcode
89/// If constant growth is used, the chunk size is always the specified maximum
90/// blocks per chunk (or an implementation-defined value if the maximum blocks
91/// per chunk is not specified), for example:
92/// @code
93/// 30, 30, 30 ...
94/// @endcode
95/// A default-constructed pool has an initial chunk size of 1 (i.e., the number
96/// of memory blocks of a given size allocated at once to replenish a pool's
97/// memory), and the pool's chunk size grows geometrically until it reaches an
98/// implementation-defined maximum, at which it is capped. Finally, unless
99/// otherwise specified, all memory comes from the allocator that was the
100/// currently installed default allocator at the time the `bdlma::Pool` was
101/// created.
102///
103/// ## Overloaded Global Operator new {#bdlma_pool-overloaded-global-operator-new}
104///
105///
106/// This component overloads the global `operator new` to allow convenient
107/// syntax for the construction of objects using a `bdlma::Pool`. The `new`
108/// operator supplied in this component takes a `bdlma::Pool` argument
109/// indicating the source of the memory. Consider the following use of standard
110/// placement `new` syntax (supplied by `bsl_new.h`) along with a `bdlma::Pool`
111/// to allocate an object of type `T`. Note that the size of `T` must be the
112/// same or smaller than the `blockSize` with which the pool is constructed:
113/// @code
114/// void f(bdlma::Pool *pool)
115/// {
116/// assert(pool->blockSize() >= sizeof(T));
117///
118/// T *t = new (pool->allocate()) T(...);
119///
120/// // ...
121/// }
122/// @endcode
123/// This usage style is not exception-safe. If the constructor of `T` throws an
124/// exception, `pool->deallocate` is never called.
125///
126/// Supplying an overloaded global `operator new`:
127/// @code
128/// ::operator new(bsl::size_t size, BloombergLP::bdlma::Pool& pool);
129/// @endcode
130/// allows for the following cleaner usage, which does not require the size
131/// calculation and guarantees that `pool->deallocate` *is* called in the case
132/// of an exception:
133/// @code
134/// void f(bdlma::Pool *pool)
135/// {
136/// assert(pool->blockSize() >= sizeof(T));
137///
138/// T *t = new (*pool) T(...);
139///
140/// // ...
141/// @endcode
142/// Also note that the analogous version of operator `delete` should *not* be
143/// called directly. Instead, this component provides a static template member
144/// function `deleteObject`, parameterized on `TYPE`:
145/// @code
146/// pool->deleteObject(t);
147/// }
148/// @endcode
149/// The above `deleteObject` call is equivalent to performing the following:
150/// @code
151/// t->~TYPE();
152/// pool->deallocate(t);
153/// @endcode
154/// An overloaded operator `delete` is supplied solely to allow the compiler to
155/// arrange for it to be called in case of an exception.
156///
157/// ## Usage {#bdlma_pool-usage}
158///
159///
160/// This section illustrates intended use of this component.
161///
162/// ### Example 1: Using a bdlma::Pool for Efficient Memory Allocation {#bdlma_pool-example-1-using-a-bdlma-pool-for-efficient-memory-allocation}
163///
164///
165/// A `bdlma::Pool` can be used by node-based containers (such as lists, trees,
166/// and hash tables that hold multiple elements of uniform size) for efficient
167/// memory allocation of new elements. The following container template class,
168/// `my_PooledArray`, stores values of (template parameter) `TYPE`
169/// "out-of-place" as nodes in a `vector` of pointers. Since the size of each
170/// node is fixed and known *a priori*, the class uses a `bdlma::Pool` to
171/// allocate memory for the nodes to improve memory allocation efficiency. Note
172/// that for simplicity, we assume that `TYPE` does not require an allocator,
173/// and that calls to the destructor of `TYPE` can be elided.
174///
175/// First, we define the interface of our `my_PooledArray` template class:
176/// @code
177/// // my_poolarray.h
178///
179/// template <class TYPE>
180/// class my_PooledArray {
181/// // This class implements a container that stores values of (template
182/// // parameter) 'TYPE' out-of-place. It is assumed that 'TYPE' does not
183/// // require an allocator, and that calls to the destructor of 'TYPE' can
184/// // be elided.
185///
186/// // DATA
187/// bsl::vector<TYPE *> d_array_p; // array of pooled elements
188/// bdlma::Pool d_pool; // memory manager for array elements
189///
190/// private:
191/// // Not implemented:
192/// my_PooledArray(const my_PooledArray&);
193///
194/// public:
195/// // CREATORS
196/// explicit my_PooledArray(bslma::Allocator *basicAllocator = 0);
197/// // Create a pooled array that stores the 'TYPE' element values
198/// // "out-of-place". Optionally specify a 'basicAllocator' used to
199/// // supply memory. If 'basicAllocator' is 0, the currently
200/// // installed default allocator is used.
201///
202/// ~my_PooledArray();
203/// // Destroy this array and all elements held by it.
204///
205/// // MANIPULATORS
206/// void append(const TYPE& value);
207/// // Append the specified 'value' to this array.
208///
209/// void removeAll();
210/// // Remove all elements from this array.
211///
212/// // ACCESSORS
213/// bsl::size_t length() const;
214/// // Return the number of elements in this array.
215///
216/// const TYPE& operator[](int index) const;
217/// // Return a reference providing non-modifiable access to the value
218/// // at the specified 'index' in this array. The behavior is
219/// // undefined unless '0 <= index < length()'.
220/// };
221/// @endcode
222/// Next, we provide the implementation of the `my_PooledArray` methods that are
223/// defined `inline`.
224///
225/// Note that in the `removeAll` method, all elements are deallocated by simply
226/// invoking the pool's `release` method. This technique implies significant
227/// performance gain when the array contains many elements:
228/// @code
229/// // MANIPULATORS
230/// template <class TYPE>
231/// inline
232/// void my_PooledArray<TYPE>::removeAll()
233/// {
234/// d_array_p.clear();
235/// d_pool.release();
236/// }
237///
238/// // ACCESSORS
239/// template <class TYPE>
240/// inline
241/// bsl::size_t my_PooledArray<TYPE>::length() const
242/// {
243/// return d_array_p.size();
244/// }
245///
246/// template <class TYPE>
247/// inline
248/// const TYPE& my_PooledArray<TYPE>::operator[](int index) const
249/// {
250/// assert(0 <= index);
251/// assert(index < static_cast<int>(length()));
252///
253/// return *d_array_p[index];
254/// }
255/// @endcode
256/// Next, we provide the implementation of the `my_PooledArray` methods that are
257/// defined in the `.cpp` file.
258///
259/// Note that the growth strategy and maximum chunk size of the pool defaults to
260/// those provided by `bdlma::Pool`:
261/// @code
262/// // my_poolarray.cpp
263///
264/// // CREATORS
265/// template <class TYPE>
266/// my_PooledArray<TYPE>::my_PooledArray(bslma::Allocator *basicAllocator)
267/// : d_array_p(basicAllocator)
268/// , d_pool(sizeof(TYPE), basicAllocator)
269/// {
270/// }
271/// @endcode
272/// Since all memory is managed by `d_pool`, we do not have to explicitly invoke
273/// `deleteObject` to reclaim outstanding memory. The destructor of the pool
274/// will automatically deallocate all array elements:
275/// @code
276/// template <class TYPE>
277/// my_PooledArray<TYPE>::~my_PooledArray()
278/// {
279/// // Elements are automatically deallocated when 'd_pool' is destroyed.
280/// }
281/// @endcode
282/// Finally, note that the overloaded "placement" `new` is used to allocate new
283/// nodes in the `append` method:
284/// @code
285/// // MANIPULATORS
286/// template <class TYPE>
287/// void my_PooledArray<TYPE>::append(const TYPE& value)
288/// {
289/// TYPE *tmp = new (d_pool) TYPE(value);
290/// d_array_p.push_back(tmp);
291/// }
292/// @endcode
293/// @}
294/** @} */
295/** @} */
296
297/** @addtogroup bdl
298 * @{
299 */
300/** @addtogroup bdlma
301 * @{
302 */
303/** @addtogroup bdlma_pool
304 * @{
305 */
306
307#include <bdlscm_version.h>
308
310
311#include <bslma_allocator.h>
312#include <bslma_deleterhelper.h>
313
314#include <bsls_alignmentutil.h>
315#include <bsls_assert.h>
316#include <bsls_blockgrowth.h>
317#include <bsls_types.h>
318
319#include <bsl_cstddef.h>
320
321
322namespace bdlma {
323
324 // ==========
325 // class Pool
326 // ==========
327
328/// This class implements a memory pool that allocates and manages memory
329/// blocks of some uniform size specified at construction. This memory pool
330/// maintains an internal linked list of free memory blocks, and dispenses
331/// one block for each `allocate` method invocation. When a memory block is
332/// deallocated, it is returned to the free list for potential reuse.
333///
334/// See @ref bdlma_pool
335class Pool {
336
337 // PRIVATE TYPES
338
339 /// This `struct` implements a link data structure that stores the
340 /// address of the next link, and is used to implement the internal
341 /// linked list of free memory blocks. Note that this type is
342 /// replicated in `bdlma_pool.cpp` to provide access to a compatible
343 /// type from static methods defined in `bdlma_pool.cpp`.
344 struct Link {
345
346 Link *d_next_p; // pointer to next link
347 };
348
349 // DATA
350 bsls::Types::size_type d_blockSize; // size (in bytes) of each
351 // allocated memory block
352 // returned to client
353
354 bsls::Types::size_type d_internalBlockSize; // actual size of each block
355 // maintained on free list
356 // (contains overhead for
357 // 'Link')
358
359 int d_chunkSize; // current chunk size (in
360 // blocks-per-chunk)
361
362 int d_maxBlocksPerChunk; // maximum chunk size (in
363 // blocks-per-chunk)
364
366 d_growthStrategy; // growth strategy of the
367 // chunk size
368
369 Link *d_freeList_p; // linked list of free memory
370 // blocks
371
373 d_blockList; // memory manager for
374 // allocated memory
375
376 char *d_begin_p; // start of a contiguous
377 // group of memory blocks
378
379 char *d_end_p; // end of a contiguous group
380 // of memory blocks
381
382 private:
383 // PRIVATE MANIPULATORS
384
385 /// Dynamically allocate a new chunk using this pool's underlying growth
386 /// strategy.
387 void replenish();
388
389 private:
390 // NOT IMPLEMENTED
391 Pool(const Pool&);
392 Pool& operator=(const Pool&);
393
394 public:
395 // CREATORS
396
397 explicit
399 bslma::Allocator *basicAllocator = 0);
401 bsls::BlockGrowth::Strategy growthStrategy,
402 bslma::Allocator *basicAllocator = 0);
403 /// Create a memory pool that returns blocks of contiguous memory of the
404 /// specified `blockSize` (in bytes) for each `allocate` method
405 /// invocation. Optionally specify a `growthStrategy` used to control
406 /// the growth of internal memory chunks (from which memory blocks are
407 /// dispensed). If `growthStrategy` is not specified, geometric growth
408 /// is used. Optionally specify `maxBlocksPerChunk` as the maximum
409 /// chunk size if `growthStrategy` is specified. If geometric growth is
410 /// used, the chunk size grows starting at `blockSize`, doubling in size
411 /// until the size is exactly `blockSize * maxBlocksPerChunk`. If
412 /// constant growth is used, the chunk size is always
413 /// `blockSize * maxBlocksPerChunk`. If `maxBlocksPerChunk` is not
414 /// specified, an implementation-defined value is used. Optionally
415 /// specify a `basicAllocator` used to supply memory. If
416 /// `basicAllocator` is 0, the currently installed default allocator is
417 /// used. The behavior is undefined unless `1 <= blockSize` and
418 /// `1 <= maxBlocksPerChunk`.
420 bsls::BlockGrowth::Strategy growthStrategy,
421 int maxBlocksPerChunk,
422 bslma::Allocator *basicAllocator = 0);
423
424 /// Destroy this pool, releasing all associated memory back to the
425 /// underlying allocator.
427
428 // MANIPULATORS
429
430 /// Return the address of a contiguous block of maximally-aligned memory
431 /// having the fixed block size specified at construction.
432 void *allocate();
433
434 /// Relinquish the memory block at the specified `address` back to this
435 /// pool object for reuse. The behavior is undefined unless `address`
436 /// is non-zero, was allocated by this pool, and has not already been
437 /// deallocated.
438 void deallocate(void *address);
439
440 /// Destroy the specified `object` based on its dynamic type and then
441 /// use this pool to deallocate its memory footprint. This method has
442 /// no effect if `object` is 0. The behavior is undefined unless
443 /// `object`, when cast appropriately to `void *`, was allocated using
444 /// this pool and has not already been deallocated. Note that
445 /// `dynamic_cast<void *>(object)` is applied if `TYPE` is polymorphic,
446 /// and `static_cast<void *>(object)` is applied otherwise.
447 template <class TYPE>
448 void deleteObject(const TYPE *object);
449
450 /// Destroy the specified `object` and then use this pool to deallocate
451 /// its memory footprint. This method has no effect if `object` is 0.
452 /// The behavior is undefined unless `object` is **not** a secondary base
453 /// class pointer (i.e., the address is (numerically) the same as when
454 /// it was originally dispensed by this pool), was allocated using this
455 /// pool, and has not already been deallocated.
456 template <class TYPE>
457 void deleteObjectRaw(const TYPE *object);
458
459 /// Relinquish all memory currently allocated via this pool object.
460 void release();
461
462 /// Reserve memory from this pool to satisfy memory requests for at
463 /// least the specified `numBlocks` before the pool replenishes. The
464 /// behavior is undefined unless `0 <= numBlocks`.
465 void reserveCapacity(int numBlocks);
466
467 // ACCESSORS
468
469 /// Return the size (in bytes) of the memory blocks allocated from this
470 /// pool object. Note that all blocks dispensed by this pool have the
471 /// same size.
473
474 // Aspects
475
476 /// Return the allocator used by this object to allocate memory. Note
477 /// that this allocator can not be used to deallocate memory
478 /// allocated through this pool.
480};
481
482} // close package namespace
483
484
485// Note that the 'new' and 'delete' operators are declared outside the
486// 'BloombergLP' namespace so that they do not hide the standard placement
487// 'new' and 'delete' operators (i.e.,
488// 'void *operator new(bsl::size_t, void *)' and
489// 'void operator delete(void *)').
490//
491// Also note that only the scalar versions of operators 'new' and 'delete' are
492// provided, because overloading 'new' (and 'delete') with their array versions
493// would cause dangerous ambiguity. Consider what would have happened had we
494// overloaded the array version of 'operator new':
495//..
496// void *operator new[](bsl::size_t size, BloombergLP::bdlma::Pool& pool);
497//..
498// A user of 'bdlma::Pool' may expect to be able to use array 'operator new' as
499// follows:
500//..
501// new (*pool) my_Type[...];
502//..
503// The problem is that this expression returns an array that cannot be safely
504// deallocated. On the one hand, there is no syntax in C++ to invoke an
505// overloaded 'operator delete'; on the other hand, the pointer returned by
506// 'operator new' cannot be passed to the 'deallocate' method directly because
507// the pointer is different from the one returned by the 'allocate' method.
508// The compiler offsets the value of this pointer by a header, which is used to
509// maintain the number of objects in the array (so that 'operator delete' can
510// destroy the right number of objects).
511
512// FREE OPERATORS
513
514/// Return a block of memory of the specified `size` (in bytes) allocated
515/// from the specified `pool`. The behavior is undefined unless `size` is
516/// the same or smaller than the `blockSize` with which `pool` was
517/// constructed. Note that an object may allocate additional memory
518/// internally, requiring the allocator to be passed in as a constructor
519/// argument:
520/// @code
521/// my_Type *newMyType(bdlma::Pool *pool, bslma::Allocator *basicAllocator)
522/// {
523/// return new (*pool) my_Type(..., basicAllocator);
524/// }
525/// @endcode
526/// Also note that the analogous version of `operator delete` should not be
527/// called directly. Instead, this component provides a static template
528/// member function, `deleteObject`, parameterized by `TYPE`:
529/// @code
530/// void deleteMyType(my_Type *t, bdlma::Pool *pool)
531/// {
532/// pool->deleteObject(t);
533/// }
534/// @endcode
535/// `deleteObject` performs the following:
536/// @code
537/// t->~my_Type();
538/// pool->deallocate(t);
539/// @endcode
540void *operator new(bsl::size_t size, BloombergLP::bdlma::Pool& pool);
541
542/// Use the specified `pool` to deallocate the memory at the specified
543/// `address`. The behavior is undefined unless `address` is non-zero, was
544/// allocated using `pool`, and has not already been deallocated. Note that
545/// this operator is supplied solely to allow the compiler to arrange for it
546/// to be called in the case of an exception.
547void operator delete(void *address, BloombergLP::bdlma::Pool& pool);
548
549// ============================================================================
550// INLINE DEFINITIONS
551// ============================================================================
552
553
554namespace bdlma {
555
556 // ----------
557 // class Pool
558 // ----------
559
560// MANIPULATORS
561inline
563{
564 if (d_begin_p == d_end_p) {
565 if (d_freeList_p) {
566 Link *p = d_freeList_p;
567 d_freeList_p = p->d_next_p;
568 return p; // RETURN
569 }
570
571 replenish();
572 }
573
574 char *p = d_begin_p;
575 d_begin_p += d_internalBlockSize;
576 return p;
577}
578
579inline
580void Pool::deallocate(void *address)
581{
582 BSLS_ASSERT_SAFE(address);
583
584 static_cast<Link *>(address)->d_next_p = d_freeList_p;
585 d_freeList_p = static_cast<Link *>(address);
586}
587
588template <class TYPE>
589inline
590void Pool::deleteObject(const TYPE *object)
591{
593}
594
595template <class TYPE>
596inline
597void Pool::deleteObjectRaw(const TYPE *object)
598{
600}
601
602inline
604{
605 d_blockList.release();
606 d_freeList_p = 0;
607 d_begin_p = 0;
608 d_end_p = 0;
609}
610
611// ACCESSORS
612inline
614{
615 return d_blockSize;
616}
617
618// Aspects
619
620inline
622{
623 return d_blockList.allocator();
624}
625
626} // close package namespace
627
628
629// FREE OPERATORS
630inline
631void *operator new(bsl::size_t size, BloombergLP::bdlma::Pool& pool)
632{
633 using namespace BloombergLP;
634
635 BSLS_ASSERT_SAFE(size <= pool.blockSize() &&
638
639 static_cast<void>(size); // suppress "unused parameter" warnings
640 return pool.allocate();
641}
642
643inline
644void operator delete(void *address, BloombergLP::bdlma::Pool& pool)
645{
646 BSLS_ASSERT_SAFE(address);
647
648 pool.deallocate(address);
649}
650
651#endif
652
653// ----------------------------------------------------------------------------
654// Copyright 2016 Bloomberg Finance L.P.
655//
656// Licensed under the Apache License, Version 2.0 (the "License");
657// you may not use this file except in compliance with the License.
658// You may obtain a copy of the License at
659//
660// http://www.apache.org/licenses/LICENSE-2.0
661//
662// Unless required by applicable law or agreed to in writing, software
663// distributed under the License is distributed on an "AS IS" BASIS,
664// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
665// See the License for the specific language governing permissions and
666// limitations under the License.
667// ----------------------------- END-OF-FILE ----------------------------------
668
669/** @} */
670/** @} */
671/** @} */
Definition bdlma_infrequentdeleteblocklist.h:241
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlma_infrequentdeleteblocklist.h:335
Definition bdlma_pool.h:335
Pool(bsls::Types::size_type blockSize, bslma::Allocator *basicAllocator=0)
Pool(bsls::Types::size_type blockSize, bsls::BlockGrowth::Strategy growthStrategy, bslma::Allocator *basicAllocator=0)
void reserveCapacity(int numBlocks)
void deleteObjectRaw(const TYPE *object)
Definition bdlma_pool.h:597
void deallocate(void *address)
Definition bdlma_pool.h:580
void deleteObject(const TYPE *object)
Definition bdlma_pool.h:590
bslma::Allocator * allocator() const
Definition bdlma_pool.h:621
bsls::Types::size_type blockSize() const
Definition bdlma_pool.h:613
void * allocate()
Definition bdlma_pool.h:562
Pool(bsls::Types::size_type blockSize, bsls::BlockGrowth::Strategy growthStrategy, int maxBlocksPerChunk, bslma::Allocator *basicAllocator=0)
void release()
Relinquish all memory currently allocated via this pool object.
Definition bdlma_pool.h:603
Definition bslma_allocator.h:457
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlma_alignedallocator.h:276
static void deleteObject(const TYPE *object, ALLOCATOR *allocator)
Definition bslma_deleterhelper.h:196
static void deleteObjectRaw(const TYPE *object, ALLOCATOR *allocator)
Definition bslma_deleterhelper.h:217
static int calculateAlignmentFromSize(std::size_t size)
Definition bsls_alignmentutil.h:344
Strategy
Definition bsls_blockgrowth.h:169
std::size_t size_type
Definition bsls_types.h:124