29/// * <a href="#bsls_exceptionutil-example-1-using-ref-bsls_exceptionutil-to-implement-vector"> Example 1: Using @ref bsls_exceptionutil to Implement vector </a>
30/// * <a href="#bsls_exceptionutil-example-2-using-ref-bsls_exceptionutil-to-throw-and-catch-exceptions"> Example 2: Using @ref bsls_exceptionutil to Throw and Catch Exceptions </a>
31///
32/// # Purpose {#bsls_exceptionutil-purpose}
33/// Provide simplified exception constructs for non-exception builds.
34///
35/// # Classes {#bsls_exceptionutil-classes}
36///
37///
38/// # Macros {#bsls_exceptionutil-macros}
39///
40/// - BSLS_TRY: begin a `try`-block
41/// - BSLS_CATCH(X): begin a `catch`-block for exception `X`
42/// - BSLS_THROW(X): `throw` exception `X`
43/// - BSLS_RETHROW: re-`throw` the current exception
44/// - BSLS_EXCEPTION_SPEC(SPEC): add `SPEC` to function exception specification
45/// - BSLS_NOTHROW_SPEC: declare that a function throws no exceptions
52/// Code that uses `try`, `throw` and `catch` constructs will
53/// often fail to compile when exceptions are disabled using a compiler switch,
54/// even if the `throw` statement is unlikely to be executed at run-time or if
55/// the `catch` clause can safely ignore an exception that will never occur.
56/// This component provides macros to replace `try`, `throw` and `catch`.
57/// These macros expand to normal exception constructs when exceptions are
58/// enabled and reasonable alternatives (usually no-ops) when exceptions are
59/// disabled.
60///
61/// ## Usage {#bsls_exceptionutil-usage}
62///
63///
64/// This section illustrates intended use of this component.
65///
66/// ### Example 1: Using @ref bsls_exceptionutil to Implement vector {#bsls_exceptionutil-example-1-using-ref-bsls_exceptionutil-to-implement-vector}
67///
68///
69/// Suppose we wanted to define an implementation of a standard-defined `vector`
70/// template. Unfortunately, the C++ standard requires that `vector` provide an
71/// `at` method that throws an `out_of_range` exception if the supplied index is
72/// not in the valid range of elements in the vector. In this example we show
73/// using `BSLS_THROW` so that such an implementation will compile in both
74/// exception enabled and non-exception enabled builds. Note that apart from
75/// memory allocation, and where required by the C++ standard, types defined in
76/// the BDE libraries do not throw exceptions, and are typically
77/// "exception-neutral" (see @ref bsldoc_glossary ), meaning they behave
78/// reasonably in the presence of injected exceptions, but do not themselves
79/// throw any exceptions.
80///
81/// First we open a namespace `myStd` and define an `out_of_range` exception
82/// that the `at` method will throw (note that in practice, `out_of_range` would
83/// inherit from @ref logic_error )':
84/// @code
85/// namespace myStd {
86///
87/// class out_of_range // ...
88/// {
89/// // ...
90/// };
91/// @endcode
92/// Next, we declare the `vector` template and its template parameters (note
93/// that the majority of the implementation is elided, for clarity):
94/// @code
95/// template <class VALUE, class ALLOCATOR /* ... */>
108/// Then, we define the `at` method, which is required to throw an
109/// `out_of_range` exception.
110/// @code
111/// const VALUE& at(size_type index) const
112/// {
113/// if (d_begin_p + index < d_end_p) {
114/// return d_begin_p[index]; // RETURN
115/// }
116/// @endcode
117/// Now, we use `BSLS_THROW` to throw an `out_of_range` exception:
118/// @code
119/// BSLS_THROW(out_of_range(/* ... */));
120/// }
121/// @endcode
122/// Finally, we complete the (mostly elided) `vector` implementation:
123/// @code
124/// // ...
125///
126/// };
127///
128/// } // close namespace myStd
129///
130/// struct DummyAllocator {
131/// typedef int size_type;
132/// };
133/// @endcode
134///
135/// ### Example 2: Using @ref bsls_exceptionutil to Throw and Catch Exceptions {#bsls_exceptionutil-example-2-using-ref-bsls_exceptionutil-to-throw-and-catch-exceptions}
136///
137///
138/// The following example demonstrates the macros defined in the
139/// @ref bsls_exceptionutil component to both throw and catch exceptions in a way
140/// that will allow the code to compile in non-exception enabled builds.
141///
142/// First, we define a couple of example exception classes (note that we cannot
143/// use `bsl::exception` in this example, as this component is defined below
144///`bsl_exception.h`):
145/// @code
146/// class my_ExClass1
147/// {
148/// };
149///
150/// class my_ExClass2
151/// {
152/// };
153/// @endcode
154/// Then, we define a function that never throws an exception, and use the
155/// `BSLS_NOTHROW_SPEC` to ensure the no-throw exception specification will be
156/// present in exception enabled builds, and elided in non-exception enabled
157/// builds:
158/// @code
159/// int noThrowFunc() BSLS_NOTHROW_SPEC
160/// {
161/// return -1;
162/// }
163/// @endcode
164/// Next, we define a function that might throw `my_ExClass1` or `my_ExClass2`,
165/// and docuemnt which exception types might be thrown. Note that dynamic
166/// exception specifications are deprecated in C++11 and removed from the
167/// language in C++17, so should not be used as a substitute for documentation
168/// in earlier language dialects:
169/// @code
170/// int mightThrowFunc(int i)
171/// // Return the specified integer 'i', unless '1 == 1' or '2 == i'. If
172/// // '1 == i' throw an exception of type 'my_ExcClass1'. If '2 == i'
173/// // throw an exception of type 'my_ExcClass2'. Note that if exceptions
174/// // are not enabled in the current build mode, then the program will
175/// // 'abort' rather than throw.
176/// {
177/// switch (i) {
178/// case 0: break;
179/// case 1: BSLS_THROW(my_ExClass1());
180/// case 2: BSLS_THROW(my_ExClass2());
181/// }
182/// return i;
183/// }
184/// @endcode
185/// Then, we start the definition of a `testMain` function:
186/// @code
187/// int testMain()
188/// {
189/// @endcode
190/// Next, we use the `BDE_BUILD_TARGET_EXC` exception build flag to determine,
191/// at compile time, whether to initialize `ITERATIONS` to 3 (for exception
192/// enabled builds) or 1 (for non-exception enabled builds). The different
193/// values of the `ITERATOR` ensure the subsequent for-loop calls
194/// `mightThrowFunc` in a way that generates exceptions for only exception
195/// enabled builds:
196/// @code
197/// #ifdef BDE_BUILD_TARGET_EXC
198/// const int ITERATIONS = 3;
199/// #else
200/// const int ITERATIONS = 1;
201/// #endif
202///
203/// for (int i = 0; i < ITERATIONS; ++i) {
204/// @endcode
205/// Then, we use a pair of nested `try` blocks constructed using
206/// `BSLS_TRY`, so that the code will compile whether or not exceptions are
207/// enabled (note that the curly brace placement is identical to normal
208/// `try` and `catch` constructs):
209/// @code
210/// int caught = -1;
211/// BSLS_TRY {
212///
213/// BSLS_TRY {
214/// noThrowFunc();
215/// mightThrowFunc(i);
216/// @endcode
217/// Notice that this example is careful to call `mightThrowFunc` in such a way
218/// that it will not throw in non-exception builds. Although the use of
219/// `BSLS_TRY`, `BSLS_THROW`, and `BSLS_CATCH` ensures the code *compiles* in
220/// both exception, and non-exception enabled builds, attempting to `BSLS_THROW`
221/// an exception in a non-exception enabled build will invoke the assert handler
222/// and will typically abort the task.
223/// @code
224/// caught = 0; // Got here if no throw
225/// }
226/// @endcode
227/// Next, we use `BSLS_CATCH` to define blocks for handling exceptions that may
228/// have been thrown from the preceding `BSLS_TRY`:
229/// @code
230/// BSLS_CATCH(my_ExClass1) {
231/// caught = 1;
232/// }
233/// BSLS_CATCH(...) {
234/// @endcode
235/// Here, within the catch-all handler, we use the `BSLS_RETHROW` macro to
236/// re-throw the exception to the outer `try` block: