BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslma.h
Go to the documentation of this file.
1/// @file bslma.h
2///
3///
4/// @defgroup bslma Package bslma
5/// @brief Basic Standard Library Memory Allocators (bslma)
6/// @addtogroup bsl
7/// @{
8/// @addtogroup bslma
9/// @{
10/// * <a href="#bslma-purpose"> Purpose</a>
11/// * <a href="#bslma-mnemonic"> Mnemonic </a>
12/// * <a href="#bslma-description"> Description </a>
13/// * <a href="#bslma-hierarchical-synopsis"> Hierarchical Synopsis </a>
14/// * <a href="#bslma-component-synopsis"> Component Synopsis </a>
15/// * <a href="#bslma-component-overview"> Component Overview </a>
16/// * <a href="#bslma-bslma_allocator"> bslma_allocator </a>
17/// * <a href="#bslma-bslma_autodeallocator"> bslma_autodeallocator </a>
18/// * <a href="#bslma-bslma_autodestructor"> bslma_autodestructor </a>
19/// * <a href="#bslma-bslma_autorawdeleter"> bslma_autorawdeleter </a>
20/// * <a href="#bslma-bslma_deallocatorguard"> bslma_deallocatorguard </a>
21/// * <a href="#bslma-bslma_deallocatorproctor"> bslma_deallocatorproctor </a>
22/// * <a href="#bslma-bslma_default"> bslma_default </a>
23/// * <a href="#bslma-bslma_defaultallocatorguard"> bslma_defaultallocatorguard </a>
24/// * <a href="#bslma-bslma_deleterhelper"> bslma_deleterhelper </a>
25/// * <a href="#bslma-bslma_destructorguard"> bslma_destructorguard </a>
26/// * <a href="#bslma-bslma_destructorproctor"> bslma_destructorproctor </a>
27/// * <a href="#bslma-bslma_isstdallocator"> bslma_isstdallocator </a>
28/// * <a href="#bslma-bslma_mallocfreeallocator"> bslma_mallocfreeallocator </a>
29/// * <a href="#bslma-bslma_newdeleteallocator"> bslma_newdeleteallocator </a>
30/// * <a href="#bslma-bslma_rawdeleterguard"> bslma_rawdeleterguard </a>
31/// * <a href="#bslma-bslma_rawdeleterproctor"> bslma_rawdeleterproctor </a>
32/// * <a href="#bslma-bslma_testallocator"> bslma_testallocator </a>
33/// * <a href="#bslma-bslma_testallocatorexception"> bslma_testallocatorexception </a>
34/// * <a href="#bslma-bslma_testallocatormonitor"> bslma_testallocatormonitor </a>
35/// * <a href="#bslma-why-use-allocators"> Why Use Allocators </a>
36/// * <a href="#bslma-rationale-for-the-bde-allocator-model"> Rationale for the BDE Allocator Model </a>
37/// * <a href="#bslma-allocators-and-other-memory-dispensing-mechanisms"> Allocators and Other Memory-Dispensing Mechanisms </a>
38/// * <a href="#bslma-allocator-and-managedallocator"> Allocator and ManagedAllocator </a>
39/// * <a href="#bslma-proctors-and-guards"> Proctors and Guards </a>
40/// * <a href="#bslma-alignment"> Alignment </a>
41/// * <a href="#bslma-deallocation"> Deallocation </a>
42/// * <a href="#bslma-type-and-origination"> Type and Origination </a>
43/// * <a href="#bslma-the-default-allocator"> The Default Allocator </a>
44/// * <a href="#bslma-interaction-with-other-packages"> Interaction With Other Packages </a>
45/// * <a href="#bslma-usage"> Usage </a>
46/// * <a href="#bslma-example-1-creating-a-type-that-uses-bslma-allocator"> Example 1: Creating a type that uses bslma::Allocator </a>
47/// * <a href="#bslma-example-2-implementing-templates-that-may-be-supplied-allocating-types"> Example 2: Implementing Templates That May Be Supplied Allocating Types </a>
48/// * <a href="#bslma-example-3-implementing-a-customized-allocator"> Example 3: Implementing a Customized Allocator </a>
49///
50/// # Purpose {#bslma-purpose}
51/// Provide allocators, guards, and other memory-management tools.
52///
53/// # Mnemonic {#bslma-mnemonic}
54/// Basic Standard Library Memory Allocators (bslma)
55///
56/// # Description {#bslma-description}
57/// The 'bslma' package provides an allocator protocol (i.e., a pure
58/// abstract interface) and a variety of concrete allocators derived from this
59/// protocol, as well as other memory-dispensing mechanisms and various guard
60/// constructs to prevent loss in case of exceptions. In addition, 'bslma' also
61/// provides a mechanism for installing a "default allocator" that will then be
62/// visible to all BDE and BDE-compliant code throughout that process. If this
63/// mechanism is not invoked explicitly, then an allocator that uses global 'new'
64/// and 'delete' is the BDE default allocator. This topic is discussed in more
65/// detail below.
66///
67/// ## Hierarchical Synopsis {#bslma-hierarchical-synopsis}
68///
69/// The 'bslma' package currently has 59 components having 16 levels of physical
70/// dependency. The list below shows the hierarchical ordering of the components.
71/// The order of components within each level is not architecturally significant,
72/// just alphabetical.
73/// @code
74/// 16. bslma_managedptr
75///
76/// 15. bslma_autodeallocator
77/// bslma_destructorproctor
78///
79/// 14. bslma_deallocatorproctor !DEPRECATED!
80///
81/// 13. bslma_aatypeutil
82/// bslma_deallocatebytesproctor
83/// bslma_deallocateobjectproctor
84/// bslma_deleteobjectproctor
85///
86/// 12. bslma_aamodel
87/// bslma_allocatorutil
88/// bslma_stdallocator !DEPRECATED!
89///
90/// 11. bslma_bslallocator
91///
92/// 10. bslma_polymorphicallocator
93///
94/// 9. bslma_allocatortraits
95/// bslma_managedptr_factorydeleter !PRIVATE!
96/// bslma_managedptr_members !PRIVATE!
97/// bslma_sequentialallocator !DEPRECATED!
98/// bslma_stdtestallocator
99///
100/// 8. bslma_constructionutil
101/// bslma_sequentialpool !DEPRECATED!
102/// bslma_sharedptrinplacerep
103/// bslma_sharedptroutofplacerep
104/// bslma_testallocatormonitor
105/// bslma_testallocatorstatisticsguard
106///
107/// 7. bslma_allocatoradaptor
108/// bslma_autodestructor
109/// bslma_deallocatorguard
110/// bslma_defaultallocatorguard
111/// bslma_destructionutil
112/// bslma_destructorguard
113/// bslma_exceptionguard
114/// bslma_infrequentdeleteblocklist !DEPRECATED!
115/// bslma_managedptr_pairproxy !PRIVATE!
116/// bslma_managedptrdeleter
117/// bslma_rawdeleterguard
118/// bslma_rawdeleterproctor
119/// bslma_sharedptrrep
120///
121/// 6. bslma_default
122/// bslma_testallocator
123///
124/// 5. bslma_autorawdeleter
125/// bslma_bufferallocator !DEPRECATED!
126/// bslma_mallocfreeallocator
127/// bslma_managedallocator !DEPRECATED!
128/// bslma_newdeleteallocator
129/// bslma_testallocatorexception
130/// bslma_usesbslmaallocator
131///
132/// 4. bslma_allocator
133///
134/// 3. bslma_hasallocatortype
135/// bslma_memoryresourceimpsupport
136///
137/// 2. bslma_allocatortraits_cpp03 !PRIVATE!
138/// bslma_deleterhelper
139/// bslma_isstdallocator
140/// bslma_memoryresource
141/// bslma_polymorphicallocator_cpp03 !PRIVATE!
142///
143/// 1. bslma_allocatorutil_cpp03 !PRIVATE!
144/// bslma_bslallocator_cpp03 !PRIVATE!
145/// bslma_constructionutil_cpp03 !PRIVATE!
146/// bslma_managedptr_cpp03 !PRIVATE!
147/// bslma_sharedptrinplacerep_cpp03 !PRIVATE!
148/// @endcode
149///
150/// ## Component Synopsis {#bslma-component-synopsis}
151///
152/// @ref bslma_aamodel :
153/// Provide metafunctions to detect a type's allocator-awareness model.
154///
155/// @ref bslma_aatypeutil :
156/// Provide a namespace for utility functions on allocator-aware types.
157///
158/// @ref bslma_allocator :
159/// Provide a pure abstract interface for memory-allocation mechanisms.
160///
161/// @ref bslma_allocatoradaptor :
162/// Provide a polymorphic adaptor for STL-style allocators
163///
164/// @ref bslma_allocatortraits :
165/// Provide a uniform interface to standard allocator types.
166///
167/// @ref bslma_allocatortraits_cpp03 : !PRIVATE!
168/// Provide C++03 implementation for bslma_allocatortraits.h
169///
170/// @ref bslma_allocatorutil :
171/// Provide a namespace for utility functions on allocators.
172///
173/// @ref bslma_allocatorutil_cpp03 : !PRIVATE!
174/// Provide C++03 implementation for bslma_allocatorutil.h
175///
176/// @ref bslma_autodeallocator :
177/// Provide a range proctor to managed a block of memory.
178///
179/// @ref bslma_autodestructor :
180/// Provide a range proctor to manage an array of objects.
181///
182/// @ref bslma_autorawdeleter :
183/// Provide a range proctor to manage a sequence objects.
184///
185/// @ref bslma_bslallocator :
186/// Provide an STL-compatible proxy for `bslma::Allocator` objects.
187///
188/// @ref bslma_bslallocator_cpp03 : !PRIVATE!
189/// Provide C++03 implementation for bslma_bslallocator.h
190///
191/// @ref bslma_bufferallocator : !DEPRECATED!
192/// Support efficient memory allocations from a user-supplied buffer.
193///
194/// @ref bslma_constructionutil :
195/// Provide methods to construct arbitrarily-typed objects uniformly.
196///
197/// @ref bslma_constructionutil_cpp03 : !PRIVATE!
198/// Provide C++03 implementation for bslma_constructionutil.h
199///
200/// @ref bslma_deallocatebytesproctor :
201/// Provide a proctor to conditionally unwind memory block allocation.
202///
203/// @ref bslma_deallocateobjectproctor :
204/// Provide a proctor to conditionally unwind object allocation.
205///
206/// @ref bslma_deallocatorguard :
207/// Provide a guard to unconditionally manage a block of memory.
208///
209/// @ref bslma_deallocatorproctor : !DEPRECATED!
210/// Provide a proctor to conditionally manage a block memory.
211///
212/// @ref bslma_default :
213/// Provide utilities to set/fetch the default and global allocators.
214///
215/// @ref bslma_defaultallocatorguard :
216/// Provide scoped guard to temporarily change the default allocator.
217///
218/// @ref bslma_deleteobjectproctor :
219/// Provide a proctor to conditionally unwind new object creation.
220///
221/// @ref bslma_deleterhelper :
222/// Provide namespace for functions used to delete objects.
223///
224/// @ref bslma_destructionutil :
225/// Provide routines that destroy objects efficiently.
226///
227/// @ref bslma_destructorguard :
228/// Provide a guard to unconditionally manage an object.
229///
230/// @ref bslma_destructorproctor :
231/// Provide a proctor to conditionally manage an object.
232///
233/// @ref bslma_exceptionguard :
234/// Provide a check that objects throwing exceptions do not change.
235///
236/// @ref bslma_hasallocatortype :
237/// Provide a compile-time check for an `allocator_type` typedef
238///
239/// @ref bslma_infrequentdeleteblocklist : !DEPRECATED!
240/// Provide allocation and management of a sequence of memory blocks.
241///
242/// @ref bslma_isstdallocator :
243/// Provide a compile-time check for determining allocator types.
244///
245/// @ref bslma_mallocfreeallocator :
246/// Provide malloc/free adaptor to `bslma::Allocator` protocol.
247///
248/// @ref bslma_managedallocator : !DEPRECATED!
249/// Provide a protocol for memory allocators that support `release`.
250///
251/// @ref bslma_managedptr :
252/// Provide a managed pointer class.
253///
254/// @ref bslma_managedptr_cpp03 : !PRIVATE!
255/// Provide C++03 implementation for bslma_managedptr.h
256///
257/// @ref bslma_managedptr_factorydeleter : !PRIVATE!
258/// Provide a factory-based deleter for the managed pointer class.
259///
260/// @ref bslma_managedptr_members : !PRIVATE!
261/// Provide the internal state of a managed pointer class.
262///
263/// @ref bslma_managedptr_pairproxy : !PRIVATE!
264/// Provide the internal state of a managed pointer class.
265///
266/// @ref bslma_managedptrdeleter :
267/// Provide an in-core value-semantic class to call a delete function.
268///
269/// @ref bslma_memoryresource :
270/// Provide a pure abstract interface for memory-allocation mechanisms.
271///
272/// @ref bslma_memoryresourceimpsupport :
273/// Provide support for implementing memory resources
274///
275/// @ref bslma_newdeleteallocator :
276/// Provide singleton new/delete adaptor to `bslma::Allocator` protocol.
277///
278/// @ref bslma_polymorphicallocator :
279/// Provide an allocator interface for `bsl::memory_resource` objects.
280///
281/// @ref bslma_polymorphicallocator_cpp03 : !PRIVATE!
282/// Provide C++03 implementation for bslma_polymorphicallocator.h
283///
284/// @ref bslma_rawdeleterguard :
285/// Provide a guard to unconditionally manage an object.
286///
287/// @ref bslma_rawdeleterproctor :
288/// Provide a proctor to conditionally manage an object.
289///
290/// @ref bslma_sequentialallocator : !DEPRECATED!
291/// Support fast memory allocation for objects of varying sizes.
292///
293/// @ref bslma_sequentialpool : !DEPRECATED!
294/// Provide fast variable-size memory pool with allocation methods.
295///
296/// @ref bslma_sharedptrinplacerep :
297/// Provide an in-place implementation of `bslma::SharedPtrRep`.
298///
299/// @ref bslma_sharedptrinplacerep_cpp03 : !PRIVATE!
300/// Provide C++03 implementation for bslma_sharedptrinplacerep.h
301///
302/// @ref bslma_sharedptroutofplacerep :
303/// Provide an out-of-place implementation of `bslma::SharedPtrRep`.
304///
305/// @ref bslma_sharedptrrep :
306/// Provide an abstract class for a shared object manager.
307///
308/// @ref bslma_stdallocator : !DEPRECATED!
309/// Provide an STL-compatible proxy for `bslma::Allocator` objects.
310///
311/// @ref bslma_stdtestallocator :
312/// Provide stl-compatible, `bslma`-style allocator to track usage.
313///
314/// @ref bslma_testallocator :
315/// Provide instrumented malloc/free allocator to track memory usage.
316///
317/// @ref bslma_testallocatorexception :
318/// Provide an exception class for memory allocation operations.
319///
320/// @ref bslma_testallocatormonitor :
321/// Provide a mechanism to summarize `bslma::TestAllocator` object use.
322///
323/// @ref bslma_testallocatorstatisticsguard :
324/// Provide mechanism for `bslma::TestAllocator` scoped statistics.
325///
326/// @ref bslma_usesbslmaallocator :
327/// Provide a metafunction to indicate the use of `bslma` allocators.
328/// ## Component Overview {#bslma-component-overview}
329///
330/// This section provides a brief introduction to some of the components of the
331/// 'bslma' package. See the documentation in each component for full details.
332///
333/// ### bslma_allocator {#bslma-bslma_allocator}
334///
335/// The @ref bslma_allocator component defines a protocol (i.e., an abstract base
336/// class) requiring the following interface: `allocate` for memory allocation,
337/// and `deallocate`, for allocation and deallocation of individual memory blocks.
338///
339/// ### bslma_autodeallocator {#bslma-bslma_autodeallocator}
340///
341/// The @ref bslma_autodeallocator component provides a range proctor class to
342/// manage a sequence of blocks of (otherwise-unmanaged) memory of a parameterized
343/// `TYPE` supplied at construction. If not explicitly released, the sequence of
344/// managed memory blocks are deallocated automatically when the range proctor
345/// goes out of scope by freeing the memory using the parameterized `ALLOCATOR`
346/// (allocator or pool) supplied at construction. This proctor mechanism is
347/// useful in guarding against memory leaks, e.g., when additional allocations may
348/// throw an exception.
349///
350/// ### bslma_autodestructor {#bslma-bslma_autodestructor}
351///
352/// The @ref bslma_autodestructor component provides a range proctor class to
353/// manage a sequence of blocks of (otherwise-unmanaged) memory of a parameterized
354/// `TYPE` supplied at construction. If not explicitly released, the sequence of
355/// managed memory blocks are destroyed automatically when the range proctor goes
356/// out of scope by calling each (managed) object`s destructor. This proctor
357/// mechanism is useful in guarding against memory leaks, e.g., when additional
358/// allocations may throw an exception.
359///
360/// ### bslma_autorawdeleter {#bslma-bslma_autorawdeleter}
361///
362/// The @ref bslma_autorawdeleter component provides a range proctor class template
363/// to manage a sequence of (otherwise-unmanaged) objects of parameterized `TYPE`
364/// supplied at construction. If not explicitly released, the sequence of managed
365/// objects are deleted automatically when the range proctor goes out of scope by
366/// iterating over each object, first calling the (managed) object`s destructor,
367/// and then freeing its memory footprint by invoking the `deallocate` method of
368/// an allocator (or pool) of parameterized `ALLOCATOR` type also supplied at
369/// construction. This proctor mechanism is useful in guarding against memory
370/// leaks, e.g., when additional allocations may throw an exception.
371///
372/// ### bslma_deallocatorguard {#bslma-bslma_deallocatorguard}
373///
374/// The @ref bslma_deallocatorguard component provides a guard class template to
375/// *unconditionally* manage a block of (otherwise-unmanaged) memory. The managed
376/// memory is deallocated automatically when the guard object goes out of scope
377/// using the `deallocate` method of the parameterized `ALLOCATOR` (allocator or
378/// pool) supplied at construction. This guard mechanism is useful in ensuring
379/// that a dynamically allocated raw memory resource is safely deallocated in the
380/// presense of multiple return satements or exceptions.
381///
382/// ### bslma_deallocatorproctor {#bslma-bslma_deallocatorproctor}
383///
384/// The @ref bslma_deallocatorproctor component provides a proctor class template
385/// to *conditionally* manage a block of (otherwise-unmanaged) memory. If not
386/// explicitly released, the managed memory is deallocated automatically when the
387/// proctor object goes out of scope by freeing the memory using the parameterized
388/// `ALLOCATOR` (allocator or pool) supplied at construction. This proctor
389/// mechanism is useful in guarding against memory leaks, e.g., when additional
390/// allocations may throw an exception.
391///
392/// ### bslma_default {#bslma-bslma_default}
393///
394/// The @ref bslma_default component provides a namespace for a set of utility
395/// functions that manage the addresses of two static (global) memory allocator
396/// instances: the *default* allocator and the *global* allocator. The default
397/// allocator is the allocator used by default by all BDE components. The global
398/// allocator is the allocator used by default to construct global singleton
399/// objects. Each of these allocators are of type derived from
400/// `bslma::Allocator`.
401///
402/// ### bslma_defaultallocatorguard {#bslma-bslma_defaultallocatorguard}
403///
404/// The @ref bslma_defaultallocatorguard component provides a mechanism that serves
405/// as a "scoped guard" to enable the temporary replacement of the process-wide
406/// default allocator. This functionality is intended for *testing* only, and in
407/// no event should this component be used except at the very beginning of `main`.
408///
409/// ### bslma_deleterhelper {#bslma-bslma_deleterhelper}
410///
411/// The @ref bslma_deleterhelper component provides non-primitive procedures used
412/// to delete objects of parameterized `TYPE` by first calling the destructor of
413/// the object, and then freeing the memory footprint of the object using a
414/// parameterized `ALLOCATOR` (allocator or pool) provided as a second argument.
415///
416/// ### bslma_destructorguard {#bslma-bslma_destructorguard}
417///
418/// The @ref bslma_destructorguard component provides a guard class template to
419/// *unconditionally* manage an (otherwise-unmanaged) object of parameterized
420/// `TYPE` supplied at construction. The managed object is destroyed
421/// automatically when the guard object goes out of scope by calling the (managed)
422/// object`s destructor. This guard mechanism is useful in ensuring that a
423/// dynamically allocated raw memory resource is safely deallocated in the
424/// presense of multiple return satements or exceptions.
425///
426/// ### bslma_destructorproctor {#bslma-bslma_destructorproctor}
427///
428/// The @ref bslma_destructorproctor component provides a proctor class template to
429/// *conditionally* manage an (otherwise-unmanaged) object of parameterized `TYPE`
430/// supplied at construction. If not explicitly released, the managed object is
431/// destroyed automatically when the proctor object goes out of scope by calling
432/// the object`s destructor. This proctor mechanism is useful in guarding against
433/// memory leaks, e.g., when additional allocations may throw an exception.
434///
435/// ### bslma_isstdallocator {#bslma-bslma_isstdallocator}
436///
437///The @ref bslma_isstdallocator component provides a meta-function,
438///`bsl::IsStdAllocator`, that determines if a type meets the requirements for an
439///allocator, as specified in [container.requirements.general].
440///
441/// ### bslma_mallocfreeallocator {#bslma-bslma_mallocfreeallocator}
442///
443/// The @ref bslma_mallocfreeallocator component provides a wrapper around
444/// `std::malloc` and `std::free` that adheres to the `bslma::Allocator` protocol
445/// (i.e., provides `allocate` and `deallocate` functions).
446///
447/// ### bslma_newdeleteallocator {#bslma-bslma_newdeleteallocator}
448///
449/// The @ref bslma_newdeleteallocator component provides a wrapper around
450/// `operator new` and `operator delete` that adheres to the `bslma::Allocator`
451/// protocol (i.e., provides an `allocate` function and a `deallocate` function).
452///
453/// ### bslma_rawdeleterguard {#bslma-bslma_rawdeleterguard}
454///
455/// The @ref bslma_rawdeleterguard component provides a guard class template to
456/// *unconditionally* manage an (otherwise-unmanaged) object of parameterized
457/// `TYPE` supplied at construction. The managed object is deleted automatically
458/// when the guard object goes out of scope by first calling the (managed)
459/// object`s destructor, and then freeing the memory using the parameterized
460/// `ALLOCATOR` (allocator or pool) also supplied at construction. This guard
461/// mechanism is useful in ensuring that a dynamically allocated raw memory
462/// resource is safely deallocated in the presense of multiple return satements or
463/// exceptions.
464///
465/// ### bslma_rawdeleterproctor {#bslma-bslma_rawdeleterproctor}
466///
467/// The @ref bslma_rawdeleterproctor component provides a proctor class template to
468/// conditionally manage an (otherwise-unmanaged) object of parameterized `TYPE`
469/// supplied at construction. If not explicitly released, the managed object is
470/// deleted automatically when the proctor object goes out of scope by first
471/// calling the (managed) object`s destructor, and then freeing the memory using
472/// the parameterized `ALLOCATOR` (allocator or pool) also supplied at
473/// construction. This proctor mechanism is useful in guarding against memory
474/// leaks, e.g., when additional allocations may throw an exception.
475///
476/// ### bslma_testallocator {#bslma-bslma_testallocator}
477///
478/// The @ref bslma_testallocator component provides an instrumented allocator that
479/// implements the `bslma::Allocator` protocol and can be used to track various
480/// aspects of memory allocated from it. This allocator memory allocator uses
481/// global functions `std::malloc` and `std::free` for allocations and
482/// deallocations.
483///
484/// ### bslma_testallocatorexception {#bslma-bslma_testallocatorexception}
485///
486/// The @ref bslma_testallocatorexception component defines an exception object for
487/// use in testing exceptions during memory allocations.
488///
489/// ### bslma_testallocatormonitor {#bslma-bslma_testallocatormonitor}
490///
491/// The @ref bslma_testallocatormonitor component provides a "monitor", a mechanism
492/// class, that allows concise tests of state change (or lack of change) in the
493/// test allocator provided at the monitor's construction.
494///
495/// ## Why Use Allocators {#bslma-why-use-allocators}
496///
497/// Allocators were originally introduced into STL to provide containers an
498/// abstraction for the different pointer types on the Intel architecture (such as
499/// near and far pointers). After the C++ standard (section 20.1.5 of the 1998
500/// standard) specified the requirements on an allocator type (`std::allocator`)
501/// that use was rendered obsolete. But the standard also specified that all
502/// standard containers be parameterized on an allocator type that provides users
503/// greater control over the memory usage of individual objects and allows an
504/// application to control from where that memory comes (e.g., stack, heap, shared
505/// memory) and how it is distributed. By using allocators, an application can
506/// ensure efficient memory usage by reducing the number of distinct calls to
507/// global operators `new` and `delete` (and functions `std::malloc` and
508/// `std::free`).
509///
510/// ## Rationale for the BDE Allocator Model {#bslma-rationale-for-the-bde-allocator-model}
511///
512/// Although C++ standard allocators (`std::allocator`) provide users great
513/// control on how containers can allocate memory having a templated allocator
514/// argument introduces other problems. Two containers instantiated with
515/// different allocator types refer to different types making interoperability
516/// between them difficult and limiting the allocator type to a per-class (as
517/// opposed to a per-instance) basis. The standard's requirement of a templated
518/// allocator type is limited to containers and does not address other
519/// user-defined types that allocate memory. Although users can augment their
520/// types to take a templated allocator type such use is likely to be tedious and
521/// to result in significant object code increase. Finally, the standard is
522/// unclear with regards to the copy semantics of stateful allocators.
523///
524/// The BDE allocator model provides a solution to these issues. BDE provides an
525/// allocator protocol and concrete allocator implementations that can be passed
526/// as constructor arguments (not as template parameters) to all objects that
527/// allocate memory. The type of an object is unaffected by the passed-in
528/// allocator and the user has full control over the scope of an allocator
529/// instance. As the model specifies a protocol it is easier to create concrete
530/// implementations and use them. The allocator model requires all elements (data
531/// members) of a container (object) to use the same allocator as the container
532/// (object). Also the allocator is not transferred on copy construction.
533///
534/// ## Allocators and Other Memory-Dispensing Mechanisms {#bslma-allocators-and-other-memory-dispensing-mechanisms}
535///
536/// An allocator is a memory manager that derives from the `bslma::Allocator`
537/// protocol and provides an `allocate` method for obtaining memory, and a
538/// `deallocate` method for returning memory (to the allocator). `bslma` also
539/// provides many memory-dispensing mechanisms that also provide an `allocate` and
540/// a `deallocate` method, but these memory managers are not properly referred to
541/// as "allocators", since we reserve the term "allocator" for concrete memory
542/// dispensers that actually derive from `bslma::Allocator` and are therefore
543/// usable anywhere that a `bslma::Allocator *` is specified. Objects that
544/// dispense memory but that are not actually "allocators" are sometimes called
545/// "end-point allocators", and may offer performance advantages to certain users.
546/// Choosing an allocation mechanisms is complex, and many factors will influence
547/// the decision. The discussions here are aimed at shedding light on this
548/// important selection process.
549///
550/// Characteristics differentiating among `bslma` memory-allocation objects *in*
551/// *general* are:
552///
553/// * Whether or not the object isA `bslma::Allocator`.
554///
555/// * Whether or not the allocator supports memory reuse.
556///
557/// * Whether allocation requests consume the exact amount of memory requested,
558/// an additive number of additional bytes, or a non-additive number of
559/// additional bytes (e.g., the smallest power of two that can satisfy the
560/// request).
561///
562/// * Whether allocation requests consume the exact amount of memory requested,
563///
564/// * Whether or not the allocator supports multi-threading.
565///
566/// All `bslma` allocators are fully thread-safe but not thread-enabled (see the
567/// @ref bsldoc_glossary for terminology).
568///
569/// The BDE allocators have two more differentiating properties. First, whether
570/// the allocator is intended to be part of a chain (or other grouping) of
571/// allocators, or is an "end-point" allocator. The former kind support the
572/// `bslma::Allocator` protocol. "End-point" allocators, such as a memory pool,
573/// are general-purpose mechanisms designed to minimize the runtime overhead of
574/// allocation and deallocation on a call-by-call basis and therefore do not
575/// derive from `bslma::Allocator`. The `bslma` package does not provide any
576/// end-point allocators although such implementations may be provided in
577/// higher-level libraries.
578///
579/// Supporting a common protocol (the `bslma::Allocator` protocol) allows passing
580/// conformant allocators to BDE (and other) objects requiring an allocator at
581/// construction. Support of this common protocol also facilitates grouping the
582/// memory used by an object into one allocator.
583///
584/// The BDE libraries use allocators with all classes requiring dynamic memory
585/// allocation, allowing clients to fine-tune memory-related performance
586/// characteristics by replacing the established defaults with client-chosen
587/// alternatives. Because the protocol is public, clients can even write their
588/// own, customized implementations, and use those. But none of these actions are
589/// required. BDE components all work with a (preset) default allocator, and
590/// clients without special requirements need never concern themselves with
591/// allocators.
592///
593/// ## Allocator and ManagedAllocator {#bslma-allocator-and-managedallocator}
594///
595/// A differentiating property among `bslma` allocators is whether the allocator
596/// is a "managed" or "unmanaged" allocator. Unmanaged allocators, concrete
597/// implementations of `bslma::Allocator`, require every allocation to be matched
598/// by a deallocation, similar to `malloc` and `free`, or `new` and `delete`.
599/// Managed allocators, concrete implementations of `bslma::ManagedAllocator`, in
600/// addition to implementing the `bslma::Allocator` protocol, provide simultaneous
601/// deallocation of all memory with one call to `release`. This `release`
602/// optimization can provide significant performance improvements if the only
603/// system resource held by an object (and all the objects it manages) is memory.
604/// The `bslma` package does not provide any concrete managed allocator
605/// implementations although such implementations may be provided in higher-level
606/// libraries.
607///
608/// ## Proctors and Guards {#bslma-proctors-and-guards}
609///
610/// The `bslma` package contains many components for managing
611/// dynamically-allocated objects. These components can be divided along two
612/// dimensions:
613///
614/// * What their objects do on destruction: The objects of these managers can
615/// either deallocate, destroy, or delete (destroy and then deallocate) the
616/// memory or object under management.
617///
618/// * Proctors or Guards: The object managers in this package can be divided
619/// into guards and proctors. See @ref bsldoc_glossary for definitions of
620/// "proctor" and "guard". Proctors provide a mechanism to release the
621/// managed object, whereas, at least within `bslma`, guards do not provide a
622/// release mechanism (and so are slightly more efficient on destruction if a
623/// release mechanism isn't needed).
624///
625/// The following table categorizes the various components along these dimensions:
626///
627/// @code
628/// Deallocation Destruction Deletion
629/// +--------------------+-------------------+-------------------+
630/// Proctor | DeallocatorProctor | DestructorProctor | RawDeleterProctor |
631/// +--------------------+-------------------+-------------------+
632/// Guard | DeallocatorGuard | DestructorGuard | RawDeleterGuard |
633/// +--------------------+-------------------+-------------------+
634/// @endcode
635///
636/// Note that the components named "raw" (@ref bslma_rawdeleterproctor and
637/// @ref bslma_rawdeleterguard ) should be used only if we are sure that the supplied
638/// pointer is !not! of a type that is a secondary base class -- i.e., the
639/// (managed) object's address is (numerically) the same as when it was originally
640/// dispensed by `ALLOCATOR`.
641///
642/// All of the object managers specified above manage an individual object or a
643/// block of memory but three components, @ref bslma_autodeallocator ,
644/// @ref bslma_autodestructor and @ref bslma_autorawdeleter allow users to manage a
645/// sequence of objects or memory blocks.
646///
647/// ## Alignment {#bslma-alignment}
648///
649/// Alignment of an *address* in memory refers to the relative position of that
650/// address with respect to specific (hardware-imposed) boundaries within the
651/// memory space. Any one address can be said to be on a one-byte boundary, a
652/// two-byte boundary, a four-byte boundary, or an eight-byte boundary. (Clearly,
653/// this sequence can be extended, but, as of this writing, boundaries beyond
654/// eight-byte boundaries are not relevant for these discussions on any hardware
655/// platform of interest. In particular, "alignment" as we are using the term
656/// here does not deal with page boundaries or other larger memory structures,
657/// although these considerations are important elsewhere.)
658///
659/// In general, we also speak about the alignment of (the *first* *byte* of) an
660/// entity (e.g., an `int`, a `double`, or a pointer) whose size is not
661/// necessarily one byte. As a practical matter, for each entity separately, some
662/// alignments are "safe" and some are not. By "not safe" we mean that, for most
663/// platforms (e.g., all of our Unix machines), attempting to access an entity at
664/// an address that is not safely aligned for that entity will cause a bus error,
665/// crashing the program on the spot. In the very best case, the access will
666/// incur a performance penalty as the memory is shifted appropriately between its
667/// initial address and its target address (e.g., a register).
668///
669/// The BDE memory managers provide three kinds of alignment: NATURAL, MAXIMAL,
670/// and BYTE -- but note that BYTE alignment is also referred to as "no alignment"
671/// or "none" in this document, since every address is aligned to *some* byte.
672///
673/// A C/C++ variable is "naturally aligned" if its size divides the numerical
674/// value of its address. An address is "maximally aligned" if it can serve as a
675/// naturally-aligned address no matter what type of object might be stored there.
676/// That is, it meets the alignment requirements of the type with the maximally
677/// restrictive needs.
678///
679/// Accessing data stored at an aligned address is *faster* on Intel platforms and
680/// *required* on almost all Unix platforms. Reading (or writing) a C/C++
681/// variable at an unaligned address will cause a Bus Error on these Unix
682/// platforms, and thus crash the program.
683///
684/// Normally, programmers need not worry about alignment for dynamically allocated
685/// memory. The runtime system's `new` (or `malloc`, for C) automatically return
686/// memory blocks beginning at maximally-aligned addresses (the C++ standard
687/// requires it of `new`). All memory managers in the `bslma` package return
688/// maximally-aligned memory.
689///
690/// The cost of obtaining aligned addresses is twofold: an increase in the memory
691/// used (allocators returning aligned addresses do so by skipping bytes that
692/// could otherwise be used, so as to return an appropriate address), and
693/// additional computation time to calculate the needed alignment and subsequent
694/// offset.
695///
696/// See the []{bsls_alignment#Alignment Strategy} component for further
697/// information on the supported alignment strategies.
698///
699/// ## Deallocation {#bslma-deallocation}
700///
701/// Some managers may not deallocate individual items. (The `deallocate` function
702/// is almost always provided, but in these managers it performs no action.) Such
703/// managers provide a `release` function instead, which relinquishes *all* memory
704/// allocated by that manager since the previous `release` call. All memory
705/// managers in the `bslma` package deallocate the specified memory during a
706/// `deallocate` method invocation.
707///
708/// ## Type and Origination {#bslma-type-and-origination}
709///
710/// Most managers provide variable-sized, untyped (i.e., `void *`) memory.
711///
712/// Different components manage memory in different ways, but they necessarily
713/// *obtain* the memory that they manage from one of the two usual sources: the
714/// heap or the stack. The `bslma::NewDeleteAllocator` is hard-coded to obtain
715/// memory from the heap -- its underlying source is `operator new`.
716///
717/// The managers in the `bslma` package are compared in the following tables:
718/// ```
719/// PERFORMANCE CHARACTERISTICS
720///
721/// Memory Source Allocation Alignment Out-of-memory
722/// Cost OVER Handling
723/// Underlying
724/// Source
725/// +-----------------+--------------+---------+--------------------+
726/// NewDelete | `operator new` | 0 if inlined,|MAXIMAL | Return value 0 |
727/// Allocator | |else vfn call+| | |
728/// +-----------------+--------------+---------+--------------------+
729/// MallocFree | `std::malloc` | 0 if inlined,|MAXIMAL | Return value 0 |
730/// Allocator | |else vfn call+| | |
731/// +-----------------+--------------+---------+--------------------+
732/// Test | `malloc` | N/A | None | Return value 0 |
733/// Allocator | | | | |
734/// +-----------------+--------------+---------+--------------------+
735///
736/// SEMANTICS
737///
738/// Deallocation Storage Facility
739/// +-----------------------+-------------------------+
740/// Newdelete | Single items only | Untyped, varying sizes |
741/// Allocator | | |
742/// +-----------------------+-------------------------+
743/// MallocFree | Single items only | Untyped, varying sizes |
744/// Allocator | | |
745/// +-----------------------+-------------------------+
746/// Test | Single items only | Untyped, varying sizes |
747/// Allocator | | |
748/// +-----------------------+-------------------------+
749/// ```
750///
751/// ## The Default Allocator {#bslma-the-default-allocator}
752///
753/// All object types in BDE libraries needing dynamic memory require that an
754/// allocator be passed to their constructor. They take a `bslma::Allocator *`
755/// argument, which defaults to the value of `bslma::Default::defaultAllocator()`.
756/// This value is set by BDE library code to be
757/// `bslma::NewDeleteAllocator::singleton()`, but it can be changed:
758/// `bslma::Default::setDefaultAllocator` sets the value of the (global) default
759/// allocator (although this is *strongly* discouraged), and
760/// `bslma::Default::allocator` returns it.
761///
762/// ## Interaction With Other Packages {#bslma-interaction-with-other-packages}
763///
764/// All BDE library objects needing dynamic memory require that an allocator be
765/// passed to their constructor, which defaults to the allocator currently
766/// installed as the default allocator.
767///
768/// ## Usage {#bslma-usage}
769///
770/// This section illustrates intended use of components in this package.
771///
772/// ### Example 1: Creating a type that uses bslma::Allocator {#bslma-example-1-creating-a-type-that-uses-bslma-allocator}
773///
774/// If objects of a class allocate memory (or contain data members that do) then
775/// having all constructors of that class accept the address of a
776/// `bslma::Allocator` object as an argument allows its clients to control how
777/// those objects allocate memory. An example of this is provided by showing the
778/// creators of a `Customer` `class` that stores the first and last names of a
779/// customer as `bsl::string` objects and the various account numbers of that
780/// customer using a `bsl::vector`. For simplicity part of the interface is
781/// elided.
782/// ```
783/// // ==============
784/// // class Customer
785/// // ==============
786///
787/// /// This simply constrained (value-semantic) attribute class represents
788/// /// the information about a bank's customer. A customer's first and last
789/// /// name are represented as `bsl::string` objects, the associated accounts
790/// /// are stored in a `bsl::vector<int>`, and the employee identification
791/// /// number is represented by an `int`. Note that the class invariants are
792/// /// identically the constraints on the individual attributes.
793/// ///
794/// /// This class:
795/// /// * supports a complete set of *value-semantic* operations
796/// /// - except for `bslx` serialization
797/// /// * is *exception-neutral* (agnostic)
798/// /// * is *alias-safe*
799/// /// * is `const` *thread-safe*
800/// class Customer {
801///
802/// // DATA
803/// bsl::string d_firstName; // first name
804/// bsl::string d_lastName; // last name
805/// bsl::vector<int> d_accounts; // account numbers
806/// int d_id; // customer identification number
807///
808/// public:
809/// ```
810/// Note that the constructor declarations below all accept the address of a
811/// 'bslma::Allocator' argument.
812/// ```
813/// // CREATORS
814///
815/// /// Create a `Customer` object having the (default) attribute values:
816/// /// ...
817/// /// firstName() == ""
818/// /// lastName() == ""
819/// /// accounts() == 0
820/// /// id() == 0
821/// /// ...
822/// /// Optionally specify a `basicAllocator` used to supply memory. If
823/// /// `basicAllocator` is 0, the currently installed default allocator
824/// /// is used.
825/// Customer(bslma::Allocator *basicAllocator = 0);
826///
827/// /// Create a `Customer` object having the specified `firstName`,
828/// /// `lastName`, `accounts`, and `id` attribute values. Optionally
829/// /// specify a `basicAllocator` used to supply memory. If
830/// /// `basicAllocator` is 0, the currently installed default allocator
831/// /// is used.
832/// Customer(const bslstl::StringRef& firstName,
833/// const bslstl::StringRef& lastName,
834/// const bsl::vector<int>& accounts,
835/// int id,
836/// bslma::Allocator *basicAllocator = 0);
837///
838/// /// Create a `Customer` object having the same value as the specified
839/// /// `original` object. Optionally specify a `basicAllocator` used to
840/// /// supply memory. If `basicAllocator` is 0, the currently installed
841/// /// default allocator is used.
842/// Customer(const Customer& original, bslma::Allocator *basicAllocator = 0);
843///
844/// /// Destroy this object.
845/// //! ~Customer() = default;
846///
847/// // Aspects
848///
849/// /// Return the allocator used by this object to supply memory. Note
850/// /// that if no allocator was supplied at construction the currently
851/// /// installed default allocator is used.
852/// bslma::Allocator *allocator() const;
853///
854/// ...
855/// };
856/// ```
857/// Since the `Customer` `class` contains members that allocate memory it can
858/// associate the `UsesBslmaAllocator` trait defined in the `bslma` package to
859/// programmatically inform templated code that it uses an allocator.
860/// ```
861///
862/// // TRAITS
863/// namespace BloombergLP{
864/// namespace bslma {
865///
866/// template <> struct UsesBslmaAllocator<Customer> : bsl::true_type {};
867///
868/// }
869/// }
870///
871/// // ==========================================================================
872/// // INLINE FUNCTION DEFINITIONS
873/// // ==========================================================================
874///
875/// // --------------
876/// // class Customer
877/// // --------------
878///
879/// ```
880/// The constructor implementations of 'Customer' can simply forward the
881/// basicAllocator argument to its data members. All BSL containers, including
882/// 'bsl::string' and 'bsl::vector', accept a 'bslma::Allocator' constructor
883/// argument:
884/// ```
885///
886/// // CREATORS
887/// inline
888/// Customer::Customer(bslma::Allocator *basicAllocator)
889/// : d_firstName(basicAllocator)
890/// , d_lastName(basicAllocator)
891/// , d_accounts(basicAllocator)
892/// , d_id(0)
893/// {
894/// }
895///
896/// inline
897/// Customer::Customer(const bslstl::StringRef& firstName,
898/// const bslstl::StringRef& lastName,
899/// const bsl::vector<int>& accounts,
900/// int id,
901/// bslma::Allocator *basicAllocator)
902/// : d_firstName(firstName.begin(), firstName.end(), basicAllocator)
903/// , d_lastName(lastName.begin(), lastName.end(), basicAllocator)
904/// , d_accounts(accounts, basicAllocator)
905/// , d_id(id)
906/// {
907/// BSLS_ASSERT_SAFE(!firstName.isEmpty());
908/// BSLS_ASSERT_SAFE(!lastName.isEmpty());
909/// }
910///
911/// inline
912/// Customer::Customer(const Customer& original,
913/// bslma::Allocator *basicAllocator)
914/// : d_firstName(original.d_firstName, basicAllocator)
915/// , d_lastName(original.d_lastName, basicAllocator)
916/// , d_accounts(original.d_accounts, basicAllocator)
917/// , d_id(original.d_id)
918/// {
919/// }
920///
921/// // MANIPULATORS
922/// inline
923/// Customer& Customer::operator=(const Customer& rhs)
924/// {
925/// d_firstName = rhs.d_firstName;
926/// d_lastName = rhs.d_lastName;
927/// d_accounts = rhs.d_accounts;
928/// d_id = rhs.d_id;
929/// return *this;
930/// }
931///
932/// // Aspects
933///
934/// inline
935/// bslma::Allocator *Customer::allocator() const
936/// {
937/// return d_firstName.get_allocator().mechanism();
938/// }
939///
940/// ```
941/// Again for simplicity the rest of the implementation is not provided.
942///
943/// ### Example 2: Implementing Templates That May Be Supplied Allocating Types {#bslma-example-2-implementing-templates-that-may-be-supplied-allocating-types}
944///
945/// When writing templatized code that may be parameterized on types that allocate
946/// memory it is often necessary to decide whether to pass through the
947/// user-supplied allocator to individual objects. Such code (and containers) can
948/// use the UsesBslmaAllocator trait defined in the bslma package to decide
949/// whether to pass the allocator to an object's constructor. An example of using
950/// this trait is provided below by showing a simplified parameterized object pool
951/// `class`:
952/// ```
953/// // ================
954/// // class ObjectPool
955/// // ================
956///
957/// /// This `class` provides a pool of reusable objects of the parameterized
958/// /// `TYPE` and assumes that the parameterized `TYPE` provides a default
959/// /// constructor, a destructor, and a `reset` method.
960/// template <typename TYPE>
961/// class ObjectPool {
962///
963/// // DATA
964/// bsl::list<TYPE *> d_objects; // list of managed objects
965/// bslma::Allocator *d_allocator_p; // memory allocator (held, not owned)
966///
967/// // PRIVATE CLASS METHODS
968///
969/// /// Construct an object of the specified `TYPE` that *does not*
970/// /// require an allocator to be passed to its constructor.
971/// TYPE *createObject(bsl::false_type);
972///
973/// /// Construct an object of the specified `TYPE` that *requires* an
974/// /// allocator to be passed to its constructor.
975/// TYPE *createObject(bsl::true_type);
976///
977/// public:
978/// // CREATORS
979///
980/// /// Create an object pool that invokes the default constructor of the
981/// /// parameterized `TYPE` to construct objects. The optionally
982/// /// specified `basicAllocator` is used to supply memory. If
983/// /// `basicAllocator` is 0, the currently installed default allocator
984/// /// is used.
985/// ObjectPool(bslma::Allocator *basicAllocator = 0);
986///
987/// /// Destroy this object pool. All objects created by this pool are
988/// /// destroyed (even if some of them are still in use) and memory is
989/// /// reclaimed.
990/// ~ObjectPool();
991///
992/// // MANIPULATORS
993///
994/// /// Return an address providing modifiable access to a
995/// /// default-constructed object of the parameterized `TYPE`. If this
996/// /// pool does not have any free objects then a default-constructed
997/// /// object is allocated and returned.
998/// TYPE* getObject();
999///
1000/// /// Return the specified `object` back to this object pool. Invoke
1001/// /// the `reset` method on `object`.
1002/// void releaseObject(TYPE *object);
1003///
1004/// // The rest of the interface is elided for brevity.
1005/// };
1006///
1007/// // ==========================================================================
1008/// // INLINE FUNCTION DEFINITIONS
1009/// // ==========================================================================
1010///
1011/// // ----------------
1012/// // class ObjectPool
1013/// // ----------------
1014///
1015/// ```
1016/// The 'createObject' private methods below allow an object to be created by
1017/// specifying an allocator only if it has the 'UsesBslmaAllocator' trait.
1018/// ```
1019///
1020/// // PRIVATE CLASS METHODS
1021/// template <typename TYPE>
1022/// inline
1023/// TYPE *ObjectPool<TYPE>::createObject(bsl::false_type)
1024/// {
1025/// return new (*d_allocator_p) TYPE();
1026/// }
1027///
1028/// template <typename TYPE>
1029/// inline
1030/// TYPE *ObjectPool<TYPE>::createObject(bsl::true_type)
1031/// {
1032/// return new (*d_allocator_p) TYPE(d_allocator_p);
1033/// }
1034///
1035/// // CREATORS
1036/// template <typename TYPE>
1037/// inline
1038/// ObjectPool<TYPE>::ObjectPool(bslma::Allocator *basicAllocator)
1039/// : d_objects(basicAllocator)
1040/// , d_allocator_p(bslma::Default::allocator(basicAllocator))
1041/// {
1042/// }
1043///
1044/// template <typename TYPE>
1045/// ObjectPool<TYPE>::~ObjectPool()
1046/// {
1047/// for (bsl::list<TYPE *>::iterator iter = d_objects.begin();
1048/// iter != d_objects.end();
1049/// ++iter) {
1050/// d_allocator_p->deleteObject(*iter);
1051/// }
1052/// d_objects.clear();
1053/// }
1054///
1055/// // MANIPULATORS
1056/// template <typename TYPE>
1057/// TYPE *ObjectPool<TYPE>::getObject()
1058/// {
1059/// if (d_objects.size()) {
1060/// TYPE *object = d_objects.back();
1061/// d_objects.pop_back();
1062/// return object; // RETURN
1063/// }
1064///
1065/// return createObject(bslma::UsesBslmaAllocator<TYPE>());
1066/// }
1067///
1068/// template <typename TYPE>
1069/// inline
1070/// void ObjectPool<TYPE>::releaseObject(TYPE *object)
1071/// {
1072/// object->reset();
1073/// d_objects.push_back(object);
1074/// }
1075/// ```
1076///
1077/// ### Example 3: Implementing a Customized Allocator {#bslma-example-3-implementing-a-customized-allocator}
1078///
1079/// Since 'bslma::Allocator' is a protocol, users can create their own concrete
1080/// implementations for object-specific situations. A complete example of a
1081/// concrete implementation that allocates memory from a user-supplied static
1082/// buffer and reverts to an allocator specified at construction if that buffer is
1083/// exhausted is provided below:
1084///
1085/// ```
1086/// // =====================
1087/// // class BufferAllocator
1088/// // =====================
1089///
1090/// using namespace BloombergLP;
1091///
1092/// /// This `class` provides a concrete buffer allocator that implements the
1093/// /// `bslma::Allocator` interface, allocating memory blocks from a
1094/// /// fixed-size buffer that is supplied by the user at construction, or
1095/// /// from an optionally-specified allocator once that buffer is exhausted.
1096/// class BufferAllocator : public bslma::Allocator {
1097///
1098/// // DATA
1099/// char *d_buffer_p; // buffer to use for memory
1100/// // allocations (held, not owned)
1101/// int d_bufferSize; // initial buffer size
1102/// int d_cursor; // current cursor
1103/// bslma::Allocator *d_allocator_p; // memory allocator to use once
1104/// // `d_buffer_p` is exhausted (held,
1105/// // not owned)
1106///
1107/// private:
1108/// // NOT IMPLEMENTED
1109/// BufferAllocator(const BufferAllocator&);
1110/// BufferAllocator& operator=(const BufferAllocator&);
1111///
1112/// public:
1113/// // CREATORS
1114///
1115/// /// Create a buffer allocator for allocating memory blocks from the
1116/// /// specified `buffer` of the specified `bufferSize`. Optionally
1117/// /// specify a `basicAllocator` used to supply memory after that
1118/// /// `buffer` is exhausted. If `basicAllocator` is 0, the currently
1119/// /// installed default allocator is used.
1120/// BufferAllocator(char *buffer,
1121/// int bufferSize,
1122/// bslma::Allocator *basicAllocator = 0);
1123///
1124/// /// Destroy this buffer allocator.
1125/// virtual ~BufferAllocator();
1126///
1127/// // MANIPULATORS
1128///
1129/// /// Return the address of a contiguous block of maximally-aligned
1130/// /// memory of the specified `size` (in bytes). If `size` is 0 no
1131/// /// memory is allocated and 0 is returned. If the allocation request
1132/// /// exceeds the remaining free memory space in the external buffer
1133/// /// supplied at construction, the allocator specified at construction
1134/// /// is used. The behavior is undefined unless `0 <= size`.
1135/// virtual void *allocate(bsls::Types::size_type size);
1136///
1137/// /// Deallocate the specified `address` if it did not come from the
1138/// /// external buffer specified at construction and do nothing
1139/// /// otherwise. Note that if the buffer specified at construction was
1140/// /// not exhausted then no deallocation overhead is incurred.
1141/// virtual void deallocate(void *address);
1142/// };
1143///
1144/// // ==========================================================================
1145/// // INLINE FUNCTION DEFINITIONS
1146/// // ==========================================================================
1147///
1148/// // ---------------------
1149/// // class BufferAllocator
1150/// // ---------------------
1151///
1152/// // CREATORS
1153/// inline
1154/// BufferAllocator::BufferAllocator(char *buffer,
1155/// int bufferSize,
1156/// bslma::Allocator *basicAllocator)
1157/// : d_buffer_p(buffer)
1158/// , d_bufferSize(bufferSize)
1159/// , d_cursor(0)
1160/// , d_allocator_p(bslma::Default::allocator(basicAllocator))
1161/// {
1162/// }
1163///
1164/// inline
1165/// BufferAllocator::~BufferAllocator()
1166/// {
1167/// }
1168///
1169/// ```
1170/// The function definitions for the 'BufferAllocator' 'class' are provided below:
1171/// ```
1172/// // MANIPULATORS
1173/// void *BufferAllocator::allocate(bsls::Types::size_type size)
1174/// {
1175/// BSLS_ASSERT_SAFE(0 <= size);
1176///
1177/// // Calculate the appropriate aligned offset
1178///
1179/// const int offset = bsls::AlignmentUtil::calculateAlignmentOffset(
1180/// d_buffer_p + d_cursor,
1181/// bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT);
1182///
1183/// if (d_cursor + offset + size > d_bufferSize) {
1184/// return d_allocator_p->allocate(size); // RETURN
1185/// }
1186///
1187/// void *result = static_cast<void *>(&d_buffer_p[d_cursor + offset]);
1188/// d_cursor += offset + size;
1189///
1190/// return result;
1191/// }
1192///
1193/// void BufferAllocator::deallocate(void *address)
1194/// {
1195/// if (!(d_buffer_p <= address && address < d_buffer_p + d_bufferSize)) {
1196/// d_allocator_p->deallocate(address);
1197/// }
1198/// }
1199/// ```
1200///
1201/// @}
1202/** @} */