BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_review.h
Go to the documentation of this file.
1/// @file bsls_review.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_review.h -*-C++-*-
8#ifndef INCLUDED_BSLS_REVIEW
9#define INCLUDED_BSLS_REVIEW
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_review bsls_review
15/// @brief Provide assertion macros to safely identify contract violations.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_review
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_review-purpose"> Purpose</a>
25/// * <a href="#bsls_review-classes"> Classes </a>
26/// * <a href="#bsls_review-macros"> Macros </a>
27/// * <a href="#bsls_review-description"> Description </a>
28/// * <a href="#bsls_review-detailed-behavior"> Detailed Behavior </a>
29/// * <a href="#bsls_review-review-levels-and-build-modes"> Review Levels and Build Modes </a>
30/// * <a href="#bsls_review-runtime-configurable-review-failure-behavior"> Runtime-Configurable Review-Failure Behavior </a>
31/// * <a href="#bsls_review-conditional-compilation"> Conditional Compilation </a>
32/// * <a href="#bsls_review-validating-disabled-macro-expressions"> Validating Disabled Macro Expressions </a>
33/// * <a href="#bsls_review-uses-for-ref-bsls_review"> Uses for @ref bsls_review </a>
34/// * <a href="#bsls_review-adding-new-ref-bsls_assert-checks-to-new-code"> Adding New @ref bsls_assert Checks To New Code </a>
35/// * <a href="#bsls_review-adding-assertions-with-ref-bsls_review"> Adding Assertions With @ref bsls_review </a>
36/// * <a href="#bsls_review-reducing-the-assertion-level-for-existing-ref-bsls_assert-macros"> Reducing The Assertion Level For Existing @ref bsls_assert Macros </a>
37/// * <a href="#bsls_review-increasing-deployed-assertion-levels-with-bsls_review_level_"> Increasing Deployed Assertion Levels With BSLS_REVIEW_LEVEL_ </a>
38/// * <a href="#bsls_review-checking-library-usage-before-changing-it-with-ref-bsls_review"> Checking Library Usage Before Changing it With @ref bsls_review </a>
39/// * <a href="#bsls_review-concerns-when-adding-reviews-or-assertions"> Concerns When Adding Reviews or Assertions </a>
40/// * <a href="#bsls_review-usage"> Usage </a>
41/// * <a href="#bsls_review-example-1-adding-bsls_assert-to-an-existing-function"> Example 1: Adding BSLS_ASSERT To An Existing Function </a>
42///
43/// # Purpose {#bsls_review-purpose}
44/// Provide assertion macros to safely identify contract violations.
45///
46/// # Classes {#bsls_review-classes}
47///
48/// - bsls::Review: namespace for "review" management functions
49/// - bsls::ReviewFailureHandlerGuard: scoped guard for changing handlers safely
50/// - bsls::ReviewViolation: attributes describing a failed review check
51///
52/// # Macros {#bsls_review-macros}
53///
54/// - BSLS_REVIEW: runtime check typically enabled in all non-opt build modes
55/// - BSLS_REVIEW_SAFE: runtime check typically only enabled in safe build modes
56/// - BSLS_REVIEW_OPT: runtime check typically enabled in all build modes
57/// - BSLS_REVIEW_INVOKE: immediately invoke the current review handler
58/// - BSLS_REVIEW_UNREACHABLE: mark unreachable code path, enabled like REVIEW
59/// - BSLS_REVIEW_SAFE_UNREACHABLE: unreachable code path, enabled like SAFE
60/// - BSLS_REVIEW_OPT_UNREACHABLE: unreachable code path, enabled like OPT
61///
62/// @see bsls_assert
63///
64/// # Description {#bsls_review-description}
65/// This component provides three "assert-like" macros,
66/// `BSLS_REVIEW`, `BSLS_REVIEW_SAFE`, and `BSLS_REVIEW_OPT`, that can be used
67/// to enable optional *redundant* runtime checks in corresponding build modes
68/// that are designed to log their failures so production systems can be safely
69/// monitored for contract violations.
70///
71/// This component is designed to allow apparently working production software,
72/// which nonetheless may harbor contract violations, to increase the number of
73/// precondition checks used to catch such bugs without negatively impacting the
74/// existing behavior of the software. The assumption is that any contract
75/// violations uncovered through these checks in stable software is (at least
76/// for the moment) benign. This component should *not* be used for assertions
77/// added to new code; new code should rely on @ref bsls_assert , as any contract
78/// violations discovered in new code may not be benign and the resulting
79/// behavior may be much worse than the task terminating (as would happen using
80/// @ref bsls_assert ).
81///
82/// If the argument of a review macro evaluates to 0, a runtime-configurable
83/// "handler" function is invoked with a `bsls::ReviewViolation`, a
84/// value-semantic class that encapsulates the current filename, line number,
85/// level of failed check, (0-valued expression) argument text, and a count of
86/// how many times that check has already failed. The default handler logs that
87/// a failure has occurred and then allows processing to continue, thus not
88/// adversely impacting the running program. The class `bsls::Review` provides
89/// functions for manipulating the globally configured "handler". A scoped
90/// guard for setting and restoring the review handler is provided by
91/// `bsls::ReviewFailureHandlerGuard`.
92///
93/// An additional macro, `BSLS_REVIEW_INVOKE`, is included for directly invoking
94/// the current review handler as if an assertion had failed on the current
95/// line with a string passed in. This string will be used as if it was the
96/// string the other macros generate from the expression. Though it can be
97/// dynamically generated, it is recommended to use a stable string to identify
98/// the character of the error and to use a logging component (such as
99/// `bsls_log`) to log any additional information relevant to the failure prior
100/// to invoking the handler.
101///
102/// ### Detailed Behavior {#bsls_review-detailed-behavior}
103///
104///
105/// If a review fires (i.e., due to a 0-valued expression argument in a review
106/// macro that is enabled), there is a violation of the contract that the review
107/// is checking. For such a failing review, the program is in an undefined
108/// state but it is deemed inadvisable to immediately abort without further
109/// analysis. It is the goal of the review to be sure to log that a contract
110/// was violated so the issue (in either the calling code or the contract) can
111/// be addressed.
112///
113/// Reviews are enabled or disabled at compile time based on the review level,
114/// assertion level, and build mode flags that have been defined. It is also
115/// possible that assert macros (see @ref bsls_assert ) can be configured in review
116/// mode, and so they may behave exactly as would review macros with appropriate
117/// build flags.
118///
119/// When enabled, the review macros will all do essentially the same thing: Each
120/// macro tests the predicate expression `X`, and if `!(X)` is `true`, tracks a
121/// count of how many times this particular review has failed and invokes the
122/// currently installed review handler. An instance of `bsls::ReviewViolation`
123/// will be created and populated with a textual rendering of the predicate
124/// (`#X`), the current `__FILE__`, the current `__LINE__`, a string
125/// representing which particular type of review or assertion has failed, and
126/// the current count of how many times this predicate has failed (used
127/// primarily to throttle repeated logging of violations from the same
128/// location). This `violation` is then passed to the currently installed
129/// review failure handler, a function pointer with the type
130/// `bsls::Review::ViolationHandler` having the signature:
131/// @code
132/// void(const bsls::ReviewViolation&)
133/// @endcode
134///
135/// ### Review Levels and Build Modes {#bsls_review-review-levels-and-build-modes}
136///
137///
138/// There are a few macros available to control which of the review macros are
139/// actually enabled. These macros are for the compilation and build
140/// environment to provide and are not themselves defined by BDE code -- e.g.,
141/// by supplying one or more of these macros with `-D` options on the compiler
142/// command line. In general, these macros are used to determine a
143/// `REVIEW_LEVEL` that can be `NONE`, `REVIEW_OPT`, `REVIEW`, or `REVIEW_SAFE`.
144/// Depending on the review level, different review macros will be enabled. For
145/// "safer" review configurations, more macros are enabled and all lower-level
146/// (and presumably lower cost) macros are kept enabled. The `NONE` level is
147/// primarily provided for testing to ensure that the `REVIEW_OPT` level doesn't
148/// actually introduce any side-effects or incur measurable overhead when
149/// enabled, though in practice it should not be deployed.
150/// @code
151/// ==================================================
152/// "REVIEW" Macro Instantiation Based on Review Level
153/// ==================================================
154/// BSLS_REVIEW_LEVEL BSLS_REVIEW_OPT BSLS_REVIEW BSLS_REVIEW_SAFE
155/// ----------------- --------------- ----------- ----------------
156/// NONE
157/// REVIEW_OPT ENABLED
158/// REVIEW ENABLED ENABLED
159/// REVIEW_SAFE ENABLED ENABLED ENABLED
160/// @endcode
161/// The logic for the determination of the review level checks a few different
162/// macros. The first check is for one of the 4 mutually exclusive
163/// `BSLS_REVIEW_LEVEL` macros that can explicitly set the review level:
164/// @code
165/// MACRO BSLS_REVIEW_LEVEL
166/// ----- ----------------
167/// BSLS_REVIEW_LEVEL_NONE NONE
168/// BSLS_REVIEW_LEVEL_REVIEW_OPT REVIEW_OPT
169/// BSLS_REVIEW_LEVEL_REVIEW REVIEW
170/// BSLS_REVIEW_LEVEL_REVIEW_SAFE REVIEW_SAFE
171/// @endcode
172/// If none of those macros are defined, the review level is implemented to be
173/// exactly the same as the assertion level (see @ref bsls_assert ). This is so
174/// that any introduced review macro will still be enabled (and become an
175/// assertion) when it is textually replaced with a `BSLS_ASSERT`. This means
176/// that first one of the 7 mutually exclusive `BSLS_ASSERT_LEVEL` macros are
177/// checked to determine the review level:
178/// @code
179/// MACRO BSLS_REVIEW_LEVEL
180/// ----- ----------------
181/// BSLS_ASSERT_LEVEL_ASSUME_SAFE NONE
182/// BSLS_ASSERT_LEVEL_ASSUME_ASSERT NONE
183/// BSLS_ASSERT_LEVEL_ASSUME_OPT NONE
184/// BSLS_ASSERT_LEVEL_NONE NONE
185/// BSLS_ASSERT_LEVEL_ASSERT_OPT REVIEW_OPT
186/// BSLS_ASSERT_LEVEL_ASSERT REVIEW
187/// BSLS_ASSERT_LEVEL_ASSERT_SAFE REVIEW_SAFE
188/// @endcode
189/// Finally, the default review (and assert) level, if none of the overriding
190/// review or assert level macros above are defined, is determined by the build
191/// mode. With "safer" build modes we incorporate higher-level defensive
192/// program checks. A particular build mode is implied by the relevant (BDE)
193/// build targets that are defined at compilation (preprocessing) time. The
194/// following table shows the three (BDE) build targets that can affect the
195/// assertion and review levels (note that `BDE_BUILD_TARGET_DBG` plays no
196/// role):
197/// @code
198/// (BDE) Build Targets
199/// -----------------------
200/// (A) BDE_BUILD_TARGET_SAFE_2
201/// (B) BDE_BUILD_TARGET_SAFE
202/// (C) BDE_BUILD_TARGET_OPT
203/// @endcode
204/// *Any* of the 8 possible combinations of the three build targets is valid;
205/// e.g., `BDE_BUILD_TARGET_OPT` and `BDE_BUILD_TARGET_SAFE_2` may both be
206/// defined. The following table shows the review level that is set depending
207/// on which combination of build target macros have been set:
208/// @code
209/// =========================================================
210/// "REVIEW" Level Set With no Level-Overriding Flags defined
211/// =========================================================
212/// --- BDE_BUILD_TARGET ---- BSLS_REVIEW_LEVEL
213/// _SAFE_2 _SAFE _OPT
214/// ------- ------- ------- -----------------
215/// REVIEW
216/// DEFINED REVIEW_OPT
217/// DEFINED REVIEW_SAFE
218/// DEFINED DEFINED REVIEW_SAFE
219/// DEFINED REVIEW_SAFE
220/// DEFINED DEFINED REVIEW_SAFE
221/// DEFINED DEFINED REVIEW_SAFE
222/// DEFINED DEFINED DEFINED REVIEW_SAFE
223/// @endcode
224/// As the table above illustrates, with no build target explicitly defined the
225/// review level defaults to `REVIEW`. If only `BDE_BUILD_TARGET_OPT` is
226/// defined, the review level will be set to `REVIEW_OPT`. If either
227/// `BDE_BUILD_TARGET_SAFE` or `BDE_BUILD_TARGET_SAFE_2` is defined then the
228/// review level is set to `REVIEW_SAFE` and ALL review macros will be enabled.
229///
230/// ### Runtime-Configurable Review-Failure Behavior {#bsls_review-runtime-configurable-review-failure-behavior}
231///
232///
233/// In addition to the three (BSLS) "REVIEW" macros, `BSLS_REVIEW`,
234/// `BSLS_REVIEW_SAFE`, and `BSLS_REVIEW_OPT`, and the immediate invocation
235/// macro `BSLS_REVIEW_INVOKE`, this component provides (1) an `invokeHandler`
236/// method used (primarily) to implement these "REVIEW" macros and enable their
237/// runtime configuration, (2) administrative methods to configure, at runtime,
238/// the behavior resulting from a review failure (i.e., by installing an
239/// appropriate review-failure handler function), and (3) a suite of standard
240/// ("off-the-shelf") review-failure handler functions, to be installed via the
241/// methods (if desired), and invoked by the `invokeHandler` method of a review
242/// failure.
243///
244/// When an enabled review fails, the currently installed *failure* *handler*
245/// ("callback") function is invoked. The default handler is the (`static`)
246/// `bsls::Review::failByLog` method, which will log the failure and the current
247/// callstack when invoked for the first time, and exponentially less frequently
248/// as additional failures of the same review site occur. A user may replace
249/// this default handler by using the (`static`)
250/// `bsls::Review::setViolationHandler` administrative method and passing it
251/// (the address of) a function whose signature conforms to the
252/// `bsls::Review::ViolationHandler` `typedef`. This handler may be one of the
253/// other handler methods provided in `bsls::Review`, or a "custom" function
254/// written by the user.
255///
256/// One additional provided class, `bsls::ReviewFailureHandlerGuard`, can be
257/// used to override the review handler within a specific block of code. Note
258/// that this is primarily intended for testing and should be instantiated at a
259/// non-granular level, as the setting and resetting of the handler done by this
260/// RAII class has no provisions in it to handle being used concurrently by
261/// multiple threads.
262///
263/// The primary uses for setting the review handler to a non-default handler are
264/// to get all reviews to behave like some kind of an assertion, or to get
265/// reviews to throw exceptions to facilitate testing. Both of these scenarios
266/// are primarily encountered in test drivers, and the general workflows for
267/// reviews and assertions depend on a policy where deployed production tasks
268/// use the default handlers.
269///
270/// ### Conditional Compilation {#bsls_review-conditional-compilation}
271///
272///
273/// To recap, there are three (mutually compatible) general *build* *targets*:
274/// * `BDE_BUILD_TARGET_OPT`
275/// * `BDE_BUILD_TARGET_SAFE`
276/// * `BDE_BUILD_TARGET_SAFE_2`
277/// seven (mutually exclusive) component-specific *assertion* *levels*:
278/// * `BSLS_ASSERT_LEVEL_ASSERT_SAFE`
279/// * `BSLS_ASSERT_LEVEL_ASSERT`
280/// * `BSLS_ASSERT_LEVEL_ASSERT_OPT`
281/// * `BSLS_ASSERT_LEVEL_NONE`
282/// * `BSLS_ASSERT_LEVEL_ASSUME_OPT`
283/// * `BSLS_ASSERT_LEVEL_ASSUME_ASSERT`
284/// * `BSLS_ASSERT_LEVEL_ASSUME_SAFE`
285/// and four (mutually exclusive) component-specific *review* *levels*:
286/// * `BSLS_REVIEW_LEVEL_REVIEW_SAFE`
287/// * `BSLS_REVIEW_LEVEL_REVIEW`
288/// * `BSLS_REVIEW_LEVEL_REVIEW_OPT`
289/// * `BSLS_REVIEW_LEVEL_NONE`
290/// The above macros can be defined (externally) by the build environment to
291/// affect which of the three *review* *macros*:
292/// * `BSLS_REVIEW_SAFE(boolean-valued expression)`
293/// * `BSLS_REVIEW(boolean-valued expression)`
294/// * `BSLS_REVIEW_OPT(boolean-valued expression)`
295/// will be enabled (i.e., instantiated).
296///
297/// The public interface of this component also provides some additional
298/// intermediate macros to identify how the various `BSLS_REVIEW` macros have
299/// been instantiated. These exist for each level and have the following
300/// suffixes and meanings:
301/// * `IS_ACTIVE`: Defined if the corresponding level is enabled.
302/// * `IS_USED`: Defined if the expressions for the corresponding level need to
303/// be valid (i.e., if they are"'ODR-used").
304///
305/// Putting that together, these 3 macros are defined if the corresponding macro
306/// is enabled:
307/// * `BSLS_REVIEW_SAFE_IS_ACTIVE`
308/// * `BSLS_REVIEW_IS_ACTIVE`
309/// * `BSLS_REVIEW_OPT_IS_ACTIVE`
310///
311/// Finally, three more macros with the `IS_USED` suffix are defined when the
312/// expression for the corresponding macro is going to be compiled. This will
313/// be true if the macro is enabled or if `BSLS_REVIEW_VALIDATE_DISABLED_MACROS`
314/// has been defined.
315/// * `BSLS_REVIEW_SAFE_IS_USED`
316/// * `BSLS_REVIEW_IS_USED`
317/// * `BSLS_REVIEW_OPT_IS_USED`
318///
319/// All of these additional "predicate" macros can be used directly by clients
320/// of this component to conditionally compile code other than just (BSLS)
321/// reviews, but that should be done with care to be sure code compiles and is
322/// compatible across all build modes.
323///
324/// ### Validating Disabled Macro Expressions {#bsls_review-validating-disabled-macro-expressions}
325///
326///
327/// An additional external macro, `BSLS_REVIEW_VALIDATE_DISABLED_MACROS`, can be
328/// defined to control the compile time behavior of @ref bsls_review . Enabling
329/// this macro configures all *disabled* review macros to still instantiate
330/// their predicates (in a non-evaluated context) to be sure that the predicate
331/// is still syntactically valid. This can be used to ensure reviews that are
332/// rarely enabled have valid expressions.
333///
334/// ### Uses for @ref bsls_review {#bsls_review-uses-for-ref-bsls_review}
335///
336///
337/// @ref bsls_review exists primarily as a step towards adding or modifying
338/// instances of @ref bsls_assert macros in code that are already running in
339/// production. New @ref bsls_assert macros are risky to add, and enabled
340/// @ref bsls_assert macros that were not previously enabled is equally risky.
341///
342/// Given code that is already running and deployed, but not "breaking" in
343/// obvious ways, the review process provides a way to see if contracts are
344/// being met in those running processes without risking unexpected aborts
345/// happening in those systems. The contracts that might be getting violated in
346/// already deployed applications need to be fixed and avoided, BUT there exists
347/// no evidence that these violations are currently crashing the system.
348///
349/// In general, @ref bsls_review can also be considered as a way to identify if
350/// deployed code is violating function contracts in some way. Once calling
351/// applications and library code have been altered so all contracts are being
352/// met, uses of @ref bsls_review macros are then changed into the corresponding
353/// @ref bsls_assert macros, which enforce the contracts instead of simply
354/// monitoring them. In some cases, the @ref bsls_review macros can also be
355/// replaced by new behavior, e.g., widening narrow contracts without risking
356/// breaking the expectations of existing applications.
357///
358/// ### Adding New @ref bsls_assert Checks To New Code {#bsls_review-adding-new-ref-bsls_assert-checks-to-new-code}
359///
360///
361/// @ref bsls_review is not appropriate for "new" code that has not yet been
362/// deployed to a production environment; use @ref bsls_assert instead.
363///
364/// ### Adding Assertions With @ref bsls_review {#bsls_review-adding-assertions-with-ref-bsls_review}
365///
366///
367/// The introduction of a new assertion using @ref bsls_review should follow these
368/// steps:
369/// 1. Add the appropriate @ref bsls_review macros to your code.
370/// 2. Commit these changes and make sure all processes using your code get
371/// rebuilt and deployed to production.
372/// 3. Monitor relevant log files for "BSLS_REVIEW failure" messages citing the
373/// location of these reviews.
374/// 4. If any failures occurred, fix the calling code, or widen the contract
375/// being violated (which should be rare).
376/// 5. Wait for sufficient time to pass to be confident that the contract is not
377/// being violated by the current version of the software in production.
378/// 6. Replace `BSLS_REVIEW` with `BSLS_ASSERT` and redeploy.
379///
380/// ### Reducing The Assertion Level For Existing @ref bsls_assert Macros {#bsls_review-reducing-the-assertion-level-for-existing-ref-bsls_assert-macros}
381///
382///
383/// In order to reduce the level of an existing assertion, such as changing a
384/// `BSLS_ASSERT_SAFE` into a `BSLS_ASSERT`, or a `BSLS_ASSERT` into a
385/// `BSLS_ASSERT_OPT`, you should follow a very similar process to the process
386/// for adding a new assertion of that level. There are two possible approaches
387/// that largely depend on how widely deployed the code is that is already built
388/// with the old assertions enabled.
389/// 1. If the existing assertion is not enabled in deployed production code,
390/// such as a `BSLS_ASSERT_SAFE` where client code rarely or never deploys
391/// safe builds, then simply remove the old assertion and start the process
392/// described above of adding in the higher level assertion as if it was a
393/// newly added assertion. Here changing a `BSLS_ASSERT_SAFE` to a
394/// `BSLS_ASSERT` would then begin with changing the `BSLS_ASSERT_SAFE` into
395/// a `BSLS_REVIEW` and continuing as above.
396/// 2. If the existing assertion is depended on in released production code then
397/// the process involved needs to maintain the assertion at the existing
398/// level while adding in the review at the higher level, eventually
399/// including only the assert at the higher level when the process is
400/// complete.
401///
402/// Therefore, the "safest" way to increase an assertion level is to follow
403/// these steps:
404/// 1. Given an existing `BSLS_ASSERT` such as this:
405/// ..
406/// BSLS_ASSERT(some_test());
407/// ..
408/// You can duplicate the test as a `BSLS_REVIEW_OPT`, if the test is very
409/// negligible, like this:
410/// ..
411/// BSLS_ASSERT(some_test());
412/// BSLS_REVIEW_OPT(some_test());
413/// ..
414/// If the duplicated check is unacceptably expensive (which should make you
415/// question making this assertion a `BSLS_ASSERT_OPT` in the first place),
416/// then you can opt for the more cumbersome:
417/// ..
418/// #ifdef BSLS_ASSERT_IS_ACTIVE
419/// BSLS_ASSERT(some_test());
420/// #else
421/// BSLS_REVIEW_OPT(some_test());
422/// #endif
423/// ..
424/// 2. Commit these changes and make sure all processes built at the higher
425/// assertion level are rebuilt and deployed, thus beginning the review
426/// process for this changed assertion.
427/// 3. Follow steps 3-5 of the {Adding Assertions With @ref bsls_review } workflow.
428/// 4. When complete, replace all changes made in step 1 with:
429/// ..
430/// BSLS_ASSERT_OPT(some_test());
431/// ..
432/// 5. Revel in the more widespread use of your existing assertion.
433///
434/// ### Increasing Deployed Assertion Levels With BSLS_REVIEW_LEVEL_ {#bsls_review-increasing-deployed-assertion-levels-with-bsls_review_level_}
435///
436///
437/// A common situation in deployed tasks is that they are built with only
438/// `BSLS_ASSERT_OPT` enabled. To improve the robustness of these applications,
439/// there is then a desire to run them with `BSLS_ASSERT` enabled, or even
440/// `BSLS_ASSERT_SAFE`. Enabling these assertions, however, brings in the same
441/// risks of hard failures for contract violations that adding new assertions
442/// does. `BSLS_REVIEW` provides a process for making this change without
443/// risking aborting processes that were previously "running just fine".
444///
445/// Any explicit setting of the `BSLS_REVIEW_LEVEL` ("review level") to a level
446/// higher than the `BSLS_ASSERT_LEVEL` ("assert level") will not only enable
447/// the `BSLS_REVIEW` macros at that level, but it will turn all `BSLS_ASSERT`
448/// macros at that level into reviews as well, and disable any assumption of
449/// `BSLS_ASSERT` assertions. Given a task that is built with an assertion
450/// level of `OPT`, if you set the review level to `REVIEW` you will then get
451/// logs and notifications of any failed `BSLS_ASSERT` checks, but those failing
452/// checks will not immediately abort your application.
453///
454/// So the process for deploying an application with a higher assertion level is
455/// to follow these steps:
456/// 1. Rebuild the task with the review level set to the desired assertion
457/// level, using `BSLS_REVIEW_LEVEL_REVIEW_OPT`, `BSLS_REVIEW_LEVEL_REVIEW`,
458/// or `BSLS_REVIEW_LEVEL_REVIEW_SAFE`.
459/// 2. Deploy the task.
460/// 3. Monitor relevant log files for "BSLS_REVIEW failure" messages citing the
461/// location of these reviews.
462/// 4. Once all review failures have been addressed and no failures are logged
463/// for a "sufficient" time, remove the explicitly set `BSLS_REVIEW_LEVEL`
464/// from your build and change to set an explicit `BSLS_ASSERT_LEVEL` at your
465/// new level.
466/// 5. Deploy your newly built application with increased enabled defensive
467/// checks.
468/// 6. Revel in the comfort of taking advantage of the additional defensive
469/// checks now enabled in your code.
470///
471/// ### Checking Library Usage Before Changing it With @ref bsls_review {#bsls_review-checking-library-usage-before-changing-it-with-ref-bsls_review}
472///
473///
474/// Occasionally, given code that is in use in production, you may come across a
475/// case that makes no sense but that you want to reimplement with altered
476/// behavior. The previous behavior might have been out of contract or just
477/// seemingly nonsensical, but you are not confident that no one is actually
478/// running code that executes that behavior and relies on it.
479///
480/// @ref bsls_review here provides a way to insert a review that checks if the code
481/// in question is ever being invoked. To do that, follow these steps:
482/// 1. Depending on the structure of the code you want to monitor, add a
483/// `BSLS_REVIEW_INVOKE` or a `BSLS_REVIEW_OPT` with a check that will fail
484/// on the condition you want to monitor. Use these macros as they will be
485/// enabled in almost all build modes.
486/// 2. Commit your changes and get the applications using your code deployed.
487/// 3. If any code hits your review, assess it for why and fix the calling code
488/// or re-assess the behavior you want to change.
489/// 4. Once "sufficient" time has passed with no review failures, remove the
490/// @ref bsls_review checks entirely.
491/// 5. Make changes to your code's behavior that impact only those states where
492/// previously your review would have failed. Check in and deploy those
493/// changes.
494/// 6. Revel in safely having deployed a Liskov-substitutable version of your
495/// library with exciting and new behavior.
496///
497/// ### Concerns When Adding Reviews or Assertions {#bsls_review-concerns-when-adding-reviews-or-assertions}
498///
499///
500/// 1. Performance: In general, a new @ref bsls_review check will perform exactly
501/// the same as a @ref bsls_assert with the same predicate. One subtle
502/// difference is that apparently working software can contain failing
503/// @ref bsls_review checks logging failures that may be ignored (whereas
504/// @ref bsls_assert failures are designed to be hard to ignore). Handling
505/// these failures requires maintaining the failure count using atomic
506/// operations that may negatively impact performance if checks are failing
507/// (and ignored) in performance-sensitive code. Failing checks should
508/// always be addressed as promptly as possible.
509/// 2. Downstream Linking: For a library developer, part of the review rollout
510/// process will rely heavily on users of your library relinking multiple
511/// times during the process of adding reviews. One might assume that this
512/// means the verification that a review is not failing can extend an
513/// indefinite amount of time. The better overall policy is to realize that,
514/// just like library users can opt-in to rebuilding their tasks more often,
515/// the stability benefits of being involved in the review process by
516/// relinking and rolling out more often are opt-in as well. For tasks that
517/// are rebuilt very infrequently, they will simply have to accept that
518/// library misuse on their end might result in crashes due to asserts that
519/// were introduced between their own too-infrequent releases.
520/// 3. Unit Testing with Reviews: In general, unit test log files are rarely
521/// monitored or read, so a failing `BSLS_REVIEW` is unlikely to be caught
522/// during unit tests. Test drivers should almost always set the review
523/// handler to the abort handler so any failed reviews are caught immediately
524/// as test failures.
525/// 4. Sufficient Time: All of the review-related workflows mention running
526/// reviewed code for "sufficient" time to know the check is not failing.
527/// "Sufficient" time will vary by application.
528///
529/// ## Usage {#bsls_review-usage}
530///
531///
532///
533/// ### Example 1: Adding BSLS_ASSERT To An Existing Function {#bsls_review-example-1-adding-bsls_assert-to-an-existing-function}
534///
535///
536/// Suppose you have an existing function, already deployed to production, that
537/// was not written with defensive programming in mind. In order to increase
538/// robustness, you would like to add `BSLS_ASSERT` macros to this function that
539/// match the contract originally written when this function was initially
540/// released.
541///
542/// For example, consider the function `myFunc` in the class `FunctionsV1` that
543/// was implemented like this:
544/// @code
545/// my_functions.h
546/// ...
547///
548/// class FunctionsV1 {
549/// // ...
550/// public:
551/// // ...
552///
553/// static int myFunc(int x, int y);
554/// // Do something with the specified positive integers 'x' and 'y'.
555/// };
556///
557/// inline int FunctionsV1::myFunc(int x, int y)
558/// {
559/// int output = 0;
560/// // ... do stuff with 'x' and 'y'.
561/// return output;
562/// }
563/// @endcode
564/// Notice that there are no checks on `x` and `y` within `myFunc` and no
565/// assertions to detect use of `myFunc` outside of its contract. On the other
566/// hand, `myFunc` is part of legacy code that has been in use extensively for
567/// years or decades, so clearly this is not causing a problem (yet).
568///
569/// Upon reviewing this class you realize that `myFunc` produces random results
570/// for values of `x` or `y` less than 0. You, however, do not have enough
571/// information to conclude that no one is calling it with negative values and
572/// just using the bad results unknowingly. There are a number of possibilities
573/// for how the result of this undefined behavior might be going unnoticed.
574/// * The invalid value might be discarded by a bounds check later in the
575/// process.
576/// * The invalid value may only result in a small glitch the users have not
577/// noticed or ignored.
578/// * The resulting value may actually be valid, but allowing negative input
579/// for `x` and `y` may preclude potential future development in ways we do
580/// not want to allow.
581/// All of these are bad, but adding in checks with `BSLS_ASSERT` that would
582/// replace these bad behaviors by process termination would turn silent errors
583/// into loud errors (potentially worse). On the other hand, by not adding
584/// `BSLS_ASSERT` checks we permit future misuses of this function, which may
585/// not be innocuous, to potentially reach production systems. `BSLS_REVIEW`
586/// here serves as a bridge, from the current state of `myFunc` (entirely
587/// unchecked) to the ideal state of `myFunc` (where misuse is caught loudly and
588/// immediately through `BSLS_ASSERT`), following a path that doesn't risk
589/// turning an un-noticed or irrelevant error into one that will significantly
590/// hinder ongoing business.
591///
592/// The solution to this is to *initially* reimplement `myFunc` using
593/// `BSLS_REVIEW` like this:
594/// @code
595/// my_functions.h
596/// ...
597/// #include <bsls_review.h>
598/// ...
599///
600/// class FunctionsV2 {
601/// // ...
602/// public:
603/// // ...
604///
605/// static int myFunc(int x, int y);
606/// // Do something with the specified 'x' and 'y'. The behavior is
607/// // undefined unless 'x > 0' and 'y > 0'.
608/// };
609///
610/// inline int FunctionsV2::myFunc(int x, int y)
611/// {
612/// BSLS_REVIEW(x > 0);
613/// BSLS_REVIEW(y > 0);
614/// int output = 0;
615/// // ... do stuff with 'x' and 'y'.
616/// return output;
617/// }
618/// @endcode
619/// Now you can deploy this code to production and then begin reviewing logs.
620/// The log messages you should look for are those produced by `bsls::Review`s
621/// default review failure handler and will be similar to:
622/// @code
623/// ERROR myfunction.h:17 BSLS_REVIEW failure (myfunction.h:17 level:R-DBG):
624/// 'x > 0' Please run "/bb/bin/showfunc.tsk ...
625/// @endcode
626/// `showfunc.tsk` is a Bloomberg application that can be used (along with the
627/// task binary) to convert the reported stack addresses to a more traditional
628/// stack trace with a function call stack.
629///
630/// It is important to note that `BSLS_REVIEW` is purely informative, and adding
631/// a review will not adversely affect behavior, and may in fact alert the
632/// library author to common client misconceptions about the intended behavior.
633///
634/// For example, let's say actual usage makes it clear that users expect 0 to be
635/// valid values for the arguments to `myFunc`, and nothing in the
636/// implementation prevents us from accepting 0 as input and producing the
637/// answer clients expect. Instead of changing all the clients, we may instead
638/// choose to change the function contract (and implemented checks):
639/// @code
640/// my_functions.h
641/// ...
642/// #include <bsls_review.h>
643/// ...
644///
645/// class FunctionsV3 {
646/// // ...
647/// public:
648/// // ...
649///
650/// static int myFunc(int x, int y);
651/// // Do something with the specified 'x' and 'y'. The behavior is
652/// // undefined unless 'x >= 0' and 'y >= 0'.
653/// };
654///
655/// inline int FunctionsV3::myFunc(int x, int y)
656/// {
657/// BSLS_REVIEW(x >= 0);
658/// BSLS_REVIEW(y >= 0);
659/// int output = 0;
660/// // ... do stuff with 'x' and 'y'.
661/// return output;
662/// }
663/// @endcode
664/// Finally, at some point, the implementation of `myFunc` using `BSLS_REVIEW`
665/// has been running a suitable amount of time that you are comfortable
666/// transitioning the use of @ref bsls_review to @ref bsls_assert . We now use our
667/// favorite text editor or script to replace "BSLS_REVIEW" with "BSLS_ASSERT":
668/// @code
669/// my_functions.h
670/// ...
671/// #include <bsls_assert.h>
672/// ...
673///
674/// class FunctionsV4 {
675/// // ...
676/// public:
677/// // ...
678///
679/// static int myFunc(int x, int y);
680/// // Do something with the specified 'x' and 'y'. The behavior is
681/// // undefined unless 'x >= 0' and 'y >= 0'.
682/// };
683///
684/// inline int FunctionsV4::myFunc(int x, int y)
685/// {
686/// BSLS_ASSERT(x >= 0);
687/// BSLS_ASSERT(y >= 0);
688/// int output = 0;
689/// // ... do stuff with 'x' and 'y'.
690/// return output;
691/// }
692/// @endcode
693/// At this point, any contract violations in the use of `myFunc` in new code
694/// will be caught immediately (i.e., in appropriate build modes).
695/// @}
696/** @} */
697/** @} */
698
699/** @addtogroup bsl
700 * @{
701 */
702/** @addtogroup bsls
703 * @{
704 */
705/** @addtogroup bsls_review
706 * @{
707 */
708
709#include <bsls_annotation.h>
710#include <bsls_assertimputil.h>
712#include <bsls_buildtarget.h>
714#include <bsls_keyword.h>
715#include <bsls_performancehint.h>
716#include <bsls_platform.h>
717
718#ifdef BSLS_ASSERT_USE_CONTRACTS
719#include <contract>
720#endif
721
722 // =============================
723 // Checks for Pre-Defined macros
724 // =============================
725
726#if defined(BSLS_REVIEW)
727#error BSLS_REVIEW is already defined!
728#endif
729
730#if defined(BSLS_REVIEW_REVIEW_IMP)
731#error BSLS_REVIEW_REVIEW_IMP is already defined!
732#endif
733
734#if defined(BSLS_REVIEW_REVIEW_COUNT_IMP)
735#error BSLS_REVIEW_REVIEW_COUNT_IMP is already defined!
736#endif
737
738#if defined(BSLS_REVIEW_DISABLED_IMP)
739#error BSLS_REVIEW_DISABLED_IMP is already defined!
740#endif
741
742#if defined(BSLS_REVIEW_INVOKE)
743#error BSLS_REVIEW_INVOKE is already defined!
744#endif
745
746#if defined(BSLS_REVIEW_UNREACHABLE_IMP)
747#error BSLS_REVIEW_UNREACHABLE_IMP is already defined!
748#endif
749
750#if defined(BSLS_REVIEW_UNREACHABLE_DISABLED_IMP)
751#error BSLS_REVIEW_UNREACHABLE_DISABLED_IMP is already defined!
752#endif
753
754#if defined(BSLS_REVIEW_IS_ACTIVE)
755#error BSLS_REVIEW_IS_ACTIVE is already defined!
756#endif
757
758#if defined(BSLS_REVIEW_IS_USED)
759#error BSLS_REVIEW_IS_USED is already defined!
760#endif
761
762#if defined(BSLS_REVIEW_OPT)
763#error BSLS_REVIEW_OPT is already defined!
764#endif
765
766#if defined(BSLS_REVIEW_OPT_IS_ACTIVE)
767#error BSLS_REVIEW_OPT_IS_ACTIVE is already defined!
768#endif
769
770#if defined(BSLS_REVIEW_OPT_IS_USED)
771#error BSLS_REVIEW_OPT_IS_USED is already defined!
772#endif
773
774#if defined(BSLS_REVIEW_SAFE)
775#error BSLS_REVIEW_SAFE is already defined!
776#endif
777
778#if defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
779#error BSLS_REVIEW_SAFE_IS_ACTIVE is already defined!
780#endif
781
782#if defined(BSLS_REVIEW_SAFE_IS_USED)
783#error BSLS_REVIEW_SAFE_IS_USED is already defined!
784#endif
785
786#if defined(BSLS_REVIEW_SAFE_UNREACHABLE)
787#error BSLS_REVIEW_SAFE_UNREACHABLE is already defined!
788#endif
789
790#if defined(BSLS_REVIEW_UNREACHABLE)
791#error BSLS_REVIEW_UNREACHABLE is already defined!
792#endif
793
794#if defined(BSLS_REVIEW_OPT_UNREACHABLE)
795#error BSLS_REVIEW_OPT_UNREACHABLE is already defined!
796#endif
797
798 // =================================
799 // (BSLS) "REVIEW" Macro Definitions
800 // =================================
801
802// Implementation Note: We wrap the 'if' statement below in a (seemingly
803// redundant) do-while-false loop to require, syntactically, a trailing
804// semicolon, and to ensure that the macro behaves properly in an if-then-else
805// context -- even if one forgets to wrap, with curly braces, the body of an
806// 'if' having just a single 'BSLS_REVIEW*' statement.
807
808 // =============================================
809 // Factored Implementation for Internal Use Only
810 // =============================================
811
812#if !(defined(BSLS_REVIEW_LEVEL_REVIEW_SAFE) || \
813 defined(BSLS_REVIEW_LEVEL_REVIEW) || \
814 defined(BSLS_REVIEW_LEVEL_REVIEW_OPT) || \
815 defined(BSLS_REVIEW_LEVEL_NONE))
816// In order to replicate the control logic of 'BSLS_ASSERT', if there has been
817// no explicit review level set we check to see if there has been an explicit
818// assert level set. If so, we act as though the review level has been
819// explicitly set to the same thing (instead of just basing the review level
820// off of only the build mode).
821 #if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE)
822 #define BSLS_REVIEW_LEVEL_REVIEW_SAFE
823 #define BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED 0
824 #elif defined(BSLS_ASSERT_LEVEL_ASSERT)
825 #define BSLS_REVIEW_LEVEL_REVIEW
826 #define BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED 0
827 #elif defined(BSLS_ASSERT_LEVEL_ASSERT_OPT)
828 #define BSLS_REVIEW_LEVEL_REVIEW_OPT
829 #define BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED 0
830 #elif defined(BSLS_ASSERT_LEVEL_NONE) || \
831 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE) || \
832 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT) || \
833 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
834 #define BSLS_REVIEW_LEVEL_NONE
835 #define BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED 0
836 #else
837 // Only here, with no explicit review level OR assertion level, does
838 // this macro finally get set to true, which will trigger
839 // buildtarget-based logic for macro configuration
840 #define BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED 1
841 #endif
842#else
843 #define BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED 0
844#endif
845
846 // ============================
847 // BSLS_REVIEW_REVIEW_COUNT_IMP
848 // ============================
849
850// This macro is defined in order to maintain a static 'count' where a
851// 'BSLS_REVIEW' is used. When possible, this is done inside a lamba (which
852// will only be invoked when a violation happens) in order to facilitate use
853// within 'constexpr' functions.
854
855#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP14
856 #define BSLS_REVIEW_REVIEW_COUNT_IMP \
857 const int lastCount = BloombergLP::bsls::Review::updateCount( \
858 []{ \
859 static BloombergLP::bsls::Review::Count count = {0}; \
860 return &count; \
861 }() );
862#else
863 #define BSLS_REVIEW_REVIEW_COUNT_IMP \
864 static BloombergLP::bsls::Review::Count count = {0}; \
865 const int lastCount = BloombergLP::bsls::Review::updateCount(&count);
866#endif
867
868 // ======================
869 // BSLS_REVIEW_REVIEW_IMP
870 // ======================
871
872#ifdef BSLS_ASSERT_USE_CONTRACTS
873#define BSLS_REVIEW_REVIEW_IMP(X,LVL) [[ assert check_maybe_continue : X ]]
874
875#ifdef BSLS_REVIEW_VALIDATE_DISABLED_MACROS
876#define BSLS_REVIEW_DISABLED_IMP(X,LVL) [[ assert ignore : X ]]
877#else
878#define BSLS_REVIEW_DISABLED_IMP(X,LVL) [[ assert : true ]]
879#endif
880
881#else // BSLS_ASSERT_USE_CONTRACTS
882
883#define BSLS_REVIEW_REVIEW_IMP(X,LVL) do { \
884 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!(X))) { \
885 BSLS_PERFORMANCEHINT_UNLIKELY_HINT; \
886 BSLS_REVIEW_REVIEW_COUNT_IMP; \
887 BloombergLP::bsls::Review::invokeHandler( \
888 BloombergLP::bsls::ReviewViolation(#X, \
889 BSLS_ASSERTIMPUTIL_FILE, \
890 BSLS_ASSERTIMPUTIL_LINE, \
891 LVL, \
892 lastCount)); \
893 } \
894 } while (false)
895
896#ifdef BSLS_REVIEW_VALIDATE_DISABLED_MACROS
897#define BSLS_REVIEW_DISABLED_IMP(X,LVL) do { \
898 static_cast<void>(sizeof(!(X)?true:false)); \
899 } while (false)
900#else
901#define BSLS_REVIEW_DISABLED_IMP(X,LVL) do {} while (false)
902#endif
903
904#endif
905
906 // ==================
907 // BSLS_REVIEW_INVOKE
908 // ==================
909
910// 'BSLS_REVIEW_INVOKE' is always active.
911#define BSLS_REVIEW_INVOKE(X) do { \
912 BSLS_REVIEW_REVIEW_COUNT_IMP; \
913 BloombergLP::bsls::Review::invokeHandler( \
914 BloombergLP::bsls::ReviewViolation( \
915 X, \
916 BSLS_ASSERTIMPUTIL_FILE, \
917 BSLS_ASSERTIMPUTIL_LINE, \
918 BloombergLP::bsls::Review::k_LEVEL_INVOKE, \
919 lastCount)); \
920 } while (false)
921
922 // ========================
923 // BSLS_REVIEW_UNREACHABLE
924 // ========================
925
926// 'BSLS_REVIEW_UNREACHABLE_IMP' invokes the review handler unconditionally
927// with the specified message 'X'. Unlike 'BSLS_REVIEW_REVIEW_IMP', this macro
928// does not check a condition -- it always invokes the handler when reached.
929
930#define BSLS_REVIEW_UNREACHABLE_IMP(X,LVL) do { \
931 BSLS_REVIEW_REVIEW_COUNT_IMP; \
932 BloombergLP::bsls::Review::invokeHandler( \
933 BloombergLP::bsls::ReviewViolation( \
934 X, \
935 BSLS_ASSERTIMPUTIL_FILE, \
936 BSLS_ASSERTIMPUTIL_LINE, \
937 LVL, \
938 lastCount)); \
939 } while (false)
940
941// 'BSLS_REVIEW_UNREACHABLE_DISABLED_IMP' does nothing except ensures that `X`
942// is a valid expression convertable to 'const char *'. It is used when the
943// corresponding UNREACHABLE macro is disabled for the current build mode.
944
945#define BSLS_REVIEW_UNREACHABLE_DISABLED_IMP(X,LVL) do { \
946 (void)sizeof(static_cast<const char*>(X)); \
947} while (false)
948
949 // ================
950 // BSLS_REVIEW_SAFE
951 // ================
952
953// Determine if 'BSLS_REVIEW_SAFE' should be active.
954
955#if defined(BSLS_REVIEW_LEVEL_REVIEW_SAFE) \
956 || BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED && ( \
957 defined(BDE_BUILD_TARGET_SAFE_2) || \
958 defined(BDE_BUILD_TARGET_SAFE) )
959
960 #define BSLS_REVIEW_SAFE_IS_ACTIVE // also usable directly in client code
961#endif
962
963// Indicate when 'BSLS_REVIEW_SAFE' arguments will be ODR-used.
964#if defined(BSLS_REVIEW_SAFE_IS_ACTIVE) || \
965 defined(BSLS_REVIEW_VALIDATE_DISABLED_MACROS)
966 #define BSLS_REVIEW_SAFE_IS_USED
967#endif
968
969// Define 'BSLS_REVIEW_SAFE' accordingly.
970
971#if defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
972 #define BSLS_REVIEW_SAFE(X) BSLS_REVIEW_REVIEW_IMP( \
973 X, \
974 BloombergLP::bsls::Review::k_LEVEL_SAFE)
975#else
976 #define BSLS_REVIEW_SAFE(X) BSLS_REVIEW_DISABLED_IMP( \
977 X, \
978 BloombergLP::bsls::Review::k_LEVEL_SAFE)
979#endif
980
981// Define 'BSLS_REVIEW_SAFE_UNREACHABLE' accordingly.
982
983#if defined(BSLS_REVIEW_SAFE_IS_ACTIVE)
984 #define BSLS_REVIEW_SAFE_UNREACHABLE(X) BSLS_REVIEW_UNREACHABLE_IMP( \
985 X, \
986 BloombergLP::bsls::Review::k_LEVEL_SAFE)
987#else
988 #define BSLS_REVIEW_SAFE_UNREACHABLE(X) \
989 BSLS_REVIEW_UNREACHABLE_DISABLED_IMP( \
990 X, \
991 BloombergLP::bsls::Review::k_LEVEL_SAFE)
992#endif
993
994 // ===========
995 // BSLS_REVIEW
996 // ===========
997
998// Determine if 'BSLS_REVIEW' should be active.
999
1000#if defined(BSLS_REVIEW_LEVEL_REVIEW_SAFE) || \
1001 defined(BSLS_REVIEW_LEVEL_REVIEW) \
1002 || BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED && ( \
1003 defined(BDE_BUILD_TARGET_SAFE_2) || \
1004 defined(BDE_BUILD_TARGET_SAFE) || \
1005 !defined(BDE_BUILD_TARGET_OPT) )
1006
1007 #define BSLS_REVIEW_IS_ACTIVE // also usable directly in client code
1008#endif
1009
1010// Indicate when 'BSLS_REVIEW' arguments will be ODR-used.
1011#if defined(BSLS_REVIEW_IS_ACTIVE) || \
1012 defined(BSLS_REVIEW_VALIDATE_DISABLED_MACROS)
1013 #define BSLS_REVIEW_IS_USED
1014#endif
1015
1016// Define 'BSLS_REVIEW' accordingly.
1017
1018#if defined(BSLS_REVIEW_IS_ACTIVE)
1019 #define BSLS_REVIEW(X) BSLS_REVIEW_REVIEW_IMP( \
1020 X, \
1021 BloombergLP::bsls::Review::k_LEVEL_REVIEW)
1022#else
1023 #define BSLS_REVIEW(X) BSLS_REVIEW_DISABLED_IMP( \
1024 X, \
1025 BloombergLP::bsls::Review::k_LEVEL_REVIEW)
1026#endif
1027
1028// Define 'BSLS_REVIEW_UNREACHABLE' accordingly.
1029
1030#if defined(BSLS_REVIEW_IS_ACTIVE)
1031 #define BSLS_REVIEW_UNREACHABLE(X) BSLS_REVIEW_UNREACHABLE_IMP( \
1032 X, \
1033 BloombergLP::bsls::Review::k_LEVEL_REVIEW)
1034#else
1035 #define BSLS_REVIEW_UNREACHABLE(X) \
1036 BSLS_REVIEW_UNREACHABLE_DISABLED_IMP( \
1037 X, \
1038 BloombergLP::bsls::Review::k_LEVEL_REVIEW)
1039#endif
1040
1041 // ===============
1042 // BSLS_REVIEW_OPT
1043 // ===============
1044
1045// Determine if 'BSLS_REVIEW_OPT' should be active.
1046
1047#if !defined(BSLS_REVIEW_LEVEL_NONE)
1048 #define BSLS_REVIEW_OPT_IS_ACTIVE // also usable directly in client code
1049#endif
1050
1051// Indicate when 'BSLS_REVIEW_OPT' arguments will be ODR-used.
1052#if defined(BSLS_REVIEW_OPT_IS_ACTIVE) || \
1053 defined(BSLS_REVIEW_VALIDATE_DISABLED_MACROS)
1054 #define BSLS_REVIEW_OPT_IS_USED
1055#endif
1056
1057// Define 'BSLS_REVIEW_OPT' accordingly.
1058
1059#if defined(BSLS_REVIEW_OPT_IS_ACTIVE)
1060 #define BSLS_REVIEW_OPT(X) BSLS_REVIEW_REVIEW_IMP( \
1061 X, \
1062 BloombergLP::bsls::Review::k_LEVEL_OPT)
1063#else
1064 #define BSLS_REVIEW_OPT(X) BSLS_REVIEW_DISABLED_IMP( \
1065 X, \
1066 BloombergLP::bsls::Review::k_LEVEL_OPT)
1067#endif
1068
1069// Define 'BSLS_REVIEW_OPT_UNREACHABLE' accordingly.
1070
1071#if defined(BSLS_REVIEW_OPT_IS_ACTIVE)
1072 #define BSLS_REVIEW_OPT_UNREACHABLE(X) BSLS_REVIEW_UNREACHABLE_IMP( \
1073 X, \
1074 BloombergLP::bsls::Review::k_LEVEL_OPT)
1075#else
1076 #define BSLS_REVIEW_OPT_UNREACHABLE(X) \
1077 BSLS_REVIEW_UNREACHABLE_DISABLED_IMP( \
1078 X, \
1079 BloombergLP::bsls::Review::k_LEVEL_OPT)
1080#endif
1081
1082// A nested include guard is needed to support the test driver implementation.
1083#ifndef BSLS_REVIEW_RECURSIVELY_INCLUDED_TESTDRIVER_GUARD
1084#define BSLS_REVIEW_RECURSIVELY_INCLUDED_TESTDRIVER_GUARD
1085
1086
1087namespace bsls {
1088
1089 // =====================
1090 // class ReviewViolation
1091 // =====================
1092
1093/// This class is an unconstrained *in-core* value-semantic class that
1094/// characterizes the details of a review failure that has occurred.
1095///
1096/// See @ref bsls_review
1098
1099 // DATA
1100 const char *d_comment_p; // the comment associated with the violation,
1101 // generally representing the expression that
1102 // failed
1103
1104 const char *d_fileName_p; // the name of the file where the violation
1105 // occurred
1106
1107 int d_lineNumber; // the line number where the violation
1108 // occurred
1109
1110 const char *d_reviewLevel_p; // the level and type of the violation that
1111 // occurred, generally one of the 'k_LEVEL'
1112 // constants defined in 'bsls::Review' or
1113 // 'bsls::Assert'
1114
1115 int d_count; // the number of times that a particular
1116 // failure has happened in the running
1117 // process
1118
1119 public:
1120 // CREATORS
1121
1122 /// Create a `ReviewViolation` with the specified `comment`, `fileName`, `lineNumber`, `reviewLevel`, and `count`.
1123 ///
1124 /// \note Note that the supplied
1125 /// `reviewLevel` will usually be one of the `k_LEVEL` constants defined
1126 /// in `bsls::Review` (or see `bsls::Assert` for the levels that will be
1127 /// passed for assertions that are being reviewed).
1129 ReviewViolation(const char *comment,
1130 const char *fileName,
1131 int lineNumber,
1132 const char *reviewLevel,
1133 int count);
1134
1135 // ACCESSORS
1136
1137 /// Return the `comment` attribute of this object.
1138 const char *comment() const;
1139
1140 /// Return the `count` attribute of this object.
1141 int count() const;
1142
1143 /// Return the `fileName` attribute of this object.
1144 const char *fileName() const;
1145
1146 /// Return the `lineNumber` attribute of this object.
1147 int lineNumber() const;
1148
1149 /// Return the `reviewLevel` attribute of this object.
1150 const char *reviewLevel() const;
1151};
1152
1153 // ============
1154 // class Review
1155 // ============
1156
1157/// This "utility" class maintains a pointer containing the address of the
1158/// current review-failure handler function (of type
1159/// `Review::ViolationHandler`) and provides methods to administer this
1160/// function pointer. The `invokeHandler` method calls the
1161/// currently-installed failure handler. The default installed handler is
1162/// the `Review::failByLog` function.
1163///
1164/// This class also provides a suite of standard failure-handler functions
1165/// that are suitable to be installed as the current `Review::ViolationHandler` function.
1166///
1167/// \note Note that clients are free to
1168/// install any of these ("off-the-shelf") handlers, or to provide their own
1169/// ("custom") review-failure handler function when using this facility.
1170/// Also note that review-failure handlers CAN return, unlike assertion
1171/// failure handlers, though not returning (thus escalating review behavior
1172/// implicitly to the level of asserts) is acceptable.
1173///
1174/// Finally, this class defines the constant strings that are used as the
1175/// `reviewLevel` in `ReviewViolation`s associated with failed `BSLS_REVIEW`
1176/// invocations.
1177///
1178/// See @ref bsls_review
1179class Review {
1180
1181 public:
1182 // TYPES
1183
1184 /// `Count` is an alias for an atomic integer. All @ref bsls_review macros
1185 /// declare a static local `Count` variable that is used to track how
1186 /// many times that review has failed. This count gets updated through
1187 /// the `bsls::Review::updateCount` function.
1188 typedef bsls::AtomicOperations::AtomicTypes::Int Count;
1189
1190 /// `ViolationHandler` is an alias for a pointer to a function returning
1191 /// `void`, and taking, as a parameter, a `const` reference to a
1192 /// `ReviewViolation` instance. For example:
1193 /// @code
1194 /// void myHandler(const ReviewViolation& violation);
1195 /// @endcode
1196 typedef void (*ViolationHandler)(const ReviewViolation&);
1197
1198 private:
1199 // FRIENDS
1201
1202 // PRIVATE CLASS METHODS
1203
1204 /// Make the specified handler `function` the current review-failure
1205 /// handler. This method has effect regardless of whether the
1206 /// `lockReviewAdministration` method has been called.
1207 static void setViolationHandlerRaw(Review::ViolationHandler function);
1208
1209 public:
1210 // PUBLIC CONSTANTS
1211
1212 // 'reviewLevel' Strings
1213
1214 static const char k_LEVEL_SAFE[];
1215 static const char k_LEVEL_OPT[];
1216 static const char k_LEVEL_REVIEW[];
1217 static const char k_LEVEL_INVOKE[];
1218
1219 // CLASS METHODS
1220
1221 // Administrative Methods
1222
1223 /// Make the specified handler `function` the current review-failure
1224 /// handler. This method has no effect if the
1225 /// `lockReviewAdministration` method has been called.
1227
1228 /// Return the address of the currently installed review-failure handler function.
1229 ///
1230 /// \note Note that the initial value of the review-failure handler
1231 /// is the `Review::failByLog` method.
1233
1234 /// Disable all subsequent calls to `setViolationHandler`.
1235 ///
1236 /// \note Note that this method has no effect on the behavior of a
1237 /// `ReviewFailureHandlerGuard` object.
1239
1240 // Dispatcher Methods (called from within macros)
1241
1242 /// Increment the specified `count` and return the new value. Instead
1243 /// of overflowing, when the value is sufficiently large, decrement the
1244 /// value so that large values repeat periodically.
1245 static int updateCount(Count *count);
1246
1247 /// Invoke the currently installed review-failure handler function with the specified `violation` as its argument.
1248 ///
1249 /// \note Note that this function
1250 /// is intended for use by the (BSLS) "REVIEW" macros, but may also be
1251 /// called by clients directly as needed.
1252 static void invokeHandler(const ReviewViolation& violation);
1253
1254#ifdef BSLS_ASSERT_USE_CONTRACTS
1255 static void invokeLanguageContractHandler(
1256 const std::contract_violation& violation);
1257 // Call 'invokeHandler' with a 'ReviewViolation' with properties from
1258 // the specified 'violation', tracking a 'count' of repeated violations
1259 // statically.
1260#endif
1261
1262 // Standard Review-Failure Handlers
1263
1264 /// Log a message to `stdout` that an assertion has failed with
1265 /// information on the failure from the specified `violation`. A
1266 /// suitably formatted "cheap stack" is included in the log message that
1267 /// identifies the call site where the failure occurred.
1268 static void failByLog(const ReviewViolation& violation);
1269
1270 /// Emulate the invocation of the standard `assert` macro with a `false`
1271 /// argument, using the specified `violation` to generate an output
1272 /// message and then, after logging, unconditionally abort.
1274 static void failByAbort(const ReviewViolation& violation);
1275
1276 /// Use the specified `violation` to generate an output message and then, after logging, spin in an infinite loop.
1277 ///
1278 /// \note Note that this
1279 /// handler function is useful for hanging a process so that a debugger
1280 /// may be attached to it.
1282 static void failBySleep(const ReviewViolation& violation);
1283
1284 /// Throw an `AssertTestException` (whose attributes are `comment`,
1285 /// `filename`, and `lineNumber` from the specified `violation`),
1286 /// provided that `BDE_BUILD_TARGET_EXC` is defined; otherwise, log an
1287 /// appropriate message and abort the program (similar to
1288 /// `failByAbort`).
1290 static void failByThrow(const ReviewViolation& violation);
1291};
1292
1293 // ===============================
1294 // class ReviewFailureHandlerGuard
1295 // ===============================
1296
1297/// An object of this class saves the current review handler and installs
1298/// the one specified on construction. On destruction, the original review handler is restored.
1299///
1300/// \note Note that two objects of this class cannot be
1301/// safely used concurrently from two separate threads (but may of course
1302/// appear sequentially, including in nested blocks and function invocations within a single thread).
1303///
1304/// \note Note that the behavior of objects of this
1305/// class is unaffected by the (`static`) `Review::lockReviewAdministration`
1306/// method (i.e., the temporary replacement will occur, regardless of
1307/// whether that method has been invoked).
1308///
1309/// See @ref bsls_review
1311
1312 // DATA
1313 Review::ViolationHandler d_original; // original (restored at destruction)
1314
1315 private:
1316 // NOT IMPLEMENTED
1319
1320 public:
1321 // CREATORS
1322
1323 /// Create a guard object that installs the specified `temporary` review
1324 /// failure handler and automatically restores the original handler on
1325 /// destruction.
1327
1328 /// Restore the failure handler that was in place when this object was
1329 /// created and destroy this guard.
1331};
1332
1333// ============================================================================
1334// INLINE FUNCTION DEFINITIONS
1335// ============================================================================
1336
1337 // ---------------------
1338 // class ReviewViolation
1339 // ---------------------
1340
1341// CREATORS
1343inline
1345 const char *fileName,
1346 int lineNumber,
1347 const char *reviewLevel,
1348 int count)
1349: d_comment_p((comment == 0) ? "" : comment)
1350, d_fileName_p((fileName == 0) ? "" : fileName)
1351, d_lineNumber(lineNumber)
1352, d_reviewLevel_p((reviewLevel == 0) ? "" : reviewLevel)
1353, d_count(count)
1354{
1355}
1356
1357// ACCESSORS
1358inline
1359const char *ReviewViolation::comment() const
1360{
1361 return d_comment_p;
1362}
1363
1364inline
1366{
1367 return d_count;
1368}
1369
1370inline
1371const char *ReviewViolation::fileName() const
1372{
1373 return d_fileName_p;
1374}
1375
1376inline
1378{
1379 return d_lineNumber;
1380}
1381
1382inline
1384{
1385 return d_reviewLevel_p;
1386}
1387
1388} // close package namespace
1389
1390
1391#endif // deeper include guard
1392
1393 // ========================================================
1394 // UNDEFINE THE LOCALLY-SCOPED IMPLEMENTATION DETAIL MACROS
1395 // ========================================================
1396
1397#undef BSLS_REVIEW_NO_REVIEW_MACROS_DEFINED
1398
1399 // =========================================
1400 // IMPLEMENTATION USING THE C++ PREPROCESSOR
1401 // =========================================
1402//
1403// At most one of the following review levels may be set during the compilation
1404// of any component that includes 'bsls_review.h':
1405//..
1406// BSLS_REVIEW_LEVEL_REVIEW_SAFE
1407// BSLS_REVIEW_LEVEL_REVIEW
1408// BSLS_REVIEW_LEVEL_REVIEW_OPT
1409// BSLS_REVIEW_LEVEL_NONE
1410//..
1411// ----------------------------------------------------------------------------
1412
1413#if defined(BSLS_REVIEW_LEVEL_REVIEW_SAFE) && \
1414 defined(BSLS_REVIEW_LEVEL_REVIEW)
1415#error incompatible BSLS_REVIEW levels: \
1416..._LEVEL_REVIEW_SAFE and ..._LEVEL_REVIEW
1417#endif
1418
1419#if defined(BSLS_REVIEW_LEVEL_REVIEW_SAFE) && \
1420 defined(BSLS_REVIEW_LEVEL_REVIEW_OPT)
1421#error incompatible BSLS_REVIEW levels: \
1422..._LEVEL_REVIEW_SAFE and ..._LEVEL_REVIEW_OPT
1423#endif
1424
1425#if defined(BSLS_REVIEW_LEVEL_REVIEW_SAFE) && \
1426 defined(BSLS_REVIEW_LEVEL_NONE)
1427#error incompatible BSLS_REVIEW levels: \
1428..._LEVEL_REVIEW_SAFE and ..._LEVEL_NONE
1429#endif
1430
1431#if defined(BSLS_REVIEW_LEVEL_REVIEW) && \
1432 defined(BSLS_REVIEW_LEVEL_REVIEW_OPT)
1433#error incompatible BSLS_REVIEW levels: \
1434..._LEVEL_REVIEW and ..._LEVEL_REVIEW_OPT
1435#endif
1436
1437#if defined(BSLS_REVIEW_LEVEL_REVIEW) && \
1438 defined(BSLS_REVIEW_LEVEL_NONE)
1439#error incompatible BSLS_REVIEW levels: \
1440..._LEVEL_REVIEW and ..._LEVEL_NONE
1441#endif
1442
1443#if defined(BSLS_REVIEW_LEVEL_REVIEW_OPT) && \
1444 defined(BSLS_REVIEW_LEVEL_NONE)
1445#error incompatible BSLS_REVIEW levels: \
1446..._LEVEL_REVIEW_OPT and ..._LEVEL_NONE
1447#endif
1448
1449// At most one of the following assert levels may be set during the compilation
1450// of any component that includes 'bsls_review.h' (this is redundant with
1451// checks in 'bsls_assert.h', but we want to be sure these are checked even for
1452// users including only this header):
1453//..
1454// BSLS_ASSERT_LEVEL_ASSERT_SAFE
1455// BSLS_ASSERT_LEVEL_ASSERT
1456// BSLS_ASSERT_LEVEL_ASSERT_OPT
1457// BSLS_ASSERT_LEVEL_NONE
1458// BSLS_ASSERT_LEVEL_ASSUME_SAFE
1459// BSLS_ASSERT_LEVEL_ASSUME_ASSERT
1460// BSLS_ASSERT_LEVEL_ASSUME_OPT
1461//..
1462// ----------------------------------------------------------------------------
1463
1464#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
1465 defined(BSLS_ASSERT_LEVEL_ASSERT)
1466#error incompatible BSLS_ASSERT levels: \
1467..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSERT
1468#endif
1469
1470#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
1471 defined(BSLS_ASSERT_LEVEL_ASSERT_OPT)
1472#error incompatible BSLS_ASSERT levels: \
1473..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSERT_OPT
1474#endif
1475
1476#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
1477 defined(BSLS_ASSERT_LEVEL_NONE)
1478#error incompatible BSLS_ASSERT levels: \
1479..._LEVEL_ASSERT_SAFE and ..._LEVEL_NONE
1480#endif
1481
1482#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
1483 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
1484#error incompatible BSLS_ASSERT levels: \
1485..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSUME_OPT
1486#endif
1487
1488#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
1489 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
1490#error incompatible BSLS_ASSERT levels: \
1491..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSUME_ASSERT
1492#endif
1493
1494#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE) && \
1495 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
1496#error incompatible BSLS_ASSERT levels: \
1497..._LEVEL_ASSERT_SAFE and ..._LEVEL_ASSUME_SAFE
1498#endif
1499
1500#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
1501 defined(BSLS_ASSERT_LEVEL_ASSERT_OPT)
1502#error incompatible BSLS_ASSERT levels: \
1503..._LEVEL_ASSERT and ..._LEVEL_ASSERT_OPT
1504#endif
1505
1506#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
1507 defined(BSLS_ASSERT_LEVEL_NONE)
1508#error incompatible BSLS_ASSERT levels: \
1509..._LEVEL_ASSERT and ..._LEVEL_NONE
1510#endif
1511
1512#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
1513 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
1514#error incompatible BSLS_ASSERT levels: \
1515..._LEVEL_ASSERT and ..._LEVEL_ASSUME_OPT
1516#endif
1517
1518#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
1519 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
1520#error incompatible BSLS_ASSERT levels: \
1521..._LEVEL_ASSERT and ..._LEVEL_ASSUME_ASSERT
1522#endif
1523
1524#if defined(BSLS_ASSERT_LEVEL_ASSERT) && \
1525 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
1526#error incompatible BSLS_ASSERT levels: \
1527..._LEVEL_ASSERT and ..._LEVEL_ASSUME_SAFE
1528#endif
1529
1530#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
1531 defined(BSLS_ASSERT_LEVEL_NONE)
1532#error incompatible BSLS_ASSERT levels: \
1533..._LEVEL_ASSERT_OPT and ..._LEVEL_NONE
1534#endif
1535
1536#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
1537 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
1538#error incompatible BSLS_ASSERT levels: \
1539..._LEVEL_ASSERT_OPT and ..._LEVEL_ASSUME_OPT
1540#endif
1541
1542#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
1543 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
1544#error incompatible BSLS_ASSERT levels: \
1545..._LEVEL_ASSERT_OPT and ..._LEVEL_ASSUME_ASSERT
1546#endif
1547
1548#if defined(BSLS_ASSERT_LEVEL_ASSERT_OPT) && \
1549 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
1550#error incompatible BSLS_ASSERT levels: \
1551..._LEVEL_ASSERT_OPT and ..._LEVEL_ASSUME_SAFE
1552#endif
1553
1554#if defined(BSLS_ASSERT_LEVEL_NONE) && \
1555 defined(BSLS_ASSERT_LEVEL_ASSUME_OPT)
1556#error incompatible BSLS_ASSERT levels: \
1557..._LEVEL_NONE and ..._LEVEL_ASSUME_OPT
1558#endif
1559
1560#if defined(BSLS_ASSERT_LEVEL_NONE) && \
1561 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
1562#error incompatible BSLS_ASSERT levels: \
1563..._LEVEL_NONE and ..._LEVEL_ASSUME_ASSERT
1564#endif
1565
1566#if defined(BSLS_ASSERT_LEVEL_NONE) && \
1567 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
1568#error incompatible BSLS_ASSERT levels: \
1569..._LEVEL_NONE and ..._LEVEL_ASSUME_SAFE
1570#endif
1571
1572#if defined(BSLS_ASSERT_LEVEL_ASSUME_OPT) && \
1573 defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT)
1574#error incompatible BSLS_ASSERT levels: \
1575..._LEVEL_ASSUME_OPT and ..._LEVEL_ASSUME_ASSERT
1576#endif
1577
1578#if defined(BSLS_ASSERT_LEVEL_ASSUME_OPT) && \
1579 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
1580#error incompatible BSLS_ASSERT levels: \
1581..._LEVEL_ASSUME_OPT and ..._LEVEL_ASSUME_SAFE
1582#endif
1583
1584#if defined(BSLS_ASSERT_LEVEL_ASSUME_ASSERT) && \
1585 defined(BSLS_ASSERT_LEVEL_ASSUME_SAFE)
1586#error incompatible BSLS_ASSERT levels: \
1587..._LEVEL_ASSUME_ASSERT and ..._LEVEL_ASSUME_SAFE
1588#endif
1589
1590#endif
1591
1592// ----------------------------------------------------------------------------
1593// Copyright 2018 Bloomberg Finance L.P.
1594//
1595// Licensed under the Apache License, Version 2.0 (the "License");
1596// you may not use this file except in compliance with the License.
1597// You may obtain a copy of the License at
1598//
1599// http://www.apache.org/licenses/LICENSE-2.0
1600//
1601// Unless required by applicable law or agreed to in writing, software
1602// distributed under the License is distributed on an "AS IS" BASIS,
1603// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1604// See the License for the specific language governing permissions and
1605// limitations under the License.
1606// ----------------------------- END-OF-FILE ----------------------------------
1607
1608/** @} */
1609/** @} */
1610/** @} */
Definition bsls_review.h:1310
ReviewFailureHandlerGuard(Review::ViolationHandler temporary)
Definition bsls_review.h:1097
BSLS_KEYWORD_CONSTEXPR ReviewViolation(const char *comment, const char *fileName, int lineNumber, const char *reviewLevel, int count)
Definition bsls_review.h:1344
int lineNumber() const
Return the lineNumber attribute of this object.
Definition bsls_review.h:1377
int count() const
Return the count attribute of this object.
Definition bsls_review.h:1365
const char * reviewLevel() const
Return the reviewLevel attribute of this object.
Definition bsls_review.h:1383
const char * fileName() const
Return the fileName attribute of this object.
Definition bsls_review.h:1371
const char * comment() const
Return the comment attribute of this object.
Definition bsls_review.h:1359
Definition bsls_review.h:1179
static Review::ViolationHandler violationHandler()
static const char k_LEVEL_REVIEW[]
Definition bsls_review.h:1216
static void setViolationHandler(Review::ViolationHandler function)
static BSLS_ANNOTATION_NORETURN void failByThrow(const ReviewViolation &violation)
static int updateCount(Count *count)
static const char k_LEVEL_OPT[]
Definition bsls_review.h:1215
bsls::AtomicOperations::AtomicTypes::Int Count
Definition bsls_review.h:1188
static void failByLog(const ReviewViolation &violation)
static const char k_LEVEL_SAFE[]
Definition bsls_review.h:1214
static void invokeHandler(const ReviewViolation &violation)
void(* ViolationHandler)(const ReviewViolation &)
Definition bsls_review.h:1196
static BSLS_ANNOTATION_NORETURN void failByAbort(const ReviewViolation &violation)
static void lockReviewAdministration()
static const char k_LEVEL_INVOKE[]
Definition bsls_review.h:1217
static BSLS_ANNOTATION_NORETURN void failBySleep(const ReviewViolation &violation)
#define BSLS_ANNOTATION_NORETURN
Definition bsls_annotation.h:378
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
Definition bdlt_iso8601util.h:707