BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_destructorproctor.h
Go to the documentation of this file.
1/// @file bslma_destructorproctor.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_destructorproctor.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_DESTRUCTORPROCTOR
9#define INCLUDED_BSLMA_DESTRUCTORPROCTOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_destructorproctor bslma_destructorproctor
15/// @brief Provide a proctor to conditionally manage an object.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_destructorproctor
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_destructorproctor-purpose"> Purpose</a>
25/// * <a href="#bslma_destructorproctor-classes"> Classes </a>
26/// * <a href="#bslma_destructorproctor-description"> Description </a>
27/// * <a href="#bslma_destructorproctor-usage"> Usage </a>
28///
29/// # Purpose {#bslma_destructorproctor-purpose}
30/// Provide a proctor to conditionally manage an object.
31///
32/// # Classes {#bslma_destructorproctor-classes}
33///
34/// - bslma::DestructorProctor: proctor to conditionally manage an object
35///
36/// @see bslma_destructorguard, bslma_autodestructor
37///
38/// # Description {#bslma_destructorproctor-description}
39/// This component provides a proctor class template,
40/// `bslma::DestructorProctor`, to conditionally manage an (otherwise-unmanaged)
41/// object of parameterized `TYPE` supplied at construction. If not explicitly
42/// released, the managed object is destroyed automatically when the proctor
43/// object goes out of scope by calling the object's destructor. Note that
44/// after a proctor object releases its managed object, the same proctor can be
45/// reused to conditionally manage another object by invoking the `reset`
46/// method.
47///
48/// ## Usage {#bslma_destructorproctor-usage}
49///
50///
51/// The `bslma::DestructorProctor` is normally used to manage objects that are
52/// constructed sequentially in a block of memory provided. This is often the
53/// case when memory management and primitive helpers are implemented in
54/// different components. An example would be the construction of a pair object
55/// within another container with the help of a scalar primitive helper (see
56/// @ref bslma_constructionutil ). After the first object is constructed in the
57/// provided memory, it should be protected in case the constructor of the
58/// second object throws. The following example illustrates a typical use of
59/// the `bslma::DestructorProctor`.
60///
61/// First, suppose we have a pair class similar to `std::pair`:
62/// @code
63/// // MyPair.h
64/// // ...
65///
66/// /// This class provides a pair container to pair two different objects,
67/// /// one of parameterized `TYPE1`, and the other of parameterized
68/// /// `TYPE2`.
69/// template <class TYPE1, class TYPE2>
70/// class MyPair {
71///
72/// public:
73/// // PUBLIC TYPES
74/// typedef TYPE1 firstType;
75/// typedef TYPE2 secondType;
76///
77/// // PUBLIC DATA
78/// TYPE1 first; // first object
79/// TYPE2 second; // second object
80///
81/// // Declare trait `my_PairTrait`.
82/// // ...
83///
84/// public:
85/// // CREATORS
86/// // ...
87///
88/// /// Create a `MyPair` object that holds a copy of the specified
89/// /// `iFirst` and `iSecond`. Optionally specify `basicAllocator` to
90/// /// supply memory. If `basicAllocator` is zero, the global default
91/// /// allocator will be used to supply memory.
92/// MyPair(const TYPE1& iFirst,
93/// const TYPE2& iSecond,
94/// bslma::Allocator *basic_Allocator = 0)
95/// : first(iFirst)
96/// , second(iSecond)
97/// , d_allocator_p(bslma::Default::allocator(basic_Allocator))
98/// {
99/// }
100///
101/// // ...
102///
103/// };
104/// @endcode
105/// Note that parts of the implementation, including the `my_PairTrait`
106/// declaration, are elided. The `my_PairTrait` will be used by the primitive
107/// helper to customize implementations for objects that are pairs.
108///
109/// We now implement the primitive helper:
110/// @code
111/// // MyPrimitives.h
112/// // ...
113///
114/// /// This `struct` provides a namespace for primitive functions used to
115/// /// construct, destroy, insert, append and remove objects.
116/// struct MyPrimitives {
117///
118/// private:
119/// // PRIVATE TYPES
120/// enum { PAIR_TRAIT = 1, NIL_TRAIT = 0 };
121///
122/// public:
123/// // CLASS METHODS
124///
125/// /// Copy construct the specified `original` into the specified
126/// /// `address` using the specified `basicAllocator` (if the
127/// /// copy constructor of `TYPE` takes an allocator).
128/// template <class TYPE>
129/// static void copyConstruct(TYPE *address,
130/// const TYPE& original,
131/// bslma::Allocator *basicAllocator);
132///
133/// /// Copy construct the specified `original` into the specified
134/// /// `address` using the specified `basicAllocator` (if the
135/// /// copy constructor of `TYPE` takes an allocator). Note that
136/// /// the last parameter is used only for overload resolution.
137/// template <class TYPE>
138/// static void copyConstruct(TYPE *address,
139/// const TYPE& original,
140/// bslma::Allocator *basicAllocator,
141/// bsl::integral_constant<bool, PAIR_TRAIT> *);
142///
143/// /// Copy construct the specified `original` into the specified
144/// /// `address` using the specified `basicAllocator` (if the
145/// /// copy constructor of `TYPE` takes an allocator). Note that
146/// /// the last parameter is used only for overload resolution.
147/// template <class TYPE>
148/// static void copyConstruct(TYPE *address,
149/// const TYPE& original,
150/// bslma::Allocator *basicAllocator,
151/// bsl::integral_constant<bool, NIL_TRAIT> *);
152/// };
153///
154/// template <class TYPE>
155/// inline
156/// void MyPrimitives::copyConstruct(TYPE *address,
157/// const TYPE& original,
158/// bslma::Allocator *basicAllocator)
159/// {
160/// copyConstruct(address,
161/// original,
162/// basicAllocator,
163/// (typename my_HasPairTrait<TYPE>::type *)0);
164/// }
165/// @endcode
166/// The implementation of `copyConstruct` constructs the pair object in two
167/// steps because of the use of allocators. We cannot simply pass the allocator
168/// to the copy constructor of the pair object (since `std::pair` does not take
169/// an allocator). Therefore, we copy construct `first` and `second` directly
170/// in the pair object.
171/// @code
172/// template <class TYPE>
173/// inline
174/// void MyPrimitives::copyConstruct(TYPE *address,
175/// const TYPE& original,
176/// bslma::Allocator *basicAllocator,
177/// bsl::integral_constant<int, PAIR_TRAIT> *)
178/// {
179/// copyConstruct(&address->first, original.first, basicAllocator);
180///
181/// //**************************************************
182/// // Note the use of the destructor proctor (below). *
183/// //**************************************************
184///
185/// bslma::DestructorProctor<typename TYPE::firstType> proctor(
186/// &address->first);
187///
188/// copyConstruct(&address->second, original.second, basicAllocator);
189///
190/// //********************************************************
191/// // Note that the destructor proctor is released (below). *
192/// //********************************************************
193///
194/// proctor.release();
195/// }
196///
197/// template <class TYPE>
198/// inline
199/// void MyPrimitives::copyConstruct(TYPE *address,
200/// const TYPE& original,
201/// bslma::Allocator *basicAllocator,
202/// bsl::integral_constant<int, NIL_TRAIT> *)
203/// {
204/// new(address)TYPE(original, basicAllocator);
205/// }
206/// @endcode
207/// Note that the implementation of `my_HasPairTrait` is not shown. It is used
208/// to detect whether `TYPE` has `my_PairTrait` or not (see @ref bslalg_typetraits ,
209/// @ref bslalg_typetraitpair ).
210///
211/// In the above implementation, if the copy construction of the second object
212/// in the pair throws, all memory (and any other resources) acquired as a
213/// result of copying the (not-yet-managed) object would be leaked. Using the
214/// `bslma::DestructorProctor` prevents the leaks by invoking the destructor of
215/// the proctored object automatically should the proctor go out of scope before
216/// the `release` method of the proctor is called (such as when the function
217/// exits prematurely due to an exception).
218///
219/// Note that the `copyConstruct` method assumes the copy constructor of
220/// `TYPE::firstType` and `TYPE::secondType` takes an allocator as a second
221/// argument. In production code, a constructor proxy that checks the traits of
222/// `TYPE::firstType` and `TYPE::secondType` (to determine whether they uses
223/// `bslma::Allocator`) should be used (see @ref bslalg_constructorproxy ).
224/// @}
225/** @} */
226/** @} */
227
228/** @addtogroup bsl
229 * @{
230 */
231/** @addtogroup bslma
232 * @{
233 */
234/** @addtogroup bslma_destructorproctor
235 * @{
236 */
237
238#include <bslscm_version.h>
239
241
242#include <bsls_assert.h>
243#include <bsls_performancehint.h>
244
245
246
247namespace bslma {
248
249 // =======================
250 // class DestructorProctor
251 // =======================
252
253/// This class implements a proctor that, unless its `release` method has
254/// previously been invoked, automatically destroys a managed object upon
255/// destruction by invoking the (managed) object's destructor.
256///
257/// See @ref bslma_destructorproctor
258template <class TYPE>
260
261 // DATA
262 TYPE *d_object_p; // managed object
263
264 // NOT IMPLEMENTED
266 DestructorProctor& operator=(const DestructorProctor&);
267
268 public:
269 // CREATORS
270
271 /// Create a destructor proctor that conditionally manages the specified
272 /// `object` (if non-zero) by invoking the destructor of the object
273 /// managed by this proctor (if not released -- see `release`) upon
274 /// destruction.
275 explicit DestructorProctor(TYPE *object);
276
277 /// Destroy this destructor proctor, and destroy the object it manages
278 /// (if any) by invoking the destructor of the (managed) object. If no
279 /// object is currently being managed, this method has no effect.
281
282 // MANIPULATORS
283
284 /// Release from management the object currently managed by this
285 /// proctor. If no object is currently being managed, this method has
286 /// no effect.
287 void release();
288
289 /// Set the specified `object` as the object to be managed by this
290 /// proctor. The behavior is undefined unless `object` is non-zero.
291 /// Note that this method releases any previously-managed object from
292 /// management (without destroying it), and so may be invoked with or
293 /// without having called `release` when reusing this object.
294 void reset(TYPE *object);
295};
296
297// ============================================================================
298// INLINE DEFINITIONS
299// ============================================================================
300
301 // -----------------------
302 // class DestructorProctor
303 // -----------------------
304
305// CREATORS
306template <class TYPE>
307inline
309: d_object_p(object)
310{
311}
312
313template <class TYPE>
314inline
316{
317 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(0 != d_object_p)) {
318 DestructionUtil::destroy(d_object_p);
319 }
320}
321
322// MANIPULATORS
323template <class TYPE>
324inline
326{
327 d_object_p = 0;
328}
329
330template <class TYPE>
331inline
333{
334 BSLS_ASSERT_SAFE(object);
335
336 d_object_p = object;
337}
338
339} // close package namespace
340
341#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
342// ============================================================================
343// BACKWARD COMPATIBILITY
344// ============================================================================
345
346#ifdef bslma_DestructorProctor
347#undef bslma_DestructorProctor
348#endif
349/// This alias is defined for backward compatibility.
350#define bslma_DestructorProctor bslma::DestructorProctor
351#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
352
353
354
355#endif
356
357// ----------------------------------------------------------------------------
358// Copyright 2013 Bloomberg Finance L.P.
359//
360// Licensed under the Apache License, Version 2.0 (the "License");
361// you may not use this file except in compliance with the License.
362// You may obtain a copy of the License at
363//
364// http://www.apache.org/licenses/LICENSE-2.0
365//
366// Unless required by applicable law or agreed to in writing, software
367// distributed under the License is distributed on an "AS IS" BASIS,
368// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
369// See the License for the specific language governing permissions and
370// limitations under the License.
371// ----------------------------- END-OF-FILE ----------------------------------
372
373/** @} */
374/** @} */
375/** @} */
Definition bslma_destructorproctor.h:259
~DestructorProctor()
Definition bslma_destructorproctor.h:315
void release()
Definition bslma_destructorproctor.h:325
void reset(TYPE *object)
Definition bslma_destructorproctor.h:332
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition balxml_encoderoptions.h:68