BDE 4.14.0 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. Note
404/// that when the length of this object is non-zero, it must refer to a
405/// non-null array of memory blocks.
406///
407/// See @ref bslma_autodeallocator
408template <class ALLOCATOR>
410
411 // DATA
412 void **d_origin_p; // reference location for the sequence of
413 // managed memory
414
415 int d_length; // number of memory blocks managed (sign
416 // encodes direction)
417
418 ALLOCATOR *d_allocator_p; // allocator or pool (held, not owned)
419
420 // NOT IMPLEMENTED
422 AutoDeallocator& operator=(const AutoDeallocator&);
423
424 private:
425 // PRIVATE MANIPULATORS
426
427 /// Deallocate the contiguous sequence of memory blocks managed by this
428 /// auto deallocator (if any) by invoking the `deallocate` method of the
429 /// allocator (or pool) supplied at construction on each memory block.
430 /// Note that the order in which the managed memory blocks are
431 /// deallocated is undefined. Also note that this method factors out
432 /// the deallocation logic, which allows the destructor to be declared
433 /// `inline` for the common case (the range proctor is released before
434 /// being destroyed).
435 void deallocate();
436
437 public:
438 // CREATORS
439
440 /// Create an auto deallocator to manage a sequence of memory blocks at
441 /// the specified `origin`, and that uses the specified `allocator` to
442 /// deallocate the sequence of memory blocks managed by this range
443 /// proctor (if not released -- see `release`) upon destruction.
444 /// Optionally specify `length` to define its range, which by default is
445 /// empty (i.e., `length = 0`). The sequence of memory blocks may
446 /// extend in either direction from `origin`. A positive `length`
447 /// represents the sequence of memory blocks starting at `origin` and
448 /// extending "up" to `length` (*not* including the memory block at the
449 /// index position `origin + length`). A negative `length` represents
450 /// the sequence of memory blocks starting at one position below
451 /// `origin` and extending "down" to the absolute value of `length`
452 /// (including the memory block at index position `origin + length`).
453 /// If `length` is 0, then this range proctor manages no memory blocks.
454 /// If `origin` is non-zero, all memory blocks within the proctored
455 /// range (if any) must be supplied by `allocator`. The behavior is
456 /// undefined unless `allocator` is non-zero, and, if `origin` is 0,
457 /// `length` is also 0. Note that when `length` is non-positive, the
458 /// memory block at the origin is *not* managed by this range proctor.
459 /// For example, if `origin` is at the index position 2, a `length` of 2
460 /// signifies that the memory blocks at positions 2 and 3 are managed,
461 /// whereas a `length` of -2 signifies that the memory blocks at
462 /// positions 0 and 1 are managed:
463 /// @code
464 /// length = -2 length = 2
465 /// |<----->| |<----->|
466 /// ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
467 /// | 0 | 1 | 2 | 3 | 4 | | 0 | 1 | 2 | 3 | 4 |
468 /// `===^===^===^===^===' `===^===^===^===^==='
469 /// ^------------ origin ^------------ origin
470 /// @endcode
471 template <class TYPE>
472 AutoDeallocator(TYPE **origin,
473 ALLOCATOR *allocator,
474 int length = 0);
475 AutoDeallocator(void **origin,
476 ALLOCATOR *allocator,
477 int length = 0);
478
479 /// Destroy this range proctor and deallocate the contiguous sequence of
480 /// memory blocks it manages (if any) by invoking the `deallocate`
481 /// method of the allocator (or pool) supplied at construction on each
482 /// memory block. Note that the order in which the managed memory
483 /// blocks are deallocated is undefined.
485
486 // MANIPULATORS
487
488 /// Increase by one the (signed) length of the sequence of memory blocks
489 /// managed by this range proctor. The behavior is undefined unless the
490 /// origin of the sequence of memory blocks managed by this proctor is
491 /// non-zero. The behavior is undefined unless the origin or this range
492 /// proctor is non-zero. Note that if the length of this proctor is
493 /// currently negative, the number of managed memory blocks will
494 /// decrease by one, whereas if the length is non-negative, the number
495 /// of managed memory blocks will increase by one.
496 void operator++();
497
498 /// Decrease by one the (signed) length of the sequence of memory blocks
499 /// managed by this range proctor. The behavior is undefined unless the
500 /// origin of the sequence of memory blocks managed by this proctor is
501 /// non-zero. The behavior is undefined unless the origin or this range
502 /// proctor is non-zero. Note that if the length of this proctor is
503 /// currently positive, the number of managed memory blocks will
504 /// decrease by one, whereas if the length is non-positive, the number
505 /// of managed memory blocks will increase by one.
506 void operator--();
507
508 /// Release from management the sequence of memory blocks currently
509 /// managed by this range proctor by setting the length of the managed
510 /// sequence to 0. All memory blocks currently under management will
511 /// become unmanaged (i.e., when the proctor goes out of scope and it
512 /// was not assigned another sequence of memory blocks to manage by
513 /// invoking `reset`, no memory blocks will be deallocated). If no
514 /// memory blocks are currently being managed, this method has no
515 /// effect. Note that the origin is not affected.
516 void release();
517
518 /// Set the specified `origin` as the origin of the sequence of memory
519 /// blocks to be managed by this range proctor. The behavior is
520 /// undefined unless `origin` is non-zero. Note that the length of the
521 /// sequence of memory blocks managed by this proctor is not affected,
522 /// and `setLength` should be invoked if the managed range is different
523 /// from the previously managed sequence of memory blocks. Also note
524 /// that this method releases any previously-managed memory blocks from
525 /// management (without deallocating them), and so may be called with or
526 /// without having called `release` when reusing this object.
527 template <class TYPE>
528 void reset(TYPE **origin);
529 void reset(void **origin);
530
531 /// Set the (signed) length of the sequence of memory blocks managed by
532 /// this range proctor to the specified `length`. The behavior is
533 /// undefined unless the origin of this range proctor is non-zero.
534 void setLength(int length);
535
536 // ACCESSORS
537
538 /// Return the (signed) length of the sequence of memory blocks managed
539 /// by this proctor.
540 int length() const;
541};
542
543// ============================================================================
544// INLINE DEFINITIONS
545// ============================================================================
546
547 // ---------------------
548 // class AutoDeallocator
549 // ---------------------
550
551// PRIVATE MANIPULATORS
552template <class ALLOCATOR>
554{
555 if (d_length > 0) {
556 for (; d_length > 0; --d_length, ++d_origin_p) {
557 d_allocator_p->deallocate(*d_origin_p);
558 }
559 }
560 else {
561 --d_origin_p;
562 for (; d_length < 0; ++d_length, --d_origin_p) {
563 d_allocator_p->deallocate(*d_origin_p);
564 }
565 }
566}
567
568// CREATORS
569template <class ALLOCATOR>
570template <class TYPE>
571inline
572AutoDeallocator<ALLOCATOR>
573::AutoDeallocator(TYPE **origin,
574 ALLOCATOR *allocator,
575 int length)
576: d_origin_p((void **)origin)
577, d_length(length)
578, d_allocator_p(allocator)
579{
580 BSLS_ASSERT_SAFE(allocator);
581 BSLS_ASSERT_SAFE(origin || !length);
582}
583
584template <class ALLOCATOR>
585inline
587::AutoDeallocator(void **origin,
588 ALLOCATOR *allocator,
589 int length)
590: d_origin_p(origin)
591, d_length(length)
592, d_allocator_p(allocator)
593{
594 BSLS_ASSERT_SAFE(allocator);
595 BSLS_ASSERT_SAFE(origin || !length);
596}
597
598template <class ALLOCATOR>
599inline
601{
602 BSLS_ASSERT_SAFE(d_origin_p || !d_length);
603
605 deallocate();
606 }
607}
608
609// MANIPULATORS
610template <class ALLOCATOR>
611inline
613{
614 BSLS_ASSERT_SAFE(d_origin_p);
615
616 ++d_length;
617}
618
619template <class ALLOCATOR>
620inline
622{
623 BSLS_ASSERT_SAFE(d_origin_p);
624
625 --d_length;
626}
627
628template <class ALLOCATOR>
629inline
631{
632 d_length = 0;
633}
634
635template <class ALLOCATOR>
636template <class TYPE>
637inline
639{
640 BSLS_ASSERT_SAFE(origin);
641
642 d_origin_p = static_cast<void **>(origin);
643}
644
645template <class ALLOCATOR>
646inline
648{
649 BSLS_ASSERT_SAFE(origin);
650
651 d_origin_p = origin;
652}
653
654template <class ALLOCATOR>
655inline
656void
658{
659 BSLS_ASSERT_SAFE(d_origin_p);
660
661 d_length = length;
662}
663
664// ACCESSORS
665template <class ALLOCATOR>
666inline
668{
669 return d_length;
670}
671
672} // close package namespace
673
674#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
675// ============================================================================
676// BACKWARD COMPATIBILITY
677// ============================================================================
678
679#ifdef bslma_AutoDeallocator
680#undef bslma_AutoDeallocator
681#endif
682/// This alias is defined for backward compatibility.
683#define bslma_AutoDeallocator bslma::AutoDeallocator
684#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
685
686
687
688#endif
689
690// ----------------------------------------------------------------------------
691// Copyright 2013 Bloomberg Finance L.P.
692//
693// Licensed under the Apache License, Version 2.0 (the "License");
694// you may not use this file except in compliance with the License.
695// You may obtain a copy of the License at
696//
697// http://www.apache.org/licenses/LICENSE-2.0
698//
699// Unless required by applicable law or agreed to in writing, software
700// distributed under the License is distributed on an "AS IS" BASIS,
701// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
702// See the License for the specific language governing permissions and
703// limitations under the License.
704// ----------------------------- END-OF-FILE ----------------------------------
705
706/** @} */
707/** @} */
708/** @} */
Definition bslma_autodeallocator.h:409
void release()
Definition bslma_autodeallocator.h:630
void setLength(int length)
Definition bslma_autodeallocator.h:657
~AutoDeallocator()
Definition bslma_autodeallocator.h:600
void reset(TYPE **origin)
Definition bslma_autodeallocator.h:638
void operator++()
Definition bslma_autodeallocator.h:612
void operator--()
Definition bslma_autodeallocator.h:621
int length() const
Definition bslma_autodeallocator.h:667
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition balxml_encoderoptions.h:68