BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslma_autodeallocator.h
Go to the documentation of this file.
1/// @file bslma_autodeallocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_autodeallocator.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_AUTODEALLOCATOR
9#define INCLUDED_BSLMA_AUTODEALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_autodeallocator bslma_autodeallocator
15/// @brief Provide a range proctor to managed a block of memory.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_autodeallocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_autodeallocator-purpose"> Purpose</a>
25/// * <a href="#bslma_autodeallocator-classes"> Classes </a>
26/// * <a href="#bslma_autodeallocator-description"> Description </a>
27/// * <a href="#bslma_autodeallocator-requirement"> Requirement </a>
28/// * <a href="#bslma_autodeallocator-usage"> Usage </a>
29///
30/// # Purpose {#bslma_autodeallocator-purpose}
31/// Provide a range proctor to managed a block of memory.
32///
33/// # Classes {#bslma_autodeallocator-classes}
34///
35/// - bslma::AutoDeallocator: range proctor to manage a block of memory
36///
37/// @see bslma_deallocatorguard, bslma_deallocatorproctor
38///
39/// # Description {#bslma_autodeallocator-description}
40/// This component provides a range proctor class template,
41/// `bslma::AutoDeallocator`, to manage a sequence of blocks of
42/// (otherwise-unmanaged) memory of parameterized `TYPE` supplied at
43/// construction. If not explicitly released, the sequence of managed memory
44/// blocks are deallocated automatically when the range proctor goes out of
45/// scope by freeing the memory using the parameterized `ALLOCATOR` (allocator
46/// or pool) supplied at construction. Note that after a range proctor releases
47/// its managed sequence of memory, the same proctor can be reused to
48/// conditionally manage another sequence of memory (allocated from the same
49/// allocator or pool that was supplied at construction) by invoking the `reset`
50/// method.
51///
52/// ## Requirement {#bslma_autodeallocator-requirement}
53///
54///
55/// The parameterized `ALLOCATOR` type of the `bslma::AutoRawDeleter` class
56/// template must provide a (possibly `virtual`) method:
57/// @code
58/// void deallocate(void *address);
59/// @endcode
60/// to deallocate memory at the specified `address` (originally supplied by the
61/// `ALLOCATOR` object).
62///
63/// ## Usage {#bslma_autodeallocator-usage}
64///
65///
66/// The `bslma::AutoDeallocator` proctor object can be used to achieve
67/// *exception* *safety* in an *exception* *neutral* way during manipulation of
68/// "out-of-place" arrays of raw resources or memory. Since there are no
69/// destructor calls, this component is more efficient compared to the
70/// `bslma::AutoRawDeleter`. The following illustrates the insertion operation
71/// for an "out-of-place" array of raw character sequences. Assume that an
72/// array initially contains 5 character sequences as its elements:
73/// @code
74/// 0 1 2 3 4
75/// _____ _____ _____ _____ _____
76/// | o | o | o | o | o |
77/// `==|==^==|==^==|==^==|==^==|=='
78/// | _V___ | __V___ |
79/// | |"Bye"| | |"berg"| |
80/// | `=====' | `======' |
81/// _V_____ _V_____ _V__
82/// |"Hello"| |"Bloom"| |"LP"|
83/// `=======' `=======' `===='
84/// @endcode
85/// To insert two more character sequences at index position 2, the array is
86/// first reallocated if it is not big enough, and then the existing elements at
87/// index positions 2, 3, and 4 are shifted:
88/// @code
89/// 0 1 2 3 4 5 6
90/// _____ _____ _____ _____ _____ _____ _____
91/// | o | o |xxxxx|xxxxx| o | o | o |
92/// `==|==^==|==^=====^=====^==|==^==|==^==|=='
93/// | _V___ | __V___ |
94/// | |"Bye"| | |"berg"| |
95/// | `=====' | `======' |
96/// _V_____ _V_____ _V__
97/// |"Hello"| |"Bloom"| |"LP"|
98/// `=======' `=======' `===='
99///
100/// Note: "xxxxx" denotes undefined value.
101/// @endcode
102/// Next, two new memory blocks must be allocated to position 2 and 3. If, one
103/// of the two allocations fails and an exception is thrown, the array will be
104/// left in an invalid state because the addresses contained at index positions
105/// 2 and 3 may be duplicates of those at index positions 4 and 5, or, if a
106/// resize occurred, invalid altogether. We can restore exception neutrality by
107/// setting the array's length to 2 before attempting to create the string
108/// objects, but there is still a problem: the character sequences "Bloom",
109/// "berg", and "LP" (at index positions 4, 5, and 6) are "orphaned" and will
110/// never be deallocated -- a memory leak. To prevent this potential memory
111/// leak, we can additionally create a `bslma::AutoDeallocator` object to manage
112/// (temporarily) the memory at index positions 4, 5, and 6 prior to allocating
113/// the new memory:
114/// @code
115/// 0 1 2 3 4 5 6
116/// _____ _____ _____ _____ _____ _____ _____
117/// | o | o |xxxxx|xxxxx| o | o | o |
118/// `==|==^==|==^=====^=====^==|==^==|==^==|=='
119/// | _V___ | __V___ |
120/// | |"Bye"| | |"berg"| |
121/// | `=====' | `======' |
122/// _V_____ _V_____ _V__
123/// |"Hello"| |"Bloom"| |"LP"|
124/// `=======' `=======' `===='
125/// my_StrArray ^---------------bslma::AutoDeallocator
126/// (length = 2) (origin = 4, length = 3)
127///
128/// Note: Configuration after initializing the proctor.
129/// @endcode
130/// If an exception occurs, the array (now of length 2) is in a perfectly valid
131/// state, while the proctor is responsible for deallocating the orphaned memory
132/// at index positions 4, 5, and 6. If no exception is thrown, the length is
133/// set to 7 and the proctor's `release` method is called, releasing its control
134/// over the (temporarily) managed memory.
135///
136/// The following example illustrates the use of `bslma::AutoDeallocator` to
137/// manage temporarily an "out-of-place" array of character sequences during the
138/// array's insertion operation.
139///
140/// First we define a `my_StrArray` class that stores an array of character
141/// sequences.
142/// @code
143/// // my_strarray.h
144/// // ...
145///
146/// /// This class is a container that stores an array of character
147/// /// sequences. Memory will be supplied by the parameterized `ALLOCATOR`
148/// /// type provided at construction (which must remain valid throughout
149/// /// the lifetime of this guard object). Note that memory is managed by
150/// /// a parameterized `ALLOCATOR` type, instead of a `bslma::Allocator`,
151/// /// to enable clients to pass in a pool (such as a sequential pool)
152/// /// optimized for allocations of character sequences.
153/// template <class ALLOCATOR>
154/// class my_StrArray {
155///
156/// // DATA
157/// char **d_array_p; // dynamically allocated array of character
158/// // sequence
159///
160/// int d_length; // logical length of this array
161///
162/// int d_size; // physical capacity of this array
163///
164/// ALLOCATOR *d_allocator_p; // allocator or pool (held, not owned)
165///
166/// public:
167/// // CREATORS
168///
169/// /// Create a `my_StrArray` object using the specified
170/// /// `basicAllocator` used to supply memory.
171/// my_StrArray(ALLOCATOR *basicAllocator);
172///
173/// /// Destroy this `my_StrArray` object and all elements currently
174/// /// stored.
175/// ~my_StrArray();
176///
177/// // MANIPULATORS
178///
179/// /// Append to this array the string `src`.
180/// void append(const char *src);
181///
182/// /// Insert into this array at the specified `dstIndex`, the
183/// /// character sequences in the specified `srcArray`. All values
184/// /// with initial indices at or above `dstIndex` are shifted up by
185/// /// unless `0 <= dstIndex` and `dstIndex <= length()`. Note that
186/// /// this method is functionally the same as `insert2`, but has a
187/// /// different implementation to facilitate the usage example.
188/// void insert(int dstIndex, const my_StrArray& srcArray);
189///
190/// /// Insert into this array at the specified `dstIndex`, the
191/// /// character sequences in the specified `srcArray`. All values
192/// /// with initial indices at or above `dstIndex` are shifted up by
193/// /// unless `0 <= dstIndex` and `dstIndex <= length()`. Note that
194/// /// this method is functionally the same as `insert`, but has a
195/// /// different implementation to facilitate the usage example.
196/// void insert2(int dstIndex, const my_StrArray& srcArray);
197///
198/// // ...
199///
200/// // ACCESSORS
201///
202/// /// Return the logical length of this array.
203/// int length() const;
204///
205/// /// Return a pointer to the 'index'th string in the array. Note
206/// /// the pointer is returned by value, it is not a reference to a
207/// /// pointer.
208/// const char *operator[](int index) const;
209///
210/// // ...
211/// };
212/// @endcode
213/// Next, we define the `insert` method of `my_StrArray`:
214/// @code
215/// template <class ALLOCATOR>
216/// void my_StrArray<ALLOCATOR>::insert(int dstIndex,
217/// const my_StrArray<ALLOCATOR>& srcArray)
218/// {
219/// int srcLength = srcArray.d_length;
220/// int newLength = d_length + srcLength;
221/// int numShifted = d_length - dstIndex;
222///
223/// if (newLength > d_size) {
224/// while (d_size < newLength) {
225/// d_size = ! d_size ? 1 : 2 * d_size;
226/// }
227///
228/// char ** newArray =
229/// (char **) d_allocator_p->allocate(d_size * sizeof(char *));
230/// memcpy(newArray, d_array_p, d_length * sizeof(char *));
231/// if (d_array_p) {
232/// d_allocator_p->deallocate(d_array_p);
233/// }
234/// d_array_p = newArray;
235/// }
236///
237/// char **tmpSrc = srcArray.d_array_p;
238/// if (this == &srcArray) {
239/// // self-alias
240/// size_t size = srcLength * sizeof(char *);
241/// tmpSrc = (char **) d_allocator_p->allocate(size);
242/// memcpy(tmpSrc, d_array_p, size);
243/// }
244/// bslma::DeallocatorProctor<ALLOCATOR> proctor(
245/// this == &srcArray ? tmpSrc : 0,
246/// d_allocator_p);
247///
248/// // First shift the elements to the back of the array.
249/// memmove(d_array_p + dstIndex + srcLength,
250/// d_array_p + dstIndex,
251/// numShifted * sizeof *d_array_p);
252///
253/// // Shorten 'd_length' and use 'bslma::AutoDeallocator' to proctor the
254/// // memory shifted.
255/// d_length = dstIndex;
256///
257/// //*******************************************************
258/// // Note use of auto deallocator on tail memory (below). *
259/// //*******************************************************
260///
261/// bslma::AutoDeallocator<ALLOCATOR> tailDeallocator(
262/// (void **) d_array_p + dstIndex + srcLength,
263/// d_allocator_p,
264/// numShifted);
265/// @endcode
266/// Now, if any allocation for the inserted character sequences throws, the
267/// memory used for the character sequences that had been moved to the end of
268/// array will be deallocated automatically by the `bslma::AutoDeallocator`.
269/// @code
270/// // Copy the character sequences from the 'srcArray'.
271/// for (int i = 0; i < srcLength; ++i, ++d_length) {
272/// std::size_t size = std::strlen(tmpSrc[i]) + 1;
273/// d_array_p[dstIndex + i] = (char *) d_allocator_p->allocate(size);
274/// memcpy(d_array_p[dstIndex + i], tmpSrc[i], size);
275/// }
276///
277/// //*********************************************
278/// // Note that the proctor is released (below). *
279/// //*********************************************
280///
281/// tailDeallocator.release();
282/// d_length = newLength;
283/// }
284/// @endcode
285/// The above method copies the source elements (visually) from left to right.
286/// Another (functionally equivalent) implementation copies the source elements
287/// from right to left, and makes use of the `operator--()` of the
288/// `bslma::AutoDeallocator` interface:
289/// @code
290/// template <class ALLOCATOR>
291/// void my_StrArray<ALLOCATOR>::insert2(int dstIndex,
292/// const my_StrArray<ALLOCATOR>& srcArray)
293/// {
294/// int srcLength = srcArray.d_length;
295/// int newLength = d_length + srcLength;
296/// int numShifted = d_length - dstIndex;
297///
298/// if (newLength > d_size) {
299/// while (d_size < newLength) {
300/// d_size = ! d_size ? 1 : 2 * d_size;
301/// }
302///
303/// char ** newArray =
304/// (char **) d_allocator_p->allocate(d_size * sizeof(char *));
305/// memcpy(newArray, d_array_p, d_length * sizeof(char *));
306/// if (d_array_p) {
307/// d_allocator_p->deallocate(d_array_p);
308/// }
309/// d_array_p = newArray;
310/// }
311///
312/// char **tmpSrc = srcArray.d_array_p;
313/// if (this == &srcArray) {
314/// // self-alias
315/// size_t size = srcLength * sizeof(char *);
316/// tmpSrc = (char **) d_allocator_p->allocate(size);
317/// memcpy(tmpSrc, d_array_p, size);
318/// }
319/// bslma::DeallocatorProctor<ALLOCATOR> proctor(
320/// this == &srcArray ? tmpSrc : 0,
321/// d_allocator_p);
322///
323/// // First shift the elements to the back of the array.
324/// memmove(d_array_p + dstIndex + srcLength,
325/// d_array_p + dstIndex,
326/// numShifted * sizeof *d_array_p);
327///
328/// // Shorten 'd_length' and use 'bslma::AutoDeallocator' to proctor the
329/// // memory shifted.
330/// d_length = dstIndex;
331///
332/// //********************************************
333/// //* Note the use of auto deallocator on tail *
334/// //* memory with negative length (below). *
335/// //********************************************
336///
337/// bslma::AutoDeallocator<ALLOCATOR> tailDeallocator(
338/// (void **) d_array_p + d_length + srcLength + numShifted,
339/// d_allocator_p,
340/// -numShifted);
341/// @endcode
342/// Since we have decided to copy the source elements from right to left, we set
343/// the origin of the `bslma::AutoDeallocator` to the end of the array, and
344/// decrement the (signed) length on each copy to extend the proctor range by 1.
345/// @code
346/// // Copy the character sequences from the 'srcArray'. Note that the
347/// // 'tailDeallocator' has to be decremented to cover the newly
348/// // created object.
349///
350/// for (int i = srcLength - 1; i >= 0; --i, --tailDeallocator) {
351/// std::size_t size = std::strlen(tmpSrc[i]) + 1;
352/// d_array_p[dstIndex + i] = (char *)d_allocator_p->allocate(size);
353/// memcpy(d_array_p[dstIndex + i], tmpSrc[i], size);
354/// }
355///
356/// //*********************************************
357/// // Note that the proctor is released (below). *
358/// //*********************************************
359///
360/// tailDeallocator.release();
361/// d_length = newLength;
362/// }
363/// @endcode
364/// Note that though the two implementations are functionally equivalent, they
365/// are logically different. First of all, the second implementation will be
366/// slightly slower because it is accessing memory backwards when compared to
367/// the normal forward sequential access. Secondly, in case of an exception,
368/// the first implementation will retain all the elements copied prior to the
369/// exception, whereas the second implementation will remove them.
370/// @}
371/** @} */
372/** @} */
373
374/** @addtogroup bsl
375 * @{
376 */
377/** @addtogroup bslma
378 * @{
379 */
380/** @addtogroup bslma_autodeallocator
381 * @{
382 */
383
384#include <bslscm_version.h>
385
386#include <bsls_assert.h>
387#include <bsls_performancehint.h>
388
389
390
391namespace bslma {
392
393 // =====================
394 // class AutoDeallocator
395 // =====================
396
397/// This class implements a range proctor that, unless its `release` method
398/// has previously been invoked, automatically deallocates the contiguous
399/// sequence of managed memory blocks upon its own destruction by invoking
400/// the `deallocate` method of an allocator (or pool) of parameterized
401/// `ALLOCATOR` type supplied to it at construction. Each of the managed
402/// memory blocks must have been supplied by this allocator (or pool), which
403/// must remain valid throughout the lifetime of the range proctor.
404///
405/// \note Note that when the length of this object is non-zero, it must refer to a
406/// non-null array of memory blocks.
407///
408/// See @ref bslma_autodeallocator
409template <class ALLOCATOR>
411
412 // DATA
413 void **d_origin_p; // reference location for the sequence of
414 // managed memory
415
416 int d_length; // number of memory blocks managed (sign
417 // encodes direction)
418
419 ALLOCATOR *d_allocator_p; // allocator or pool (held, not owned)
420
421 private:
422 // NOT IMPLEMENTED
424 AutoDeallocator& operator=(const AutoDeallocator&);
425
426 private:
427 // PRIVATE MANIPULATORS
428
429 /// Deallocate the contiguous sequence of memory blocks managed by this
430 /// auto deallocator (if any) by invoking the `deallocate` method of the
431 /// allocator (or pool) supplied at construction on each memory block.
432 ///
433 /// \note Note that the order in which the managed memory blocks are
434 /// deallocated is undefined. Also note that this method factors out
435 /// the deallocation logic, which allows the destructor to be declared
436 /// `inline` for the common case (the range proctor is released before
437 /// being destroyed).
438 void deallocate();
439
440 public:
441 // CREATORS
442
443 /// Create an auto deallocator to manage a sequence of memory blocks at
444 /// the specified `origin`, and that uses the specified `allocator` to
445 /// deallocate the sequence of memory blocks managed by this range
446 /// proctor (if not released -- see `release`) upon destruction.
447 /// Optionally specify `length` to define its range, which by default is
448 /// empty (i.e., `length = 0`). The sequence of memory blocks may
449 /// extend in either direction from `origin`. A positive `length`
450 /// represents the sequence of memory blocks starting at `origin` and
451 /// extending "up" to `length` (*not* including the memory block at the
452 /// index position `origin + length`). A negative `length` represents
453 /// the sequence of memory blocks starting at one position below
454 /// `origin` and extending "down" to the absolute value of `length`
455 /// (including the memory block at index position `origin + length`).
456 /// If `length` is 0, then this range proctor manages no memory blocks.
457 /// If `origin` is non-zero, all memory blocks within the proctored
458 /// range (if any) must be supplied by `allocator`.
459 ///
460 /// \pre The behavior is undefined unless `allocator` is non-zero, and, if `origin` is 0, `length` is also 0.
461 ///
462 /// \note Note that when `length` is non-positive, the
463 /// memory block at the origin is *not* managed by this range proctor.
464 /// For example, if `origin` is at the index position 2, a `length` of 2
465 /// signifies that the memory blocks at positions 2 and 3 are managed,
466 /// whereas a `length` of -2 signifies that the memory blocks at
467 /// positions 0 and 1 are managed:
468 /// @code
469 /// length = -2 length = 2
470 /// |<----->| |<----->|
471 /// ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
472 /// | 0 | 1 | 2 | 3 | 4 | | 0 | 1 | 2 | 3 | 4 |
473 /// `===^===^===^===^===' `===^===^===^===^==='
474 /// ^------------ origin ^------------ origin
475 /// @endcode
476 template <class TYPE>
477 AutoDeallocator(TYPE **origin,
478 ALLOCATOR *allocator,
479 int length = 0);
480 AutoDeallocator(void **origin,
481 ALLOCATOR *allocator,
482 int length = 0);
483
484 /// Destroy this range proctor and deallocate the contiguous sequence of
485 /// memory blocks it manages (if any) by invoking the `deallocate`
486 /// method of the allocator (or pool) supplied at construction on each memory block.
487 ///
488 /// \note Note that the order in which the managed memory
489 /// blocks are deallocated is undefined.
491
492 // MANIPULATORS
493
494 /// Increase by one the (signed) length of the sequence of memory blocks managed by this range proctor.
495 ///
496 /// \pre The behavior is undefined unless the
497 /// origin of the sequence of memory blocks managed by this proctor is non-zero.
498 ///
499 /// \pre The behavior is undefined unless the origin or this range proctor is non-zero.
500 ///
501 /// \note Note that if the length of this proctor is
502 /// currently negative, the number of managed memory blocks will
503 /// decrease by one, whereas if the length is non-negative, the number
504 /// of managed memory blocks will increase by one.
505 void operator++();
506
507 /// Decrease by one the (signed) length of the sequence of memory blocks managed by this range proctor.
508 ///
509 /// \pre The behavior is undefined unless the
510 /// origin of the sequence of memory blocks managed by this proctor is non-zero.
511 ///
512 /// \pre The behavior is undefined unless the origin or this range proctor is non-zero.
513 ///
514 /// \note Note that if the length of this proctor is
515 /// currently positive, the number of managed memory blocks will
516 /// decrease by one, whereas if the length is non-positive, the number
517 /// of managed memory blocks will increase by one.
518 void operator--();
519
520 /// Release from management the sequence of memory blocks currently
521 /// managed by this range proctor by setting the length of the managed
522 /// sequence to 0. All memory blocks currently under management will
523 /// become unmanaged (i.e., when the proctor goes out of scope and it
524 /// was not assigned another sequence of memory blocks to manage by
525 /// invoking `reset`, no memory blocks will be deallocated). If no
526 /// memory blocks are currently being managed, this method has no effect.
527 ///
528 /// \note Note that the origin is not affected.
529 void release();
530
531 /// Set the specified `origin` as the origin of the sequence of memory
532 /// blocks to be managed by this range proctor.
533 ///
534 /// \pre The behavior is undefined unless `origin` is non-zero.
535 /// \note Note that the length of the
536 /// sequence of memory blocks managed by this proctor is not affected,
537 /// and `setLength` should be invoked if the managed range is different
538 /// from the previously managed sequence of memory blocks. Also note
539 /// that this method releases any previously-managed memory blocks from
540 /// management (without deallocating them), and so may be called with or
541 /// without having called `release` when reusing this object.
542 template <class TYPE>
543 void reset(TYPE **origin);
544 void reset(void **origin);
545
546 /// Set the (signed) length of the sequence of memory blocks managed by
547 /// this range proctor to the specified `length`.
548 ///
549 /// \pre The behavior is undefined unless the origin of this range proctor is non-zero.
550 void setLength(int length);
551
552 // ACCESSORS
553
554 /// Return the (signed) length of the sequence of memory blocks managed
555 /// by this proctor.
556 int length() const;
557};
558
559// ============================================================================
560// INLINE DEFINITIONS
561// ============================================================================
562
563 // ---------------------
564 // class AutoDeallocator
565 // ---------------------
566
567// PRIVATE MANIPULATORS
568template <class ALLOCATOR>
570{
571 if (d_length > 0) {
572 for (; d_length > 0; --d_length, ++d_origin_p) {
573 d_allocator_p->deallocate(*d_origin_p);
574 }
575 }
576 else {
577 --d_origin_p;
578 for (; d_length < 0; ++d_length, --d_origin_p) {
579 d_allocator_p->deallocate(*d_origin_p);
580 }
581 }
582}
583
584// CREATORS
585template <class ALLOCATOR>
586template <class TYPE>
587inline
588AutoDeallocator<ALLOCATOR>
589::AutoDeallocator(TYPE **origin,
590 ALLOCATOR *allocator,
591 int length)
592: d_origin_p((void **)origin)
593, d_length(length)
594, d_allocator_p(allocator)
595{
596 BSLS_ASSERT_SAFE(allocator);
597 BSLS_ASSERT_SAFE(origin || !length);
598}
599
600template <class ALLOCATOR>
601inline
603::AutoDeallocator(void **origin,
604 ALLOCATOR *allocator,
605 int length)
606: d_origin_p(origin)
607, d_length(length)
608, d_allocator_p(allocator)
609{
610 BSLS_ASSERT_SAFE(allocator);
611 BSLS_ASSERT_SAFE(origin || !length);
612}
613
614template <class ALLOCATOR>
615inline
617{
618 BSLS_ASSERT_SAFE(d_origin_p || !d_length);
619
621 deallocate();
622 }
623}
624
625// MANIPULATORS
626template <class ALLOCATOR>
627inline
629{
630 BSLS_ASSERT_SAFE(d_origin_p);
631
632 ++d_length;
633}
634
635template <class ALLOCATOR>
636inline
638{
639 BSLS_ASSERT_SAFE(d_origin_p);
640
641 --d_length;
642}
643
644template <class ALLOCATOR>
645inline
647{
648 d_length = 0;
649}
650
651template <class ALLOCATOR>
652template <class TYPE>
653inline
655{
656 BSLS_ASSERT_SAFE(origin);
657
658 d_origin_p = static_cast<void **>(origin);
659}
660
661template <class ALLOCATOR>
662inline
664{
665 BSLS_ASSERT_SAFE(origin);
666
667 d_origin_p = origin;
668}
669
670template <class ALLOCATOR>
671inline
672void
674{
675 BSLS_ASSERT_SAFE(d_origin_p);
676
677 d_length = length;
678}
679
680// ACCESSORS
681template <class ALLOCATOR>
682inline
684{
685 return d_length;
686}
687
688} // close package namespace
689
690#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
691// ============================================================================
692// BACKWARD COMPATIBILITY
693// ============================================================================
694
695#ifdef bslma_AutoDeallocator
696#undef bslma_AutoDeallocator
697#endif
698/// This alias is defined for backward compatibility.
699#define bslma_AutoDeallocator bslma::AutoDeallocator
700#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
701
702
703
704#endif
705
706// ----------------------------------------------------------------------------
707// Copyright 2013 Bloomberg Finance L.P.
708//
709// Licensed under the Apache License, Version 2.0 (the "License");
710// you may not use this file except in compliance with the License.
711// You may obtain a copy of the License at
712//
713// http://www.apache.org/licenses/LICENSE-2.0
714//
715// Unless required by applicable law or agreed to in writing, software
716// distributed under the License is distributed on an "AS IS" BASIS,
717// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
718// See the License for the specific language governing permissions and
719// limitations under the License.
720// ----------------------------- END-OF-FILE ----------------------------------
721
722/** @} */
723/** @} */
724/** @} */
Definition bslma_autodeallocator.h:410
void release()
Definition bslma_autodeallocator.h:646
void setLength(int length)
Definition bslma_autodeallocator.h:673
~AutoDeallocator()
Definition bslma_autodeallocator.h:616
void reset(TYPE **origin)
Definition bslma_autodeallocator.h:654
void operator++()
Definition bslma_autodeallocator.h:628
void operator--()
Definition bslma_autodeallocator.h:637
int length() const
Definition bslma_autodeallocator.h:683
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition baljsn_encoder_testtypes.h:76