BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_deallocatorguard.h
Go to the documentation of this file.
1/// @file bslma_deallocatorguard.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_deallocatorguard.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_DEALLOCATORGUARD
9#define INCLUDED_BSLMA_DEALLOCATORGUARD
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_deallocatorguard bslma_deallocatorguard
15/// @brief Provide a guard to unconditionally manage a block of memory.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_deallocatorguard
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_deallocatorguard-purpose"> Purpose</a>
25/// * <a href="#bslma_deallocatorguard-classes"> Classes </a>
26/// * <a href="#bslma_deallocatorguard-description"> Description </a>
27/// * <a href="#bslma_deallocatorguard-requirement"> Requirement </a>
28/// * <a href="#bslma_deallocatorguard-usage"> Usage </a>
29///
30/// # Purpose {#bslma_deallocatorguard-purpose}
31/// Provide a guard to unconditionally manage a block of memory.
32///
33/// # Classes {#bslma_deallocatorguard-classes}
34///
35/// - bslma::DeallocatorGuard: guard to unconditionally manage a block of memory
36///
37/// @see bslma_deallocatorproctor, bslma_autodeallocator
38///
39/// # Description {#bslma_deallocatorguard-description}
40/// This component provides a guard class template,
41/// `bslma::DeallocatorGuard`, to unconditionally manage a block of
42/// (otherwise-unmanaged) memory. The managed memory is deallocated
43/// automatically when the guard object goes out of scope using the `deallocate`
44/// method of the parameterized `ALLOCATOR` (allocator or pool) supplied at
45/// construction.
46///
47/// ## Requirement {#bslma_deallocatorguard-requirement}
48///
49///
50/// The parameterized `ALLOCATOR` type of the `bslma::DeallocatorGuard` class
51/// template must provide a (possibly `virtual`) method:
52/// @code
53/// void deallocate(void *address);
54/// @endcode
55/// to deallocate memory at the specified `address` (originally supplied by the
56/// `ALLOCATOR` object).
57///
58/// ## Usage {#bslma_deallocatorguard-usage}
59///
60///
61/// A `bslma::DeallocatorGuard` can be used to ensure that a dynamically
62/// allocated raw memory resource is safely deallocated in the presence of
63/// multiple return statements or exceptions in an exception-neutral way (i.e.,
64/// without the need for `try`/`catch` blocks). In this simple example,
65/// consider the function `evaluatePassword` which attempts to determine how
66/// secure a given password might be:
67/// @code
68/// /// Evaluate the strength of the specified `password`, using the
69/// /// specified `allocator` to supply memory for evaluation. Return a
70/// /// real value in the range `[ 0.0 .. 1.0 ]` where 0.0 indicates the
71/// /// weakest password, and 1.0 the strongest.
72/// double evaluatePassword(const char *password, bslma::Allocator *allocator);
73/// @endcode
74/// This function will be implemented in terms of three *exception* *neutral*
75/// subroutines, each of which operates on a writable copy of the
76/// null-terminated password, (perturbing its contents slightly) and requiring
77/// unbounded amounts of scratch memory (to be allocated and deallocated from a
78/// supplied allocator):
79/// @code
80/// int subroutine1(char *inOut, bslma::Allocator *allocator);
81/// int subroutine2(char *inOut, bslma::Allocator *allocator);
82/// int subroutine3(char *inOut, bslma::Allocator *allocator);
83/// @endcode
84/// A final subroutine is then used to determine and return the score:
85/// @code
86/// double finalSubroutine(const char *result);
87/// @endcode
88/// The top-level routine is implemented as follows:
89/// @code
90/// double evaluatePassword(const char *password, bslma::Allocator *allocator)
91/// {
92///
93/// // Set up local writable copy of password in buffer.
94///
95/// size_t size = strlen(password) + 1;
96/// char *buffer = (char *)allocator->allocate(size);
97/// memcpy(buffer, password, size);
98///
99/// //**************************************************************
100/// //* Note the use of the deallocator guard on 'buffer' (below). *
101/// //**************************************************************
102///
103/// bslma::DeallocatorGuard<bslma::Allocator> guard(buffer, allocator);
104///
105/// // Process and evaluate the supplied password.
106///
107/// if (0 != subroutine1(buffer, allocator)) {
108/// return 0.0; // RETURN
109/// }
110/// if (0 != subroutine2(buffer, allocator)) {
111/// return 0.2; // RETURN
112/// }
113/// if (0 != subroutine3(buffer, allocator)) {
114/// return 0.4; // RETURN
115/// }
116///
117/// return finalSubroutine(buffer);
118///
119/// } // note that 'buffer' is deallocated at end of block regardless
120/// @endcode
121/// Notice that if any of the initial (numbered) subroutines returns a non-zero
122/// status value, the top-level `evaluatePassword` routine returns immediately
123/// with a predetermined score. Moreover, each of these routines may encounter
124/// a @ref bad_alloc exception should the supplied allocator fail to return the
125/// requested memory. Even if all of these subroutines evaluates successfully,
126/// the score calculated using `finalEval` is returned directly by
127/// `evaluatePassword`, yet we still need to deallocate `buffer`. By guarding
128/// buffer with a `bslma::DeallocatorGuard` as shown above, all of these issues
129/// are fully addressed, and the top-level routine is also *exception* *neutral*
130/// as desired.
131/// @}
132/** @} */
133/** @} */
134
135/** @addtogroup bsl
136 * @{
137 */
138/** @addtogroup bslma
139 * @{
140 */
141/** @addtogroup bslma_deallocatorguard
142 * @{
143 */
144
145#include <bslscm_version.h>
146
147#include <bsls_assert.h>
148
149
150
151namespace bslma {
152
153 // ======================
154 // class DeallocatorGuard
155 // ======================
156
157/// This class implements a guard that unconditionally deallocates a block
158/// of managed memory upon destruction by invoking the `deallocate` method
159/// of an allocator (or pool) of parameterized `ALLOCATOR` type supplied to
160/// it at construction. The managed memory must have been supplied by the
161/// allocator (or pool), which must remain valid throughout the lifetime of
162/// the guard object.
163///
164/// See @ref bslma_deallocatorguard
165template <class ALLOCATOR>
167
168 // DATA
169 void *d_memory_p; // address of managed memory
170 ALLOCATOR *d_allocator_p; // allocator or pool (held, not owned)
171
172 // NOT IMPLEMENTED
174 DeallocatorGuard& operator=(const DeallocatorGuard&);
175
176 public:
177 // CREATORS
178
179 /// Create a deallocator guard that unconditionally manages the
180 /// specified `memory` block, and that uses the specified `allocator` to
181 /// deallocate `memory` upon destruction of this guard. The behavior is
182 /// undefined unless `memory` and `allocator` are non-zero, and
183 /// `allocator` supplied `memory`. Note that `allocator` must remain
184 /// valid throughout the lifetime of this guard.
185 DeallocatorGuard(void *memory, ALLOCATOR *allocator);
186
187 /// Destroy this deallocator guard and deallocate the block of memory it
188 /// manages by invoking the `deallocate` method of the allocator (or
189 /// pool) that was supplied with the address of the (managed) memory at
190 /// construction.
192};
193
194// ============================================================================
195// INLINE DEFINITIONS
196// ============================================================================
197
198 // ----------------------
199 // class DeallocatorGuard
200 // ----------------------
201
202// CREATORS
203template <class ALLOCATOR>
204inline
206 ALLOCATOR *allocator)
207: d_memory_p(memory)
208, d_allocator_p(allocator)
209{
210 BSLS_ASSERT_SAFE(memory);
211 BSLS_ASSERT_SAFE(allocator);
212}
213
214template <class ALLOCATOR>
215inline
217{
218 BSLS_ASSERT_SAFE(d_memory_p);
219 BSLS_ASSERT_SAFE(d_allocator_p);
220
221 d_allocator_p->deallocate(d_memory_p);
222}
223
224} // close package namespace
225
226#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
227// ============================================================================
228// BACKWARD COMPATIBILITY
229// ============================================================================
230
231#ifdef bslma_DeallocatorGuard
232#undef bslma_DeallocatorGuard
233#endif
234/// This alias is defined for backward compatibility.
235#define bslma_DeallocatorGuard bslma::DeallocatorGuard
236#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
237
238
239
240#endif
241
242// ----------------------------------------------------------------------------
243// Copyright 2013 Bloomberg Finance L.P.
244//
245// Licensed under the Apache License, Version 2.0 (the "License");
246// you may not use this file except in compliance with the License.
247// You may obtain a copy of the License at
248//
249// http://www.apache.org/licenses/LICENSE-2.0
250//
251// Unless required by applicable law or agreed to in writing, software
252// distributed under the License is distributed on an "AS IS" BASIS,
253// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
254// See the License for the specific language governing permissions and
255// limitations under the License.
256// ----------------------------- END-OF-FILE ----------------------------------
257
258/** @} */
259/** @} */
260/** @} */
Definition bslma_deallocatorguard.h:166
~DeallocatorGuard()
Definition bslma_deallocatorguard.h:216
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balxml_encoderoptions.h:68