BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_allocator.h
Go to the documentation of this file.
1/// @file bslma_allocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_allocator.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_ALLOCATOR
9#define INCLUDED_BSLMA_ALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_allocator bslma_allocator
15/// @brief Provide a pure abstract interface for memory-allocation mechanisms.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_allocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_allocator-purpose"> Purpose</a>
25/// * <a href="#bslma_allocator-classes"> Classes </a>
26/// * <a href="#bslma_allocator-description"> Description </a>
27/// * <a href="#bslma_allocator-thread-safety"> Thread Safety </a>
28/// * <a href="#bslma_allocator-allocators-versus-pools"> Allocators Versus Pools </a>
29/// * <a href="#bslma_allocator-overloaded-global-operators-new-and-delete"> Overloaded Global Operators new and delete </a>
30/// * <a href="#bslma_allocator-usage"> Usage </a>
31/// * <a href="#bslma_allocator-example-1-container-objects"> Example 1: Container Objects </a>
32/// * <a href="#bslma_allocator-example-2-derived-concrete-allocators"> Example 2: Derived Concrete Allocators </a>
33///
34/// # Purpose {#bslma_allocator-purpose}
35/// Provide a pure abstract interface for memory-allocation mechanisms.
36///
37/// # Classes {#bslma_allocator-classes}
38///
39/// - bslma::Allocator: protocol class for memory allocation and deallocation
40///
41/// @see bslma_newdeleteallocator, bslma_testallocator
42///
43/// # Description {#bslma_allocator-description}
44/// This component provides the base-level protocol (pure abstract
45/// interface) class, @ref bslma_allocator , that serves as a ubiquitous vocabulary
46/// type for various memory allocation mechanisms. The functional capabilities
47/// documented by this protocol are similar to those afforded by global
48/// operators `new` and `delete`: sufficiently (but not necessarily maximally)
49/// aligned memory is guaranteed for any object of a given size. Clients of
50/// this abstract base class will typically accept a supplied allocator (often
51/// at construction) and use its `allocate` and `deallocate` methods instead of
52/// `new` and `delete` directly.
53///
54/// The use of (abstract) allocators provides at least three distinct advantages
55/// over direct (hard-coded) calls to global `new` and `delete` (see
56/// @ref bslma_newdeleteallocator ):
57///
58/// 1. The particular choice of allocator can be selected to improve performance
59/// on a per-object basis. Without allocators, the best we can do in C++ is
60/// to overload the class-specific new and delete. Class-specific allocators
61/// tend to hoard memory even when most objects of the class have been
62/// deallocated, and often mask memory leaks that would otherwise have been
63/// detected. See Lakos-96, Section 10.3.4.2, pp 705-711.
64/// 2. By providing extra capabilities (beyond `new` and `delete`) in the
65/// derived class (see @ref bslma_managedallocator ), we can bypass the
66/// individual destructors in a dynamically allocated type and remove all
67/// memory for one or more associated object almost instantly.
68/// 3. The `bslma::Allocator` protocol, like any other protocol, isolates
69/// clients from direct coupling with platform level facilities that are not
70/// fully under their control. By installing a test allocator (see
71/// @ref bslma_testallocator ), we are able to orchestrate the white-box testing
72/// of internal calls to global operators `new` and `delete` in a
73/// platform-neutral manner.
74///
75/// ## Thread Safety {#bslma_allocator-thread-safety}
76///
77///
78/// Unless otherwise documented, a single allocator object is not safe for
79/// concurrent access by multiple threads. Classes derived from
80/// `bslma::Allocator` that are specifically designed for concurrent access must
81/// be documented as such. Unless specifically documented otherwise, separate
82/// objects of classes derived from `bslma::Allocator` may safely be used in
83/// separate threads.
84///
85/// ## Allocators Versus Pools {#bslma_allocator-allocators-versus-pools}
86///
87///
88/// An allocator and a pool are quite different. For starters,
89/// `bslma::Allocator` is an abstract class used to obtain "raw" memory of
90/// arbitrary size. A pool is a concrete data structure used to organize and
91/// supply memory according to specific needs (e.g., a consistent size).
92/// Concrete allocators may use pools in their implementations, and pools will
93/// always take a base `bslma::Allocator` protocol in their interface. You can
94/// think of an allocator as a stream of memory that flows into a pool of
95/// memory. Memory is allocated from the pool until it is dry; only then does
96/// new memory flow into the pool from the allocator.
97///
98/// ## Overloaded Global Operators new and delete {#bslma_allocator-overloaded-global-operators-new-and-delete}
99///
100///
101/// This component overloads the global operator `new` to allow convenient
102/// syntax for the construction of objects using the `bslma::Allocator`
103/// protocol. The overloaded `new` operator defined in this component has a
104/// second parameter, `bslma::Allocator&`, that identifies the concrete
105/// (derived) allocator that will be used to supply memory.
106///
107/// Consider the following use of standard placement syntax (supplied by
108/// `#include <new>`) along with a `bslma::Allocator`, used to allocate an
109/// arbitrary `TYPE`.
110/// @code
111/// void someFunction(bslma::Allocator *basicAllocator)
112/// {
113/// TYPE *obj = new (basicAllocator->allocate(sizeof(TYPE))) TYPE(...);
114///
115/// // ...
116/// @endcode
117/// This style of usage is inconvenient and error prone; it is also *not*
118/// exception safe: If the constructor of `TYPE` throws an exception, the
119/// `basicAllocator->deallocate` method is never called.
120///
121/// Providing an overloaded global operator `new`, taking a reference to a
122/// modifiable `bslma::Allocator` as an explicit argument allows for cleaner
123/// usage and guarantees that the `basicAllocator->deallocate` method is called
124/// in case of an exception:
125/// @code
126/// void someFunction(bslma::Allocator *basicAllocator)
127/// {
128/// TYPE *obj = new (*basicAllocator) TYPE(...);
129///
130/// // ...
131/// @endcode
132/// Finally, the analogous version of operator `delete` should not be called
133/// directly: The overloaded operator `delete` supplied in this component is
134/// solely for the compiler to invoke in the event an exception is thrown during
135/// a failed construction. Instead, the `bslma::Allocator` protocol provides
136/// `deleteObject` (a template member function parameterized by the type of the
137/// object being deleted), which is implemented *conceptually* as follows:
138/// @code
139/// template <class TYPE>
140/// void bslma::Allocator::deleteObject(TYPE *address)
141/// {
142/// address->~TYPE();
143/// this->deallocate(address);
144/// }
145/// @endcode
146/// Note that there is also a `deleteObjectRaw` which is more efficient when it
147/// is known that the `address` does *not* refer to a secondary base class of
148/// the object being deleted.
149///
150/// ## Usage {#bslma_allocator-usage}
151///
152///
153/// The `bslma::Allocator` protocol provided in this component defines a
154/// bilateral contract between suppliers and consumers of raw memory. The
155/// following subsections illustrate (1) use, and (2) implementation of the
156/// abstract `bslma::Allocator` base class:
157///
158/// ### Example 1: Container Objects {#bslma_allocator-example-1-container-objects}
159///
160///
161/// Allocators are often supplied to objects requiring dynamically-allocated
162/// memory at construction. For example, consider the following
163/// `my_DoubleStack` class, parameterized by a `bslma::Allocator`:
164/// @code
165/// // my_doublestack.h
166/// // ...
167///
168/// #include <bslma_allocator.h>
169///
170/// class my_DoubleStack {
171/// // DATA
172/// double *d_stack_p; // dynamically allocated array (d_size
173/// // elements)
174///
175/// int d_size; // physical capacity of this stack (in
176/// // elements)
177///
178/// int d_length; // logical index of next available
179/// // stack element
180///
181/// bslma::Allocator *d_allocator_p; // holds (but does not own) object
182///
183/// // FRIENDS
184/// friend class my_DoubleStackIter;
185///
186/// private:
187/// // PRIVATE MANIPULATORS
188/// void increaseSize(); // Increase the capacity by at least one element.
189///
190/// public:
191/// // CREATORS
192/// my_DoubleStack(bslma::Allocator *basicAllocator = 0);
193/// my_DoubleStack(const my_DoubleStack& other,
194/// bslma::Allocator *basicAllocator = 0);
195/// ~my_DoubleStack();
196///
197/// // MANIPULATORS
198/// my_DoubleStack& operator=(const my_DoubleStack& rhs);
199/// void push(double value);
200/// void pop();
201///
202/// // ACCESSORS
203/// const double& top() const;
204/// bool isEmpty() const;
205/// };
206///
207/// // ...
208///
209/// inline
210/// void my_DoubleStack::push(double value)
211/// {
212/// if (d_length >= d_size) {
213/// increaseSize();
214/// }
215/// d_stack_p[d_length++] = item;
216/// }
217///
218/// // ...
219/// @endcode
220/// The stack interface takes an optional `basicAllocator` supplied only at
221/// construction. (We avoid use of the name `allocator` so as not to conflict
222/// with the STL use of the word, which differs slightly.) If non-zero, the
223/// stack holds a pointer to this allocator, but does not own it. If no
224/// allocator is supplied, the implementation itself must either conditionally
225/// invoke global `new` and `delete` explicitly whenever dynamic memory must be
226/// managed (BAD IDEA) or (GOOD IDEA) install a default allocator that adapts
227/// use of these global operators to the @ref bslma_allocator interface (see
228/// @ref bslma_newdeleteallocator ).
229/// @code
230/// // my_doublestack.cpp
231/// #include <my_doublestack.h>
232/// #include <bslma_allocator.h>
233/// #include <bslma_newdeleteallocator.h> // adapter for 'new' and 'delete'
234/// // ...
235///
236/// enum { INITIAL_SIZE = 1, GROW_FACTOR = 2 };
237///
238/// // ...
239///
240/// // CREATORS
241/// my_DoubleStack::my_DoubleStack(bslma::Allocator *basicAllocator)
242/// : d_size(INITIAL_SIZE)
243/// , d_length(0)
244/// , d_allocator_p(bslma::NewDeleteAllocator::allocator(basicAllocator))
245/// // The above initialization expression is equivalent to 'basicAllocator
246/// // ? basicAllocator : &bslma::NewDeleteAllocator::singleton()'.
247/// {
248/// assert(d_allocator_p);
249/// d_stack_p = (double *)
250/// d_allocator_p->allocate(d_size * sizeof *d_stack_p);
251/// }
252///
253/// my_DoubleStack::~my_DoubleStack()
254/// {
255/// // CLASS INVARIANTS
256/// assert(d_allocator_p);
257/// assert(d_stack_p);
258/// assert(0 <= d_length);
259/// assert(0 <= d_size);
260/// assert(d_length <= d_size);
261///
262/// d_allocator_p->deallocate(d_stack_p);
263/// }
264/// @endcode
265/// Even in this simplified implementation, all use of the allocator protocol is
266/// relegated to the `.cpp` file. Subsequent use of the allocator is
267/// demonstrated by the following file-scope static reallocation function:
268/// @code
269/// /// Reallocate memory in the specified `array` to the specified
270/// /// `newSize` using the specified `basicAllocator`. The specified
271/// /// `length` number of leading elements are preserved. Since the
272/// /// class invariant requires that the physical capacity of the
273/// /// container may grow but never shrink, the behavior is undefined
274/// /// unless `length <= newSize`.
275/// static inline
276/// void reallocate(double **array,
277/// int newSize,
278/// int length,
279/// bslma::Allocator *basicAllocator)
280/// {
281/// assert(array);
282/// assert(1 <= newSize);
283/// assert(0 <= length);
284/// assert(basicAllocator);
285/// assert(length <= newSize); // enforce class invariant
286///
287/// double *tmp = *array; // support exception neutrality
288/// *array = (double *) basicAllocator->allocate(newSize * sizeof **array);
289///
290/// // COMMIT POINT
291///
292/// std::memcpy(*array, tmp, length * sizeof **array);
293/// basicAllocator->deallocate(tmp);
294/// }
295///
296/// // PRIVATE MANIPULATORS
297/// void my_DoubleStack::increaseSize()
298/// {
299/// int proposedNewSize = d_size * GROW_FACTOR; // reallocate can throw
300/// assert(proposedNewSize > d_length);
301/// reallocate(&d_stack_p, proposedNewSize, d_length, d_allocator_p);
302/// d_size = proposedNewSize; // we're committed
303/// }
304/// @endcode
305///
306/// ### Example 2: Derived Concrete Allocators {#bslma_allocator-example-2-derived-concrete-allocators}
307///
308///
309/// In order for the `bslma::Allocator` interface to be useful, we must supply a
310/// concrete allocator that implements it. In this example we demonstrate how
311/// to adapt `operator new` and `operator delete` to this protocol base class.
312/// @code
313/// // my_newdeleteallocator.h
314/// // ...
315///
316/// /// This class is a sample concrete implementation of the
317/// /// `bslma::Allocator` protocol that provides direct access to the
318/// /// system-supplied (native) global operators `new` and `delete`.
319/// class my_NewDeleteAllocator : public bslma::Allocator {
320///
321/// // NOT IMPLEMENTED
322/// my_NewDeleteAllocator(const bslma::NewDeleteAllocator&);
323/// my_NewDeleteAllocator& operator=(const bslma::NewDeleteAllocator&);
324///
325/// public:
326/// // CREATORS
327///
328/// /// Create an allocator that wraps the global (native) operators
329/// /// `new` and `delete` to supply memory. Note that all objects of
330/// /// this class share the same underlying resource.
331/// my_NewDeleteAllocator();
332///
333/// /// Destroy this allocator object. Note that destroying this
334/// /// allocator has no effect on any outstanding allocated memory.
335/// virtual ~my_NewDeleteAllocator();
336///
337/// // MANIPULATORS
338///
339/// /// Return a newly allocated block of memory of (at least) the
340/// /// specified positive `size` (in bytes). If `size` is 0, a null
341/// /// pointer is returned with no other effect. If this allocator
342/// /// cannot return the requested number of bytes, then it will throw
343/// /// a `std::bad_alloc` exception in an exception-enabled build, or
344/// /// else will abort the program in a non-exception build. The
345/// /// behavior is undefined unless `0 <= size`. Note that the
346/// /// alignment of the address returned is the maximum alignment for
347/// /// any type defined on this platform. Also note that global
348/// /// `operator new` is *not* called when `size` is 0 (in order to
349/// /// avoid having to acquire a lock, and potential contention in
350/// /// multi-threaded programs).
351/// virtual void *allocate(size_type size);
352///
353/// /// Return the memory block at the specified `address` back to this
354/// /// allocator. If `address` is 0, this function has no effect. The
355/// /// behavior is undefined unless `address` was allocated using this
356/// /// allocator object and has not already been deallocated. Note
357/// /// that global `operator delete` is *not* called when `address` is
358/// /// 0 (in order to avoid having to acquire a lock, and potential
359/// /// contention in multi-treaded programs).
360/// virtual void deallocate(void *address);
361/// };
362///
363/// // CREATORS
364/// inline
365/// my_NewDeleteAllocator::my_NewDeleteAllocator()
366/// {
367/// }
368/// // ...
369/// @endcode
370/// The virtual methods of `my_NewDeleteAllocator` are defined in the component
371/// `.cpp` file as they would not be inlined when invoked from the base class,
372/// which would be the typical usage in this case:
373/// @code
374/// // my_newdeleteallocator.cpp
375/// #include <my_newdeleteallocator.h>
376///
377/// // CREATORS
378/// my_NewDeleteAllocator::~my_NewDeleteAllocator()
379/// {
380/// }
381///
382/// // MANIPULATORS
383/// void *my_NewDeleteAllocator::allocate(size_type size)
384/// {
385/// BSLS_ASSERT_SAFE(0 <= size);
386///
387/// return 0 == size ? 0 : ::operator new(size);
388/// }
389///
390/// void my_NewDeleteAllocator::deallocate(void *address)
391/// {
392/// // While the C++ standard guarantees that calling delete(0) is safe
393/// // (3.7.3.2 paragraph 3), some libc implementations take out a lock to
394/// // deal with the free(0) case, so this check can improve efficiency of
395/// // threaded programs.
396///
397/// if (address) {
398/// ::operator delete(address);
399/// }
400/// }
401/// @endcode
402/// @}
403/** @} */
404/** @} */
405
406/** @addtogroup bsl
407 * @{
408 */
409/** @addtogroup bslma
410 * @{
411 */
412/** @addtogroup bslma_allocator
413 * @{
414 */
415
416#include <bslma_allocator.fwd.h>
417
418#include <bslscm_version.h>
419
420#include <bslma_deleterhelper.h>
421#include <bslma_memoryresource.h>
422
423#include <bslmf_assert.h>
426#include <bslmf_issame.h>
429
430#include <bsls_keyword.h>
431#include <bsls_nullptr.h>
432#include <bsls_platform.h>
433
434#include <cstddef> // for 'std::size_t', 'std::ptrdiff_t'
435
436#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
437#include <bsls_cpp11.h>
438#endif
439
440
441
442namespace bslma {
443
444 // ===============
445 // class Allocator
446 // ===============
447
448/// This protocol class provides a pure abstract interface and contract for
449/// clients and suppliers of raw memory. If the requested memory cannot be
450/// returned, the contract requires that an `std::bad_alloc` exception be
451/// thrown. Note that memory is guaranteed to be sufficiently aligned for
452/// any object of the requested size on the current platform, which may be
453/// less than the maximal alignment guarantee afforded by global
454/// `operator new`.
455///
456/// See @ref bslma_allocator
458
459 protected:
460 // PROTECTED MANIPULATORS
461
462 /// Return a newly allocated block of memory of (at least) the specified
463 /// positive `bytes` and having at least the specified `alignment`.
464 /// Unless overriden in a derived class, the return value is
465 /// `this->allocate(bytes)`. If this allocator cannot return the
466 /// requested number of bytes or cannot satisfy the alignment request,
467 /// then it will throw a `std::bad_alloc` exception in an
468 /// exception-enabled build, or else will abort the program in a
469 /// non-exception build. The behavior is undefined unless '0 <=
470 /// bytes'. Unless overriden in a derived class, the behavior is
471 /// undefined if `alignment > bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT`.
472 void* do_allocate(std::size_t bytes,
473 std::size_t alignment) BSLS_KEYWORD_OVERRIDE;
474
475 /// Return the memory block at the specified `p` address, having the
476 /// specified `bytes` and specified `alignment`, back to this allocator.
477 /// If `address` is 0, this function has no effect. The behavior is
478 /// undefined unless `address` is 0 or a block allocated from this
479 /// allocator object using the same `bytes` and `alignment` and has not
480 /// already been deallocated.
481 void do_deallocate(void *p,
482 std::size_t bytes,
483 std::size_t alignment) BSLS_KEYWORD_OVERRIDE;
484
485 // PROTECTED ACCESSORS
486
487 /// Return `true` if this allocator is equal to the specified `other`
488 /// allocator, meaning (at least) that a memory block allocated by one
489 /// can be deallocated by the other; otherwise return `false`. Unless
490 /// overriden, this method returns `this == &other`.
491 bool do_is_equal(const memory_resource& other) const
493
494 public:
495 // PUBLIC TYPES
496
497 /// Alias for an unsigned integral type capable of representing the
498 /// number of bytes in this platform's virtual address space.
499 typedef std::size_t size_type;
500
501#ifndef BDE_OMIT_INTERNAL_DEPRECATED
502 // CLASS METHODS
503
504 /// @deprecated Use @ref bsls::BslExceptionUtil::throwBadAlloc instead.
505 ///
506 /// Throw `std::bad_alloc` if exceptions are enabled or abort the
507 /// program otherwise. Derived classes and helper functions will
508 /// typically call this function when they are unable to satisfy an
509 /// allocation request. This function never returns.
510 static void throwBadAlloc();
511#endif // BDE_OMIT_INTERNAL_DEPRECATED
512
513 // CREATORS
514
515 /// Destroy this allocator. Note that the behavior of destroying an
516 /// allocator while memory is allocated from it is not specified;
517 /// unless you *know* that it is valid to do so, don't!
519
520 // MANIPULATORS
521
522 /// Return a newly allocated block of memory of (at least) the specified
523 /// positive `size` (in bytes). If `size` is 0, a null pointer is
524 /// returned with no other effect. If this allocator cannot return the
525 /// requested number of bytes, then it will throw a `std::bad_alloc`
526 /// exception in an exception-enabled build, or else will abort the
527 /// program in a non-exception build. The behavior is undefined unless
528 /// `0 <= size`. Note that the alignment of the address returned
529 /// conforms to the platform requirement for any object of the specified
530 /// `size`. Note that this virtual function hides a two-argument
531 /// non-virtual `allocate` method inherited from `bsl::memory_resource`;
532 /// to access the inherited function, upcast the object to
533 /// `bsl::memory_resource&` before calling the base-class function.
534 virtual void *allocate(size_type size) = 0;
535
536 /// Return the memory block at the specified `address` back to this
537 /// allocator. If `address` is 0, this function has no effect. The
538 /// behavior is undefined unless `address` was allocated using this
539 /// allocator object and has not already been deallocated. Note that
540 /// this virtual function hides a two-argument, non-virtual `deallocate`
541 /// method inherited from `bsl::memory_resource`; to access the
542 /// inherited function, upcast the object to `bsl::memory_resource&`
543 /// before calling the base-class function.
544 virtual void deallocate(void *address) = 0;
545
546 /// Destroy the specified `object` based on its dynamic type and then
547 /// use this allocator to deallocate its memory footprint. Do nothing
548 /// if `object` is a null pointer. The behavior is undefined unless
549 /// `object`, when cast appropriately to `void *`, was allocated using
550 /// this allocator and has not already been deallocated. Note that
551 /// `dynamic_cast<void *>(object)` is applied if `TYPE` is polymorphic,
552 /// and `static_cast<void *>(object)` is applied otherwise.
553 template <class TYPE>
554 void deleteObject(const TYPE *object);
555
556 /// Destroy the specified `object` and then use this allocator to
557 /// deallocate its memory footprint. Do nothing if `object` is a null
558 /// pointer. The behavior is undefined unless `object` was allocated
559 /// using this allocator, is **not** a secondary base class pointer --
560 /// i.e., the address is (numerically) the same as when it was
561 /// originally dispensed by this allocator, and has not already been
562 /// deallocated.
563 template <class TYPE>
564 void deleteObjectRaw(const TYPE *object);
565
566 /// This function has no effect. Note that it exists to support calling
567 /// `deleteObject` will a null pointer literal, that would otherwise not
568 /// deduce to a pointer type for the method above. As calls to
569 /// `deleteObject` with (typed) null pointer values have well-defined
570 /// behavior, it should also support calls with a null pointer literal.
571 void deleteObject(bsl::nullptr_t);
572
573 /// This function has no effect. Note that it exists to support calling
574 /// `deleteObjectRaw` will a null pointer literal, that would otherwise
575 /// not deduce to a pointer type for the method above. As calls to
576 /// `deleteObjectRaw` with (typed) null pointer values have well-defined
577 /// behavior, it should also support calls with a null pointer literal.
578 void deleteObjectRaw(bsl::nullptr_t);
579};
580
581} // close package namespace
582
583
584// FREE OPERATORS
585
586// Note that the operators 'new' and 'delete' are declared outside the
587// 'BloombergLP' namespace so that they do not hide the standard placement
588// 'new' and 'delete' operators (i.e.,
589// 'void *operator new(std::size_t, void *)' and
590// 'void operator delete(void *)').
591//
592// Note also that only the scalar versions of operators 'new' and 'delete' are
593// provided, because overloading 'new' (and 'delete') with their array versions
594// would cause dangerous ambiguity. Consider what would have happened had we
595// overloaded the array version of operator 'new':
596//..
597// void *operator new[](std::size_t size,
598// BloombergLP::bslma::Allocator& basicAllocator)
599//..
600// The user of the allocator class may expect to be able to use array
601// 'operator new' as follows:
602//..
603// new (*basicAllocator) my_Type[...];
604//..
605// The problem is that this expression returns an array that cannot be safely
606// deallocated. On the one hand, there is no syntax in C++ to invoke an
607// overloaded 'operator delete' that, other than deallocating memory, would
608// invoke the destructor. On the other hand, the pointer returned by
609// 'operator new' cannot be passed to the 'deallocate' method directly because
610// the pointer is different from the one returned by the 'allocate' method.
611// The compiler offsets the value of this pointer by a header, which is used to
612// maintain the number of objects in the array (so that the non-overloaded
613// 'operator delete' can destroy the right number of objects).
614
615/// Return the memory allocated from the specified `basicAllocator` of at
616/// least the specified `size` bytes, or 0 if `size` is 0. The behavior is
617/// undefined unless `0 <= static_cast<bslma::Allocator::size_type>(size)`.
618/// Note that an object may allocate additional memory internally, requiring
619/// the allocator to be passed in as a constructor argument:
620/// @code
621/// my_Type *createMyType(bslma::Allocator *basicAllocator)
622/// {
623/// return new (*basicAllocator) my_Type(..., basicAllocator);
624/// }
625/// @endcode
626/// Note also that the analogous version of operator `delete` should *not*
627/// be called directly. Instead, this component provides a template member
628/// function `deleteObject` parameterized by `TYPE` that effectively
629/// performs the following operations:
630/// @code
631/// void deleteMyType(bslma::Allocator *basicAllocator, my_Type *address)
632/// {
633/// address->~my_Type();
634/// basicAllocator->deallocate(address);
635/// }
636/// @endcode
637/// See also `deleteObjectRaw` for better performance when `address` is
638/// known not to be a secondary base type of the object being deleted.
639inline
640void *operator new(std::size_t size,
641 BloombergLP::bslma::Allocator& basicAllocator);
642
643/// Use the specified `basicAllocator` to deallocate the memory at the
644/// specified `address`. The behavior is undefined unless `address` was
645/// allocated using `basicAllocator` and has not already been deallocated.
646/// This operator is supplied solely to allow the compiler to arrange for it
647/// to be called in case of an exception.
648inline
649void operator delete(void *address,
650 BloombergLP::bslma::Allocator& basicAllocator);
651
652// NOTE: The following two operators are declared but never defined to force a
653// link-time error should any code inadvertently use them.
654
655/// Note that this operator is intentionally not defined.
656void *operator new(
657 std::size_t size,
658 BloombergLP::bslma::Allocator *basicAllocator) BSLS_KEYWORD_DELETED;
659
660/// Note that this operator is intentionally not defined.
661void operator delete(
662 void *address,
663 BloombergLP::bslma::Allocator *basicAllocator) BSLS_KEYWORD_DELETED;
664
665// ============================================================================
666// INLINE DEFINITIONS
667// ============================================================================
668
669
670
671namespace bslma {
672
673 // ---------------
674 // class Allocator
675 // ---------------
676
677// MANIPULATORS
678template <class TYPE>
679inline
680void Allocator::deleteObject(const TYPE *object)
681{
682 DeleterHelper::deleteObject(object, this);
683}
684
685
686inline
688{
689 // This function body is intentionally left blank.
690}
691
692template <class TYPE>
693inline
694void Allocator::deleteObjectRaw(const TYPE *object)
695{
696 DeleterHelper::deleteObjectRaw(object, this);
697}
698
699inline
701{
702 // This function body is intentionally left blank.
703}
704
705} // close package namespace
706
707#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
708// ============================================================================
709// BACKWARD COMPATIBILITY
710// ============================================================================
711
712/// This alias is defined for backward compatibility.
714
715#ifndef bdema_Allocator
716#define bdema_Allocator bslma::Allocator
717#endif
718#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
719
720
721
722// ============================================================================
723// INLINE FUNCTION DEFINITIONS
724// ============================================================================
725
726inline
727void *operator new(std::size_t size,
728 BloombergLP::bslma::Allocator& basicAllocator)
729{
730 return basicAllocator.allocate(size);
731}
732
733inline
734void operator delete(void *address,
735 BloombergLP::bslma::Allocator& basicAllocator)
736{
737 basicAllocator.deallocate(address);
738}
739
740#endif
741
742// ----------------------------------------------------------------------------
743// Copyright 2013 Bloomberg Finance L.P.
744//
745// Licensed under the Apache License, Version 2.0 (the "License");
746// you may not use this file except in compliance with the License.
747// You may obtain a copy of the License at
748//
749// http://www.apache.org/licenses/LICENSE-2.0
750//
751// Unless required by applicable law or agreed to in writing, software
752// distributed under the License is distributed on an "AS IS" BASIS,
753// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
754// See the License for the specific language governing permissions and
755// limitations under the License.
756// ----------------------------- END-OF-FILE ----------------------------------
757
758/** @} */
759/** @} */
760/** @} */
Definition bslma_memoryresource.h:441
memory_resource() BSLS_KEYWORD_DEFAULT
Create this object. Has no effect other than to begin its lifetime.
Definition bslma_allocator.h:457
~Allocator() BSLS_KEYWORD_OVERRIDE
void * do_allocate(std::size_t bytes, std::size_t alignment) BSLS_KEYWORD_OVERRIDE
static void throwBadAlloc()
void deleteObjectRaw(const TYPE *object)
Definition bslma_allocator.h:694
virtual void deallocate(void *address)=0
bool do_is_equal(const memory_resource &other) const BSLS_KEYWORD_NOEXCEPT BSLS_KEYWORD_OVERRIDE
std::size_t size_type
Definition bslma_allocator.h:499
void deleteObject(const TYPE *object)
Definition bslma_allocator.h:680
virtual void * allocate(size_type size)=0
void do_deallocate(void *p, std::size_t bytes, std::size_t alignment) BSLS_KEYWORD_OVERRIDE
bslma::Allocator bslma_Allocator
Definition bslfwd_bslma_allocator.h:53
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_DELETED
Definition bsls_keyword.h:609
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition bdlb_printmethods.h:283
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:281
Definition balxml_encoderoptions.h:68
Definition bdldfp_decimal.h:5188
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