BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_testallocator.h
Go to the documentation of this file.
1/// @file bslma_testallocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_testallocator.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_TESTALLOCATOR
9#define INCLUDED_BSLMA_TESTALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_testallocator bslma_testallocator
15/// @brief Provide instrumented malloc/free allocator to track memory usage.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_testallocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_testallocator-purpose"> Purpose</a>
25/// * <a href="#bslma_testallocator-classes"> Classes </a>
26/// * <a href="#bslma_testallocator-macros"> Macros </a>
27/// * <a href="#bslma_testallocator-description"> Description </a>
28/// * <a href="#bslma_testallocator-detecting-memory-leaks"> Detecting Memory Leaks </a>
29/// * <a href="#bslma_testallocator-modes"> Modes </a>
30/// * <a href="#bslma_testallocator-allocation-limit"> Allocation Limit </a>
31/// * <a href="#bslma_testallocator-exception-test-macros"> Exception Test Macros </a>
32/// * <a href="#bslma_testallocator-thread-safety"> Thread Safety </a>
33/// * <a href="#bslma_testallocator-usage"> Usage </a>
34///
35/// # Purpose {#bslma_testallocator-purpose}
36/// Provide instrumented malloc/free allocator to track memory usage.
37///
38/// # Classes {#bslma_testallocator-classes}
39///
40/// - bslma::TestAllocator: instrumented `malloc`/`free` memory allocator
41///
42/// # Macros {#bslma_testallocator-macros}
43///
44/// - BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN: macro to begin testing exceptions
45/// - BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END: macro to end testing exceptions
46///
47/// @see bslma_newdeleteallocator, bslma_mallocfreeallocator,
48/// balst_stacktracetestallocator
49///
50/// # Description {#bslma_testallocator-description}
51/// This component provides an instrumented allocator,
52/// `bslma::TestAllocator`, that implements the `bslma::Allocator` protocol and
53/// can be used to track various aspects of memory allocated from it. Available
54/// statistics include the number of outstanding blocks (and bytes) that are
55/// currently in use, the cumulative number of blocks (and bytes) that have been
56/// allocated, and the maximum number of blocks (and bytes) that have been in
57/// use at any one time. A `print` function formats these values to `stdout`:
58/// @code
59/// ,--------------------.
60/// ( bslma::TestAllocator )
61/// `--------------------'
62/// | ctor/dtor
63/// | lastAllocatedAddress/lastDeallocatedAddress
64/// | lastAllocatedNumBytes/lastDeallocatedNumBytes
65/// | numAllocations/numDeallocations
66/// | numBlocksInUse/numBlocksMax/numBlocksTotal
67/// | numBytesInUse/numBytesMax/numBytesTotal
68/// | numMismatches/numBoundsErrors
69/// | print/name
70/// | setAllocationLimit/allocationLimit
71/// | setNoAbort/isNoAbort
72/// | setQuiet/isQuiet
73/// | setVerbose/isVerbose
74/// | status
75/// V
76/// ,----------------.
77/// ( bslma::Allocator )
78/// `----------------'
79/// allocate
80/// deallocate
81/// @endcode
82/// If exceptions are enabled, this allocator can be configured to throw an
83/// exception after the number of allocation requests exceeds some specified
84/// limit (see the subsection on "Allocation Limit" below). The level of
85/// verbosity can also be adjusted. Each allocator object also maintains a
86/// current status.
87///
88/// By default this allocator gets its memory from the C Standard Library
89/// functions `malloc` and `free`, but can be overridden to take memory from any
90/// allocator (supplied at construction) that implements the `bslma::Allocator`
91/// protocol. Note that allocation and deallocation using a
92/// `bslma::TestAllocator` object is explicitly incompatible with `malloc` and
93/// `free` (or any other allocation mechanism). Attempting to use `free` to
94/// deallocate memory allocated from a `bslma::TestAllocator` -- even when
95/// `malloc` and `free` are used by default -- will result in undefined
96/// behavior, almost certainly corrupting the C Standard Library's runtime
97/// memory manager.
98///
99/// Memory dispensed from a `bslma::TestAllocator` is marked such that
100/// attempting to deallocate previously unallocated (or already deallocated)
101/// memory will (with high probability) be flagged as an error (unless quiet
102/// mode is set for the purpose of testing the test allocator itself). A
103/// `bslma::TestAllocator` also supports a buffer overrun / underrun feature --
104/// each allocation has "pads", areas of extra memory before and after the
105/// segment that are initialized to a particular value and checked upon
106/// deallocation to see if they have been modified. If they have, a message is
107/// printed and the allocator aborts, unless it is in quiet mode.
108///
109/// ## Detecting Memory Leaks {#bslma_testallocator-detecting-memory-leaks}
110///
111///
112/// The `bslma::TestAllocator` is useful for detecting memory leaks, unless
113/// configured in quiet mode. With the default configuration, if a test
114/// allocator is destroyed before all memory is reclaimed, a report will be
115/// logged and `abort` will be called. When such a memory leak is detected,
116/// clients can substitute `balst::StackTraceTestAllocator` for
117/// `bslma::TestAllocator` to report stack traces of allocations that were
118/// leaked. Note that `balst::StackTraceTestAllocator` is slower and consumes
119/// more memory than `bslma::TestAllocator`, and usually is not appropriate for
120/// automated tests.
121///
122/// ## Modes {#bslma_testallocator-modes}
123///
124///
125/// The test allocator's behavior is controlled by three basic *mode* flags:
126///
127/// VERBOSE MODE: (Default 0) Specifies that each allocation and deallocation
128/// should be printed to standard output. In verbose mode all state variables
129/// will be displayed at destruction.
130///
131/// QUIET MODE: (Default 0) Specifies that mismatched memory and memory leaks
132/// should *not* be reported, and should not cause the process to terminate when
133/// detected. Note that this mode is used primarily for testing the test
134/// allocator itself; behavior that would otherwise abort now quietly increments
135/// the `numMismatches` and `numBoundsErrors` counter.
136///
137/// NO-ABORT MODE: (Default 0) Specifies that the test allocator should not
138/// invoke `abort` under any circumstances without suppressing diagnostics.
139/// Although the internal state values are independent, quiet mode implies the
140/// behavior of no-abort mode in all cases. Note that this mode is used
141/// primarily for visual inspection of unusual error diagnostics in this
142/// component's test driver (in non-quiet mode only).
143///
144/// Taking the default mode settings, memory allocation/deallocation will not be
145/// displayed individually. However, in the event of a mismatched deallocation
146/// or a memory leak detected at destruction, the problem will be announced, any
147/// relevant state of the object will be displayed, and the program will abort.
148///
149/// The three modes are independently set using the `setVerbose`, `setQuiet`,
150/// and `setNoAbort` manipulators.
151///
152/// ## Allocation Limit {#bslma_testallocator-allocation-limit}
153///
154///
155/// If exceptions are enabled at compile time, the test allocator can be
156/// configured to throw a `bslma::TestAllocatorException` after a specified
157/// number of allocation requests is exceeded. If the allocation limit is less
158/// than 0 (default), then the allocator won't throw a `TestAllocatorException`
159/// exception. Note that a non-negative allocation limit is decremented after
160/// each allocation attempt, and an exception is thrown only when the current
161/// allocation limit transitions from 0 to -1; no additional exceptions will be
162/// thrown until the allocation limit is again reset to a non-negative value.
163///
164/// The allocation limit is set using the `setAllocationLimit` manipulator.
165///
166/// ## Exception Test Macros {#bslma_testallocator-exception-test-macros}
167///
168///
169/// This component also provides a pair of macros:
170///
171/// * `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(BSLMA_TESTALLOCATOR)`
172/// * `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END`
173///
174/// These macros can be used for testing exception-safety of classes and their
175/// methods when memory allocation is needed. A reference to an object of type
176/// `bslma::TestAllocator` must be supplied as an argument to the `_BEGIN`
177/// macro. Note that if exception-handling is disabled (i.e., if
178/// `BDE_BUILD_TARGET_EXC` is not defined when building the code under test),
179/// then the macros simply print the following:
180/// @code
181/// BSLMA EXCEPTION TEST -- (NOT ENABLED) --
182/// @endcode
183/// When exception-handling is enabled, the `_BEGIN` macro will set the
184/// allocation limit of the supplied allocator to 0, `try` the code being
185/// tested, `catch` any `TestAllocatorException`s that are thrown, and keep
186/// increasing the allocation limit until the code being tested completes
187/// successfully.
188///
189/// ## Thread Safety {#bslma_testallocator-thread-safety}
190///
191///
192/// The `bslma::TestAllocator` class is fully thread-safe (see
193/// @ref bsldoc_glossary ). Note that the `bslma::MallocFreeAllocator` singleton
194/// (the allocator used by the test allocator if none is supplied at
195/// construction) is fully thread-safe.
196///
197/// ## Usage {#bslma_testallocator-usage}
198///
199///
200/// The `bslma::TestAllocator` defined in this component can be used in
201/// conjunction with the `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN` and
202/// `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END` macros to test the memory usage
203/// patterns of an object that uses the `bslma::Allocator` protocol in its
204/// interface. In this example, we illustrate how we might test that an object
205/// under test is exception-neutral. For illustration purposes, we will assume
206/// the existence of a `my_shortarray` component implementing an
207/// `std::vector`-like array type, `myShortArray`:
208/// @code
209/// // my_shortarray.t.cpp
210/// #include <my_shortarray.h>
211///
212/// #include <bslma_testallocator.h>
213/// #include <bslma_testallocatorexception.h>
214///
215/// // ...
216/// @endcode
217/// Below we provide a `static` function, `areEqual`, that will allow us to
218/// compare two short arrays:
219/// @code
220/// static
221/// bool areEqual(const short *array1, const short *array2, int numElements)
222/// // Return 'true' if the specified initial 'numElements' in the
223/// // specified 'array1' and 'array2' have the same values, and 'false'
224/// // otherwise.
225/// {
226/// for (int i = 0; i < numElements; ++i) {
227/// if (array1[i] != array2[i]) {
228/// return false; // RETURN
229/// }
230/// }
231/// return true;
232/// }
233///
234/// // ...
235/// @endcode
236/// The following is an abbreviated standard test driver. Note that the number
237/// of arguments specify the verbosity level that the test driver uses for
238/// printing messages:
239/// @code
240/// int main(int argc, char *argv[])
241/// {
242/// int test = argc > 1 ? atoi(argv[1]) : 0;
243/// bool verbose = argc > 2;
244/// bool veryVerbose = argc > 3;
245/// bool veryVeryVerbose = argc > 4;
246/// bool veryVeryVeryVerbose = argc > 5;
247/// @endcode
248/// We now define a `bslma::TestAllocator`, `sa`, named "supplied" to indicate
249/// that it is the allocator to be supplied to our object under test, as well as
250/// to the `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN` macro (below). Note that
251/// if `veryVeryVeryVerbose` is `true`, then `sa` prints all allocation and
252/// deallocation requests to `stdout` and also prints the accumulated statistics
253/// on destruction:
254/// @code
255/// bslma::TestAllocator sa("supplied", veryVeryVeryVerbose);
256///
257/// switch (test) { case 0:
258///
259/// // ...
260///
261/// case 6: {
262///
263/// // ...
264///
265/// struct {
266/// int d_line;
267/// int d_numElem;
268/// short d_exp[NUM_VALUES];
269/// } DATA[] = {
270/// { L_, 0, { } },
271/// { L_, 1, { V0 } },
272/// { L_, 5, { V0, V1, V2, V3, V4 } }
273/// };
274/// const int NUM_DATA = sizeof DATA / sizeof *DATA;
275///
276/// for (int ti = 0; ti < NUM_DATA; ++ti) {
277/// const int LINE = DATA[ti].d_line;
278/// const int NUM_ELEM = DATA[ti].d_numElem;
279/// const short *EXP = DATA[ti].d_exp;
280///
281/// if (veryVerbose) { T_ P_(ti) P_(NUM_ELEM) }
282///
283/// // ...
284/// @endcode
285/// All code that we want to test for exception-safety must be enclosed within
286/// the `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN` and
287/// `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END` macros, which internally implement
288/// a `do`-`while` loop. Code provided by the
289/// `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN` macro sets the allocation limit
290/// of the supplied allocator to 0 causing it to throw an exception on the first
291/// allocation. This exception is caught by code provided by the
292/// `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END` macro, which increments the
293/// allocation limit by 1 and re-runs the same code again. Using this scheme we
294/// can check that our code does not leak memory for any memory allocation
295/// request. Note that the curly braces surrounding these macros, although
296/// visually appealing, are not technically required:
297/// @code
298/// BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(sa) {
299/// my_ShortArray mA(&sa);
300/// const my_ShortArray& A = mA;
301/// for (int ei = 0; ei < NUM_ELEM; ++ei) {
302/// mA.append(VALUES[ei]);
303/// }
304/// if (veryVerbose) { T_ T_ P_(NUM_ELEM) P(A) }
305/// LOOP_ASSERT(LINE, areEqual(EXP, A, NUM_ELEM));
306/// } BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
307/// }
308/// @endcode
309/// After the exception-safety test we can ensure that all the memory allocated
310/// from `sa` was successfully deallocated:
311/// @code
312/// if (veryVerbose) sa.print();
313///
314/// } break;
315///
316/// // ...
317///
318/// }
319///
320/// // ...
321/// }
322/// @endcode
323/// Note that the `BDE_BUILD_TARGET_EXC` macro is defined at compile-time to
324/// indicate whether or not exceptions are enabled.
325/// @}
326/** @} */
327/** @} */
328
329/** @addtogroup bsl
330 * @{
331 */
332/** @addtogroup bslma
333 * @{
334 */
335/** @addtogroup bslma_testallocator
336 * @{
337 */
338
339#include <bslscm_version.h>
340
341#include <bslma_allocator.h>
343
344#include <bsls_atomic.h>
345#include <bsls_bsllock.h>
346#include <bsls_buildtarget.h>
347#include <bsls_keyword.h>
348#include <bsls_types.h>
349
350#include <cstdio> // 'std::FILE' and (in macros) 'std::puts'
351
352#ifdef BDE_VERIFY
353# pragma bde_verify -AQK01 // Suppress "Need #include <stdio.h> for 'stdout'"
354#endif
355
356
357namespace bslma {
358
359// FORWARD REFERENCES
360struct TestAllocator_BlockHeader;
361
362 // ===================
363 // class TestAllocator
364 // ===================
365
366/// This class defines a concrete "test" allocator mechanism that implements
367/// the `Allocator` protocol, and provides instrumentation to track (1) the
368/// number of blocks/bytes currently in use, (2) the maximum number of
369/// blocks/bytes that have been outstanding at any one time, and (3) the
370/// cumulative number of blocks/bytes that have ever been allocated by this
371/// test allocator object. The accumulated statistics are based solely on
372/// the number of bytes requested. Additional testing facilities include
373/// allocation limits, verbosity modes, status, and automated report
374/// printing.
375///
376/// Note that, unlike many other allocators, this allocator does NOT rely on
377/// the currently installed default allocator (see @ref bslma_default ), but
378/// instead -- by default -- uses the `MallocFreeAllocator` singleton, which
379/// in turn calls the C Standard Library functions `malloc` and `free` as
380/// needed. Clients may, however, override this allocator by supplying (at
381/// construction) any other allocator implementing the `Allocator` protocol.
382///
383/// See @ref bslma_testallocator
384class TestAllocator : public Allocator {
385
386 // CONSTANTS
387 enum {
388 // Compute size of buffer needed to hold ascii-formatted statistics.
389 // The computation is a high estimate and includes the null terminator.
390 k_INT64_MAXDIGITS = 20, // max digits in `Int64, including sign
391 k_LABLETEXT_LEN = 51, // max label characters per line, including NL
392 k_NUM_STATLINES = 11, // Number of nonblank lines in formatted stats
393 k_PRINTED_STATS_SZ =
394 k_NUM_STATLINES * (k_LABLETEXT_LEN + 2 * k_INT64_MAXDIGITS) + 1,
395
396 // Compute size of buffer needed to hold one line of block IDs
397 // separated by tabs (including newline and null terminator).
398 k_BLOCKID_LINE_SZ = 8 * (k_INT64_MAXDIGITS + 1) + 1 + 1
399 };
400
401 // DATA
402
403 // Control Points
404
405 const char *d_name_p; // optionally specified name of this
406 // test allocator object (or 0)
407
409 d_noAbortFlag; // whether or not to suppress
410 // aborting on fatal errors
411
413 d_quietFlag; // whether or not to suppress
414 // reporting hard errors
415
417 d_verboseFlag; // whether or not to report
418 // allocation/deallocation events and
419 // print statistics on destruction
420
422 d_allocationLimit; // number of allocations before
423 // exception is thrown by this object
424
425 // Statistics
426
427 // Statistics and other attributes are updated in bulk while holding an
428 // object-wide mutex ('d_lock') but are read atomically by individual
429 // accessors without acquiring the mutex; hence, each such data member has
430 // an atomic type.
431
433 d_numAllocations; // total number of allocation
434 // requests on this object (including
435 // those for 0 bytes)
436
438 d_numDeallocations; // total number of deallocation
439 // requests on this object (including
440 // those supplying a 0 address)
441
443 d_numMismatches; // number of mismatched memory
444 // deallocation errors encountered by
445 // this object
447 d_numBoundsErrors; // number of overrun/underrun errors
448 // encountered by this object
449
451 d_numBlocksInUse; // number of blocks currently
452 // allocated from this object
453
455 d_numBytesInUse; // number of bytes currently
456 // allocated from this object
457
459 d_numBlocksMax; // maximum number of blocks ever
460 // allocated from this object at any
461 // one time
462
464 d_numBytesMax; // maximum number of bytes ever
465 // allocated from this object at any
466 // one time
467
469 d_numBlocksTotal; // cumulative number of blocks ever
470 // allocated from this object
471
473 d_numBytesTotal; // cumulative number of bytes ever
474 // allocated from this object
475
476 // Other Attributes
477
479 d_lastAllocatedNumBytes; // size (in bytes) of the most recent
480 // allocation request
481
483 d_lastDeallocatedNumBytes;
484 // size (in bytes) of the most
485 // recently deallocated memory
486
488 d_lastAllocatedAddress_p;// address of the most recently
489 // allocated memory (or 0)
490
492 d_lastDeallocatedAddress_p;
493 // address of the most recently
494 // deallocated memory (or 0)
495
496 // Other Data
497
498 TestAllocator_BlockHeader
499 *d_blockListHead_p; // first allocated block (owned)
500
501 TestAllocator_BlockHeader
502 *d_blockListTail_p; // last allocated block (owned)
503
504 mutable bsls::BslLock
505 d_lock; // Ensure mutual exclusion in
506 // 'allocate', 'deallocate', 'print',
507 // and 'status'.
508
509 Allocator *d_allocator_p; // upstream allocator (held, not owned)
510
511 // PRIVATE ACCESSORS
512
513 /// Traverse up to 8 blocks from the specified `*blockList` and write
514 /// their IDs to the specified `output` buffer, advance `*blockList` to
515 /// point to the first block in the list not not traversed (null if the
516 /// the last block was traversed), then return the number of characters
517 /// written to `output`, excluding the null terminator. The output
518 /// consists of a sequence of decimal-formatted IDs, each proceeded by
519 /// a tab character and ending with a newline character and null
520 /// terminator. The behavior is undefined unless `output` has
521 /// sufficient space for at least `k_BLOCKID_LINE_SZ` characters.
522 std::size_t
523 formatEightBlockIds(const TestAllocator_BlockHeader** blockList,
524 char* output ) const;
525
526 /// Write the accumulated statistics held in this allocator to the
527 /// specified `output` in a reasonable (multi-line) format and return
528 /// the number of characters written, excluding the null terminator.
529 /// The behavior is undefined unless `output` has sufficient space for
530 /// at least `k_PRINTED_STATS_SZ` characters.
531 std::size_t formatStats(char *output) const;
532
533 /// Write the accumulated state information held in this allocator to
534 /// the specified `stream` in a reasonable (multi-line) format and
535 /// return a reference offering modifiable access to `stream`. Output
536 /// is performed via calls to `stream.write(s, count)`.
537 template <class t_OS>
538 t_OS& printToStream(t_OS& stream) const;
539
540 // NOT IMPLEMENTED
541 TestAllocator(const TestAllocator&); // = delete
542 TestAllocator& operator=(const TestAllocator&); // = delete
543
544 public:
545 // CREATORS
546
547 explicit
548 TestAllocator(Allocator *basicAllocator = 0);
549 explicit
550 TestAllocator(const char *name,
551 Allocator *basicAllocator = 0);
552 explicit
553 TestAllocator(bool verboseFlag,
554 Allocator *basicAllocator = 0);
555 /// Create an instrumented "test" allocator. Optionally specify a
556 /// `name` (associated with this object) to be included in diagnostic
557 /// messages written to `stdout`, thereby distinguishing this test
558 /// allocator from others that might be used in the same program. If
559 /// `name` is 0 (or not specified), no distinguishing name is
560 /// incorporated in diagnostics. Optionally specify a `verboseFlag`
561 /// indicating whether this test allocator should automatically report
562 /// all allocation/deallocation events to `stdout` and print accumulated
563 /// statistics on destruction. If `verboseFlag` is `false` (or not
564 /// specified), allocation/deallocation and summary messages will not be
565 /// written automatically. Optionally specify a `basicAllocator` used
566 /// to supply memory. If `basicAllocator` is 0, the
567 /// `MallocFreeAllocator` singleton is used.
568 TestAllocator(const char *name,
569 bool verboseFlag,
570 Allocator *basicAllocator = 0);
571
572 /// Destroy this allocator. In verbose mode, print all contained state
573 /// values of this allocator object to `stdout`. Except in quiet mode,
574 /// automatically report any memory leaks to `stdout`. Abort if either
575 /// `numBlocksInUse` or `numBytesInUse` return non-zero unless in
576 /// no-abort mode or quiet mode. Note that, in all cases, destroying
577 /// this object has no effect on outstanding memory blocks allocated
578 /// from this test allocator (and may result in memory leaks -- e.g., if
579 /// the (default) `MallocFreeAllocator` singleton was used).
581
582 // MANIPULATORS
583
584 /// Return a newly-allocated block of memory of the specified `size` (in
585 /// bytes). If `size` is 0, a null pointer is returned. Otherwise,
586 /// invoke the `allocate` method of the allocator supplied at
587 /// construction, increment the number of currently (and cumulatively)
588 /// allocated blocks, and increase the number of currently allocated
589 /// bytes by `size`. Update all other fields accordingly; if the
590 /// allocation fails via an exception, `numAllocations()` is
591 /// incremented, `lastAllocatedNumBytes()` is set to `size`, and
592 /// `lastDeallocatedAddress()` is set to 0.
594
595 /// Return the memory block at the specified `address` back to this
596 /// allocator. If `address` is 0, this function has no effect (other
597 /// than to record relevant statistics). Otherwise, if the memory at
598 /// `address` is consistent with being allocated from this test
599 /// allocator, decrement the number of currently allocated blocks, and
600 /// decrease the number of currently allocated bytes by the size (in
601 /// bytes) originally requested for the block. Although technically
602 /// undefined behavior, if the memory can be determined not to have been
603 /// allocated from this test allocator, increment the number of
604 /// mismatches, and -- unless in quiet mode -- immediately report the
605 /// details of the mismatch to `stdout` (e.g., as an `std::hex` memory
606 /// dump) and abort.
608
609 /// Set the number of valid allocation requests before an exception is
610 /// to be thrown for this allocator to the specified `limit`. If
611 /// `limit` is less than 0, no exception is to be thrown. By default,
612 /// no exception is scheduled.
613 void setAllocationLimit(bsls::Types::Int64 limit);
614
615 /// Set the no-abort mode for this test allocator to the specified
616 /// (boolean) `flagValue`. `If flagValue` is `true`, aborting on fatal
617 /// errors is suppressed, and the functions simply return. Diagnostics
618 /// are not affected. Note that the default mode is to abort. Also
619 /// note that this function is provided primarily to enable visual
620 /// testing of diagnostic messages produced by this component.
621 void setNoAbort(bool flagValue);
622
623 /// Set the quiet mode for this test allocator to the specified
624 /// (boolean) `flagValue`. If `flagValue` is `true`, mismatched
625 /// allocations, overrun/underrun errors, and memory leak messages will
626 /// not be displayed to `stdout` and the process will not abort as a
627 /// result of such conditions. Note that the default mode is *not*
628 /// quiet. Also note that this function is provided primarily to enable
629 /// testing of this component; in quiet mode, situations that would
630 /// otherwise abort will just quietly increment the `numMismatches`
631 /// and/or `numBoundsErrors` counters.
632 void setQuiet(bool flagValue);
633
634 /// Set the verbose mode for this test allocator to the specified
635 /// (boolean) `flagValue`. If `flagValue` is `true`, all
636 /// allocation/deallocation events will be reported automatically on
637 /// `stdout`, as will accumulated statistics upon destruction of this
638 /// object. Note that the default mode is *not* verbose.
639 void setVerbose(bool flagValue);
640
641 // ACCESSORS
642
643 /// Return the current number of allocation requests left before an
644 /// exception is thrown. A negative value indicates that no exception
645 /// is scheduled.
646 bsls::Types::Int64 allocationLimit() const;
647
648 /// Return `true` if this allocator is currently in no-abort mode, and
649 /// `false` otherwise. In no-abort mode all diagnostic messages are
650 /// printed, but all aborts are suppressed. Note that quiet mode
651 /// implies no-abort mode.
652 bool isNoAbort() const;
653
654 /// Return `true` if this allocator is currently in quiet mode, and
655 /// `false` otherwise. In quiet mode, messages about mismatched
656 /// deallocations, overrun/underrun errors, and memory leaks will not be
657 /// displayed to `stdout` and will not cause the program to abort.
658 bool isQuiet() const;
659
660 /// Return `true` if this allocator is currently in verbose mode, and
661 /// `false` otherwise. In verbose mode, all allocation/deallocation
662 /// events will be reported on `stdout`, as will summary statistics upon
663 /// destruction of this object.
664 bool isVerbose() const;
665
666 /// Return the address that was returned by the most recent allocation
667 /// request. Return 0 if the most recent allocation request was for 0
668 /// bytes.
669 void *lastAllocatedAddress() const;
670
671 /// Return the number of bytes of the most recent allocation request.
673
674 /// Return the address that was supplied to the most recent deallocation
675 /// request. Return 0 if a null pointer was most recently deallocated.
676 /// Note that the address is always recorded regardless of the validity
677 /// of the request.
678 void *lastDeallocatedAddress() const;
679
680 /// Return the number of bytes of the most recent deallocation request.
681 /// Return 0 if a null pointer was most recently deallocated, or if the
682 /// request was invalid (e.g., an attempt to deallocate memory not
683 /// allocated through this allocator).
685
686 /// Return the name of this test allocator, or 0 if no name was
687 /// specified at construction.
688 const char *name() const;
689
690 /// Return the cumulative number of allocation requests. Note that this
691 /// number is incremented for every `allocate` invocation.
692 bsls::Types::Int64 numAllocations() const;
693
694 /// Return the number of blocks currently allocated from this object.
695 /// Note that `numBlocksInUse() <= numBlocksMax()`.
696 bsls::Types::Int64 numBlocksInUse() const;
697
698 /// Return the maximum number of blocks ever allocated from this object
699 /// at any one time. Note that
700 /// `numBlocksInUse() <= numBlocksMax() <= numBlocksTotal()`.
701 bsls::Types::Int64 numBlocksMax() const;
702
703 /// Return the cumulative number of blocks ever allocated from this
704 /// object. Note that `numBlocksMax() <= numBlocksTotal()`.
705 bsls::Types::Int64 numBlocksTotal() const;
706
707 /// Return the number of times memory deallocations have detected that
708 /// pad areas at the front or back of the user segment had been
709 /// overwritten.
710 bsls::Types::Int64 numBoundsErrors() const;
711
712 /// Return the number of bytes currently allocated from this object.
713 /// Note that `numBytesInUse() <= numBytesMax()`.
714 bsls::Types::Int64 numBytesInUse() const;
715
716 /// Return the maximum number of bytes ever allocated from this object
717 /// at any one time. Note that
718 /// `numBytesInUse() <= numBytesMax() <= numBytesTotal()`.
719 bsls::Types::Int64 numBytesMax() const;
720
721 /// Return the cumulative number of bytes ever allocated from this
722 /// object. Note that `numBytesMax() <= numBytesTotal()`.
723 bsls::Types::Int64 numBytesTotal() const;
724
725 /// Return the cumulative number of deallocation requests. Note that
726 /// this number is incremented for every `deallocate` invocation,
727 /// regardless of the validity of the request.
728 bsls::Types::Int64 numDeallocations() const;
729
730 /// Return the number of mismatched memory deallocations that have
731 /// occurred since this object was created. A memory deallocation is
732 /// *mismatched* if that memory was not allocated directly from this
733 /// allocator.
734 bsls::Types::Int64 numMismatches() const;
735
736 /// Write the accumulated state information held in this allocator to
737 /// the optionally specified file `f` (default `stdout`) in a reasonable
738 /// (multi-line) format.
739 void print(std::FILE *f = stdout) const;
740
741 /// Return 0 on success, and non-zero otherwise: If there have been any
742 /// mismatched memory deallocations or over/under runs, return the
743 /// number of such errors that have occurred as a positive number; if
744 /// either `0 < numBlocksInUse()` or `0 < numBytesInUse()`, return an
745 /// arbitrary negative number; else return 0.
746 int status() const;
747
748#ifndef BDE_OPENSOURCE_PUBLICATION // DEPRECATED
749
750 /// Return the allocated memory address of the most recent memory
751 /// request. Return 0 if the request was invalid (e.g., allocate non-
752 /// positive number of bytes).
753 ///
754 /// DEPRECATED: use `lastAllocatedAddress` instead.
755 void *lastAllocateAddress() const;
756
757 /// Return the number of bytes of the most recent memory request. Note
758 /// that this number is always recorded regardless of the validity of
759 /// the request.
760 ///
761 /// DEPRECATED: use `lastAllocatedNumBytes` instead.
763
764 /// Return the memory address of the last memory deallocation request.
765 /// Note that the address is always recorded regardless of the validity
766 /// of the request.
767 ///
768 /// DEPRECATED: use `lastDeallocatedAddress` instead.
769 void *lastDeallocateAddress() const;
770
771 /// Return the number of bytes of the most recent memory deallocation
772 /// request. Return 0 if the request was invalid (e.g., deallocating
773 /// memory not allocated through this allocator).
774 ///
775 /// DEPRECATED: use `lastDeallocatedNumBytes` instead.
777
778 /// Return the cumulative number of allocation requests. Note that this
779 /// number is incremented for every `allocate` invocation, regardless of
780 /// the validity of the request.
781 ///
782 /// DEPRECATED: use `numAllocations` instead.
784
785 /// Return the cumulative number of deallocation requests. Note that
786 /// this number is incremented for every `deallocate` invocation,
787 /// regardless of the validity of the request.
788 ///
789 /// DEPRECATED: use `numDeallocations` instead.
791#endif // BDE_OPENSOURCE_PUBLICATION
792
793 // HIDDEN FRIENDS
794
795 /// Write the accumulated state information held in the specified
796 /// allocator `ta` to the specified `stream` in a reasonable
797 /// (multi-line) format identical to the format produced by `ta.print()`
798 /// and return a reference offering modifiable access to `stream`.
799 /// Output is performed via calls to `stream.write(s, count)`, where
800 /// `write` is a required method of class `t_OS`, `s` is a `const char*`
801 /// holding the formatted output, and `count` is the length of `s`
802 /// excluding any null terminator. Note that `std::ostream` meets the
803 /// requirements for `t_OS`.
804 template <class t_OS>
805 friend t_OS& operator<<(t_OS& stream, const TestAllocator& ta)
806 { return ta.printToStream(stream); }
807};
808
809} // close package namespace
810
811 // ==============================================
812 // macro BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
813 // ==============================================
814
815#ifdef BDE_BUILD_TARGET_EXC
816
817namespace bslma {
818
819/// This class provides a common base class for the parameterized
820/// `TestAllocator_Proxy` class (below). Note that the `virtual`
821/// `setAllocationLimit` method, although a "setter", *must* be declared
822/// `const`.
823///
824/// See @ref bslma_testallocator
825class TestAllocator_ProxyBase {
826
827 public:
828 // CREATOR
829 virtual ~TestAllocator_ProxyBase()
830 {
831 }
832
833 // ACCESSORS
834 virtual void setAllocationLimit(bsls::Types::Int64 limit) const = 0;
835};
836
837/// This class provides a proxy to the test allocator that is supplied to
838/// the `BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN` macro. This proxy may be
839/// instantiated with `TestAllocator`, or with a type that supports the same
840/// interface as `TestAllocator`.
841///
842/// See @ref bslma_testallocator
843template <class BSLMA_ALLOC_TYPE>
844class TestAllocator_Proxy : public TestAllocator_ProxyBase {
845
846 // DATA
847 BSLMA_ALLOC_TYPE *d_allocator_p; // allocator used in '*_BEGIN' and
848 // '*_END' macros (held, not owned)
849
850 public:
851 // CREATORS
852 explicit TestAllocator_Proxy(BSLMA_ALLOC_TYPE *allocator)
853 : d_allocator_p(allocator)
854 {
855 }
856
857 ~TestAllocator_Proxy() BSLS_KEYWORD_OVERRIDE
858 {
859 }
860
861 // ACCESSORS
862 void setAllocationLimit(bsls::Types::Int64 limit) const
864 {
865 d_allocator_p->setAllocationLimit(limit);
866 }
867};
868
869/// Return, by value, a test allocator proxy for the specified parameterized
870/// `allocator`.
871template <class BSLMA_ALLOC_TYPE>
872inline
873TestAllocator_Proxy<BSLMA_ALLOC_TYPE>
874TestAllocator_getProxy(BSLMA_ALLOC_TYPE *allocator)
875{
876 return TestAllocator_Proxy<BSLMA_ALLOC_TYPE>(allocator);
877}
878
879} // close package namespace
880
881#ifndef BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
882// Note that the `while` loop in the following code uses a flag
883// `bslmaKeepLoopingInTestAllocatorExceptionTest`. This is a workaround for an
884// XLC16 bug: a `continue` statement in a `catch` block can result in
885// segmentation faults on optimized XLC16 builds. Bug raised with IBM - see
886// DRQS 169604597
887#define BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(BSLMA_TESTALLOCATOR) { \
888 { \
889 static int firstTime = 1; \
890 if (veryVerbose && firstTime) { \
891 std::puts("\t\tBSLMA EXCEPTION TEST -- (ENABLED) --"); \
892 } \
893 firstTime = 0; \
894 } \
895 if (veryVeryVerbose) { \
896 std::puts("\t\tBegin bslma exception test."); \
897 } \
898 int bslmaExceptionCounter = 0; \
899 const BloombergLP::bslma::TestAllocator_ProxyBase& \
900 bslmaExceptionTestAllocator = \
901 BloombergLP::bslma::TestAllocator_getProxy(&BSLMA_TESTALLOCATOR); \
902 bslmaExceptionTestAllocator.setAllocationLimit(bslmaExceptionCounter); \
903 bool bslmaKeepLoopingInTestAllocatorExceptionTest = true; \
904 while(bslmaKeepLoopingInTestAllocatorExceptionTest) { \
905 bslmaKeepLoopingInTestAllocatorExceptionTest = false; \
906 try {
907#endif // BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
908
909#else // !defined(BDE_BUILD_TARGET_EXC)
910
911#ifndef BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
912#define BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(BSLMA_TESTALLOCATOR) \
913{ \
914 static int firstTime = 1; \
915 if (verbose && firstTime) { \
916 std::puts("\t\tBSLMA EXCEPTION TEST -- (NOT ENABLED) --"); \
917 firstTime = 0; \
918 } \
919}
920#endif // BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
921
922#endif // BDE_BUILD_TARGET_EXC
923
924 // ============================================
925 // macro BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
926 // ============================================
927
928#ifdef BDE_BUILD_TARGET_EXC
929
930#ifndef BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
931#define BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END \
932 } catch (BloombergLP::bslma::TestAllocatorException& e) { \
933 if (veryVeryVerbose) { \
934 std::printf("\t*** BSLMA_EXCEPTION: " \
935 "alloc limit = %d, last alloc size = %d ***\n", \
936 bslmaExceptionCounter, \
937 static_cast<int>(e.numBytes())); \
938 } \
939 bslmaExceptionTestAllocator.setAllocationLimit( \
940 ++bslmaExceptionCounter); \
941 bslmaKeepLoopingInTestAllocatorExceptionTest = true; \
942 } \
943 }; \
944 bslmaExceptionTestAllocator.setAllocationLimit(-1); \
945 if (veryVeryVerbose) { \
946 std::puts("\t\tEnd bslma exception test."); \
947 } \
948}
949
950#endif // BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
951
952#else // !defined(BDE_BUILD_TARGET_EXC)
953
954#ifndef BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
955#define BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
956#endif
957
958#endif
959
960namespace bslma {
961
962// ============================================================================
963// INLINE DEFINITIONS
964// ============================================================================
965
966 // -------------------
967 // class TestAllocator
968 // -------------------
969
970// PRIVATE ACCESSORS
971template <class t_OS>
972t_OS& TestAllocator::printToStream(t_OS& stream) const
973{
974 bsls::BslLockGuard guard(&d_lock);
975
976 char buffer[k_PRINTED_STATS_SZ];
977 std::size_t cnt = formatStats(buffer);
978 stream.write(buffer, cnt);
979
980 static const char k_ID_STR[] =
981 " Indices of Outstanding Memory Allocations:\n";
982 static const std::size_t k_ID_STR_LEN = sizeof(k_ID_STR) - 1;
983
984 if (d_blockListHead_p) {
985 stream.write(k_ID_STR, k_ID_STR_LEN);
986
987 // Traverse the linked list starting from 'd_blockListHead_p' and print
988 // the ID of each block in the list, 8 to a line
989 const TestAllocator_BlockHeader *next_p = d_blockListHead_p;
990 while (next_p) {
991 cnt = formatEightBlockIds(&next_p, buffer);
992 stream.write(buffer, cnt);
993 }
994 }
995
996 return stream;
997}
998
999
1000// MANIPULATORS
1001inline
1003{
1004 d_allocationLimit.storeRelaxed(limit);
1005}
1006
1007inline
1008void TestAllocator::setNoAbort(bool flagValue)
1009{
1010 d_noAbortFlag.storeRelaxed(flagValue);
1011}
1012
1013inline
1014void TestAllocator::setQuiet(bool flagValue)
1015{
1016 d_quietFlag.storeRelaxed(flagValue);
1017}
1018
1019inline
1020void TestAllocator::setVerbose(bool flagValue)
1021{
1022 d_verboseFlag.storeRelaxed(flagValue);
1023}
1024
1025// ACCESSORS
1026inline
1028{
1029 return d_allocationLimit.loadRelaxed();
1030}
1031
1032inline
1034{
1035 return d_noAbortFlag.loadRelaxed();
1036}
1037
1038inline
1040{
1041 return d_quietFlag.loadRelaxed();
1042}
1043
1044inline
1046{
1047 return d_verboseFlag.loadRelaxed();
1048}
1049
1050inline
1052{
1053 return reinterpret_cast<void *>(d_lastAllocatedAddress_p.loadRelaxed());
1054}
1055
1056inline
1058{
1059 return static_cast<size_type>(d_lastAllocatedNumBytes.loadRelaxed());
1060}
1061
1062inline
1064{
1065 return reinterpret_cast<void *>(d_lastDeallocatedAddress_p.loadRelaxed());
1066}
1067
1068inline
1070{
1071 return static_cast<size_type>(d_lastDeallocatedNumBytes.loadRelaxed());
1072}
1073
1074inline
1075const char *TestAllocator::name() const
1076{
1077 return d_name_p;
1078}
1079
1080inline
1082{
1083 return d_numAllocations.loadRelaxed();
1084}
1085
1086inline
1088{
1089 return d_numBlocksInUse.loadRelaxed();
1090}
1091
1092inline
1094{
1095 return d_numBlocksMax.loadRelaxed();
1096}
1097
1098inline
1100{
1101 return d_numBlocksTotal.loadRelaxed();
1102}
1103
1104inline
1106{
1107 return d_numBoundsErrors.loadRelaxed();
1108}
1109
1110inline
1112{
1113 return d_numBytesInUse.loadRelaxed();
1114}
1115
1116inline
1118{
1119 return d_numBytesMax.loadRelaxed();
1120}
1121
1122inline
1124{
1125 return d_numBytesTotal.loadRelaxed();
1126}
1127
1128inline
1130{
1131 return d_numDeallocations.loadRelaxed();
1132}
1133
1134inline
1136{
1137 return d_numMismatches.loadRelaxed();
1138}
1139
1140#ifndef BDE_OPENSOURCE_PUBLICATION // DEPRECATED
1141inline
1143{
1144 return lastAllocatedAddress();
1145}
1146
1147inline
1153
1154inline
1156{
1157 return lastDeallocatedAddress();
1158}
1159
1160inline
1166
1167inline
1172
1173inline
1178
1179#endif // BDE_OPENSOURCE_PUBLICATION
1180
1181} // close package namespace
1182
1183#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
1184// ============================================================================
1185// BACKWARD COMPATIBILITY
1186// ============================================================================
1187
1188/// This alias is defined for backward compatibility.
1190
1191// The following two macros can be deleted when they are no longer referenced
1192// in any .t.cpp files.
1193
1194#ifndef BEGIN_BSLMA_EXCEPTION_TEST
1195#define BEGIN_BSLMA_EXCEPTION_TEST \
1196 BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(testAllocator)
1197#endif
1198
1199#ifndef END_BSLMA_EXCEPTION_TEST
1200#define END_BSLMA_EXCEPTION_TEST BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
1201#endif
1202
1203#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
1204
1205
1206
1207#endif
1208
1209// ----------------------------------------------------------------------------
1210// Copyright 2013 Bloomberg Finance L.P.
1211//
1212// Licensed under the Apache License, Version 2.0 (the "License");
1213// you may not use this file except in compliance with the License.
1214// You may obtain a copy of the License at
1215//
1216// http://www.apache.org/licenses/LICENSE-2.0
1217//
1218// Unless required by applicable law or agreed to in writing, software
1219// distributed under the License is distributed on an "AS IS" BASIS,
1220// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1221// See the License for the specific language governing permissions and
1222// limitations under the License.
1223// ----------------------------- END-OF-FILE ----------------------------------
1224
1225/** @} */
1226/** @} */
1227/** @} */
Definition bslma_allocator.h:457
std::size_t size_type
Definition bslma_allocator.h:499
Definition bslma_testallocator.h:384
TestAllocator(const char *name, Allocator *basicAllocator=0)
void deallocate(void *address) BSLS_KEYWORD_OVERRIDE
TestAllocator(Allocator *basicAllocator=0)
void setAllocationLimit(bsls::Types::Int64 limit)
Definition bslma_testallocator.h:1002
bsls::Types::Int64 numAllocation() const
Definition bslma_testallocator.h:1168
bsls::Types::Int64 numDeallocations() const
Definition bslma_testallocator.h:1129
bsls::Types::Int64 numBlocksInUse() const
Definition bslma_testallocator.h:1087
bsls::Types::Int64 numDeallocation() const
Definition bslma_testallocator.h:1174
bsls::Types::Int64 numBlocksMax() const
Definition bslma_testallocator.h:1093
void * lastAllocatedAddress() const
Definition bslma_testallocator.h:1051
void print(std::FILE *f=stdout) const
bsls::Types::Int64 allocationLimit() const
Definition bslma_testallocator.h:1027
size_type lastAllocatedNumBytes() const
Return the number of bytes of the most recent allocation request.
Definition bslma_testallocator.h:1057
bsls::Types::Int64 numBytesInUse() const
Definition bslma_testallocator.h:1111
bool isNoAbort() const
Definition bslma_testallocator.h:1033
TestAllocator(const char *name, bool verboseFlag, Allocator *basicAllocator=0)
size_type lastDeallocatedNumBytes() const
Definition bslma_testallocator.h:1069
~TestAllocator() BSLS_KEYWORD_OVERRIDE
bsls::Types::Int64 numBlocksTotal() const
Definition bslma_testallocator.h:1099
bsls::Types::Int64 numBytesTotal() const
Definition bslma_testallocator.h:1123
void * lastAllocateAddress() const
Definition bslma_testallocator.h:1142
friend t_OS & operator<<(t_OS &stream, const TestAllocator &ta)
Definition bslma_testallocator.h:805
size_type lastDeallocateNumBytes() const
Definition bslma_testallocator.h:1162
void setQuiet(bool flagValue)
Definition bslma_testallocator.h:1014
bsls::Types::Int64 numMismatches() const
Definition bslma_testallocator.h:1135
bool isQuiet() const
Definition bslma_testallocator.h:1039
void * lastDeallocatedAddress() const
Definition bslma_testallocator.h:1063
void * allocate(size_type size) BSLS_KEYWORD_OVERRIDE
TestAllocator(bool verboseFlag, Allocator *basicAllocator=0)
void setNoAbort(bool flagValue)
Definition bslma_testallocator.h:1008
void setVerbose(bool flagValue)
Definition bslma_testallocator.h:1020
bsls::Types::Int64 numBoundsErrors() const
Definition bslma_testallocator.h:1105
size_type lastAllocateNumBytes() const
Definition bslma_testallocator.h:1149
void * lastDeallocateAddress() const
Definition bslma_testallocator.h:1155
const char * name() const
Definition bslma_testallocator.h:1075
bsls::Types::Int64 numAllocations() const
Definition bslma_testallocator.h:1081
bool isVerbose() const
Definition bslma_testallocator.h:1045
bsls::Types::Int64 numBytesMax() const
Definition bslma_testallocator.h:1117
Definition bsls_atomic.h:892
Types::Int64 loadRelaxed() const
Definition bsls_atomic.h:1914
void storeRelaxed(Types::Int64 value)
Definition bsls_atomic.h:1833
Definition bsls_atomic.h:743
int loadRelaxed() const
Definition bsls_atomic.h:1738
void storeRelaxed(int value)
Definition bsls_atomic.h:1660
Definition bsls_atomic.h:1349
TYPE * loadRelaxed() const
Definition bsls_atomic.h:2402
Definition bsls_bsllock.h:227
Definition bsls_bsllock.h:175
bslma::TestAllocator bslma_TestAllocator
This alias is defined for backward compatibility.
Definition bslma_testallocator.h:1189
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition balxml_encoderoptions.h:68
Definition bdlt_iso8601util.h:691
Definition bdldfp_decimal.h:5188
long long Int64
Definition bsls_types.h:132