BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_rawdeleterguard.h
Go to the documentation of this file.
1/// @file bslma_rawdeleterguard.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_rawdeleterguard.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_RAWDELETERGUARD
9#define INCLUDED_BSLMA_RAWDELETERGUARD
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_rawdeleterguard bslma_rawdeleterguard
15/// @brief Provide a guard to unconditionally manage an object.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_rawdeleterguard
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_rawdeleterguard-purpose"> Purpose</a>
25/// * <a href="#bslma_rawdeleterguard-classes"> Classes </a>
26/// * <a href="#bslma_rawdeleterguard-description"> Description </a>
27/// * <a href="#bslma_rawdeleterguard-raw-warning"> "Raw" Warning </a>
28/// * <a href="#bslma_rawdeleterguard-requirement"> Requirement </a>
29/// * <a href="#bslma_rawdeleterguard-usage"> Usage </a>
30///
31/// # Purpose {#bslma_rawdeleterguard-purpose}
32/// Provide a guard to unconditionally manage an object.
33///
34/// # Classes {#bslma_rawdeleterguard-classes}
35///
36/// - bslma::RawDeleterGuard: guard to unconditionally manage an object
37///
38/// @see bslma_rawdeleterproctor, bslma_autorawdeleter
39///
40/// # Description {#bslma_rawdeleterguard-description}
41/// This component provides a guard class template,
42/// `bslma::RawDeleterGuard`, to unconditionally manage an (otherwise-unmanaged)
43/// object of parameterized `TYPE` supplied at construction. The managed object
44/// is deleted automatically when the guard object goes out of scope by first
45/// calling the (managed) object's destructor, and then freeing the memory using
46/// the parameterized `ALLOCATOR` (allocator or pool) also supplied at
47/// construction.
48///
49/// ## "Raw" Warning {#bslma_rawdeleterguard-raw-warning}
50///
51///
52/// Note that this component should be used only if we are sure that the
53/// supplied pointer is **not** of a type that is a secondary base class -- i.e.,
54/// the (managed) object's address is (numerically) the same as when it was
55/// originally dispensed by `ALLOCATOR`.
56///
57/// ## Requirement {#bslma_rawdeleterguard-requirement}
58///
59///
60/// The parameterized `ALLOCATOR` type of the `bslma::RawDeleterGuard` class
61/// template must provide a (possibly `virtual`) method:
62/// @code
63/// void deallocate(void *address);
64/// @endcode
65/// to deallocate memory at the specified `address` (originally supplied by the
66/// `ALLOCATOR` object).
67///
68/// ## Usage {#bslma_rawdeleterguard-usage}
69///
70///
71/// This example shows how one might use a `bslma::RawDeleterGuard` to guard a
72/// dynamically-allocated object, deleting that object automatically when the
73/// guard goes out of scope.
74///
75/// Suppose we have a simple queue class that stores object values using an
76/// "out-of-place" representation (i.e., an array of dynamically-allocated
77/// object pointers):
78/// @code
79/// // my_queue.h
80/// // ...
81///
82/// template <class TYPE>
83/// class my_Queue {
84/// // This class is a container that uses an "out-of-place"
85/// // representation to manage objects of parameterized 'TYPE'. Note
86/// // that this class is implemented with the native version of 'deque',
87/// // instead of the version provided in 'bslstl_Deque'. This is so that
88/// // a circular dependency in the physical hierarchy will not be created.
89///
90/// // DATA
91/// std::deque<TYPE *> d_objects; // objects stored in the queue
92/// bslma::Allocator *d_allocator_p; // allocator (held, not owned)
93///
94/// public:
95/// // CREATORS
96/// my_Queue(bslma::Allocator *basicAllocator = 0);
97/// // Create a 'my_Queue' object. Optionally specify a
98/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
99/// // 0, the currently installed default allocator is used.
100///
101/// // ...
102///
103/// ~my_Queue();
104/// // Destroy this 'my_Queue' object and all elements currently
105/// // stored.
106///
107/// // MANIPULATORS
108///
109/// // ...
110///
111/// void pushBack(const TYPE& object);
112/// // Push the value of the specified 'object' of parameterized 'TYPE'
113/// // onto the back of this queue.
114///
115/// TYPE popFront();
116/// // Remove and return (by value) the object of parameterized 'TYPE'
117/// // that is currently at the front of this queue.
118///
119/// // ...
120/// };
121/// @endcode
122/// Note that the `popFront` method returns an object by value because (1) there
123/// may be no reasonable default object to pass in, (2) there may be no
124/// reasonable copy-assignment semantics, or (3) it is simply more syntactically
125/// convenient (e.g., if, say, the queued objects are themselves pointers):
126/// @code
127/// // CREATORS
128/// template <class TYPE>
129/// inline
130/// my_Queue<TYPE>::my_Queue(bslma::Allocator *basicAllocator)
131/// : d_objects(basicAllocator)
132/// , d_allocator_p(bslma::Default::allocator(basicAllocator))
133/// {
134/// }
135///
136/// template <class TYPE>
137/// my_Queue<TYPE>::~my_Queue()
138/// {
139/// for (int i = 0; i < d_objects.size(); ++i) {
140/// d_allocator_p->deleteObjectRaw(d_objects[i]);
141/// }
142/// }
143/// @endcode
144/// Note that the `pushBack` method should be implemented with a constructor
145/// proxy that determines whether `TYPE` takes an allocator at construction (see
146/// @ref bslalg_constructorproxy ). However, for the purpose of this example, the
147/// implementation is simplified by assuming `TYPE` takes an allocator.
148/// @code
149/// // MANIPULATORS
150/// template <class TYPE>
151/// inline
152/// void my_Queue<TYPE>::pushBack(const TYPE& object)
153/// {
154/// TYPE *tmp = (TYPE *)new(*d_allocator_p) TYPE(object);
155/// d_objects.push_back(tmp);
156/// }
157///
158/// template <class TYPE>
159/// inline
160/// TYPE my_Queue<TYPE>::popFront()
161/// {
162/// TYPE *tmp = d_objects.front();
163/// d_objects.pop_front();
164///
165/// //***********************************************************
166/// //* Note the use of the raw deleter guard on 'tmp' (below). *
167/// //***********************************************************
168///
169/// bslma::RawDeleterGuard<TYPE, bslma::Allocator>
170/// guard(tmp, d_allocator_p);
171///
172/// return *tmp;
173/// }
174/// @endcode
175/// The `pushBack` method defined above stores a copy of the provided object.
176/// The `popFront` method returns the leading object by value, and the
177/// `bslma::RawDeleterGuard` is used to automatically delete the copy the queue
178/// manages when the guard goes out of scope (i.e., when the function returns).
179/// @}
180/** @} */
181/** @} */
182
183/** @addtogroup bsl
184 * @{
185 */
186/** @addtogroup bslma
187 * @{
188 */
189/** @addtogroup bslma_rawdeleterguard
190 * @{
191 */
192
193#include <bslscm_version.h>
194
195#include <bslma_deleterhelper.h>
196
197#include <bsls_assert.h>
198
199
200
201namespace bslma {
202
203 // =====================
204 // class RawDeleterGuard
205 // =====================
206
207/// This class implements a guard that unconditionally deletes a managed
208/// object upon destruction by first invoking the object's destructor, and
209/// then invoking the `deallocate` method of an allocator (or pool) of
210/// parameterized `ALLOCATOR` type supplied to it at construction. The
211/// managed object of parameterized `TYPE` must have been created using
212/// memory provided by this allocator (or pool), which must remain valid
213/// throughout the lifetime of the guard object.
214///
215/// See @ref bslma_rawdeleterguard
216template <class TYPE, class ALLOCATOR>
218
219 // DATA
220 TYPE *d_object_p; // managed object
221 ALLOCATOR *d_allocator_p; // allocator or pool (held, not owned)
222
223 // NOT IMPLEMENTED
225 RawDeleterGuard& operator=(const RawDeleterGuard&);
226
227 public:
228 // CREATORS
229
230 /// Create a raw deleter guard that unconditionally manages the
231 /// specified `object`, and that uses the specified `allocator` to
232 /// delete `object` upon the destruction of this guard. The behavior is
233 /// undefined unless `object` and `allocator` are non-zero, and
234 /// `allocator` supplied the memory for `object`. Note that `allocator`
235 /// must remain valid throughout the lifetime of this guard.
236 RawDeleterGuard(TYPE *object, ALLOCATOR *allocator);
237
238 /// Destroy this raw deleter guard and delete the object it manages by
239 /// first invoking the destructor of the (managed) object, and then
240 /// invoking the `deallocate` method of the allocator (or pool) that was
241 /// supplied with the object at construction.
243};
244
245// ============================================================================
246// INLINE DEFINITIONS
247// ============================================================================
248
249 // ---------------------
250 // class RawDeleterGuard
251 // ---------------------
252
253// CREATORS
254template <class TYPE, class ALLOCATOR>
255inline
257RawDeleterGuard(TYPE *object, ALLOCATOR *allocator)
258: d_object_p(object)
259, d_allocator_p(allocator)
260{
261 BSLS_ASSERT_SAFE(object);
262 BSLS_ASSERT_SAFE(allocator);
263}
264
265template <class TYPE, class ALLOCATOR>
266inline
268{
269 BSLS_ASSERT_SAFE(d_object_p);
270 BSLS_ASSERT_SAFE(d_allocator_p);
271
272 DeleterHelper::deleteObjectRaw(d_object_p, d_allocator_p);
273}
274
275} // close package namespace
276
277#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
278// ============================================================================
279// BACKWARD COMPATIBILITY
280// ============================================================================
281
282#ifdef bslma_RawDeleterGuard
283#undef bslma_RawDeleterGuard
284#endif
285/// This alias is defined for backward compatibility.
286#define bslma_RawDeleterGuard bslma::RawDeleterGuard
287#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
288
289
290
291#endif
292
293// ----------------------------------------------------------------------------
294// Copyright 2013 Bloomberg Finance L.P.
295//
296// Licensed under the Apache License, Version 2.0 (the "License");
297// you may not use this file except in compliance with the License.
298// You may obtain a copy of the License at
299//
300// http://www.apache.org/licenses/LICENSE-2.0
301//
302// Unless required by applicable law or agreed to in writing, software
303// distributed under the License is distributed on an "AS IS" BASIS,
304// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
305// See the License for the specific language governing permissions and
306// limitations under the License.
307// ----------------------------- END-OF-FILE ----------------------------------
308
309/** @} */
310/** @} */
311/** @} */
Definition bslma_rawdeleterguard.h:217
~RawDeleterGuard()
Definition bslma_rawdeleterguard.h:267
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balxml_encoderoptions.h:68
static void deleteObjectRaw(const TYPE *object, ALLOCATOR *allocator)
Definition bslma_deleterhelper.h:217