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