BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslma_managedptr_members.h
Go to the documentation of this file.
1/// @file bslma_managedptr_members.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_managedptr_members.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_MANAGEDPTR_MEMBERS
9#define INCLUDED_BSLMA_MANAGEDPTR_MEMBERS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_managedptr_members bslma_managedptr_members
15/// @brief Provide the internal state of a managed pointer class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_managedptr_members
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_managedptr_members-purpose"> Purpose</a>
25/// * <a href="#bslma_managedptr_members-classes"> Classes </a>
26/// * <a href="#bslma_managedptr_members-description"> Description </a>
27///
28/// # Purpose {#bslma_managedptr_members-purpose}
29/// Provide the internal state of a managed pointer class.
30///
31/// # Classes {#bslma_managedptr_members-classes}
32///
33/// - bslma::ManagedPtr_Members: internal state of a `bslma::ManagedPtr` object
34///
35/// @see bslma_managedptr
36///
37/// # Description {#bslma_managedptr_members-description}
38/// This component provides a class, `bslma::ManagedPtr_Members`,
39/// to store and manage the internal state of a `bslma::ManagedPtr` object. It
40/// enforces the rules for correct transfer of ownership from one
41/// `bslma::ManagedPtr` object to another. A `bslma::ManagedPtr_Members` object
42/// has two attributes:
43/// * pointer - address of the object being managed, or an alias to the object
44/// * deleter - address of a function used to destroy the managed object
45/// @}
46/** @} */
47/** @} */
48
49/** @addtogroup bsl
50 * @{
51 */
52/** @addtogroup bslma
53 * @{
54 */
55/** @addtogroup bslma_managedptr_members
56 * @{
57 */
58
59#include <bslscm_version.h>
60
62
64
65#include <bsls_assert.h>
66
67
68namespace bslma {
69
70 // ========================
71 // class ManagedPtr_Members
72 // ========================
73
74/// This class provides a type-agnostic container for managed pointer data
75/// members. This type exists so that a `ManagedPtr_Ref` (see
76/// @ref bslma_managedptr ) can point to the representation of a `ManagedPtr`
77/// even if the `ManagedPtr_Ref` object is instantiated on a different type
78/// than the managed pointer type (e.g., in the case of conversions or
79/// aliasing). `ManagedPtr_Members` also "erases" the type of each member,
80/// so that the same object code can be shared between all instantiations of
81/// the `ManagedPtr` class template, reducing template bloat.
82///
83/// \note Note that objects of this type have an "unset" state, where the pointer member has
84/// a null value and the deleter member has an unspecified value.
85///
86/// See @ref bslma_managedptr_members
88
89 private:
90 // PRIVATE TYPES
91 typedef ManagedPtrDeleter::Deleter DeleterFunc;
92
93 // DATA
94 void *d_obj_p; // pointer to the managed object, or an
95 // alias to the object; 'void *' is used so
96 // that this single (non-template) class may
97 // be used for any instantiation of
98 // 'bslma::ManagedPtr'
99
100 ManagedPtrDeleter d_deleter; // deleter-related information
101
102 private:
103 // NOT IMPLEMENTED
104 ManagedPtr_Members& operator=(const ManagedPtr_Members&);
105
106 public:
107 // CREATORS
108
109 /// Create a `ManagedPtr_Members` object in an unset state, i.e., where
110 /// `pointer` is null and `deleter` has an unspecified value.
112
113 /// Create a `ManagedPtr_Members` object having the same `pointer` as
114 /// the specified `other` object, and, if `0 != other.pointer()`, the
115 /// same deleter as `other`, then put `other` into an unset state.
116 explicit ManagedPtr_Members(ManagedPtr_Members& other);
117
118 /// Create a `ManagedPtr_Members` object having the specified `object`,
119 /// `factory`, and `deleter`. The newly created object does not manage a pointer if `0 == object`.
120 ///
121 /// \pre The behavior is undefined unless
122 /// `object` is null if `deleter` is null.
123 ManagedPtr_Members(void *object, void *factory, DeleterFunc deleter);
124
125 /// Create a `ManagedPtr_Members` object having the specified `object`,
126 /// `factory`, `deleter`, and `alias`. The newly created object does
127 /// not manage a pointer if `0 == object`.
128 ///
129 /// \pre The behavior is undefined unless `object` is null if `deleter` is null, and `0 == object` if and only if `0 == alias`.
130 ///
131 /// \note Note that this constructor is important
132 /// for managed pointers pointing to one of multiple base classes of a
133 /// class using multiple inheritance.
134 ManagedPtr_Members(void *object,
135 void *factory,
136 DeleterFunc deleter,
137 void *alias);
138
140 // Destroy this object. Note that this trivial destructor's definition
141 // is compiler generated.
142
143 // MANIPULATORS
144
145 /// Reset this object to an unset state with no effect on the previously
146 /// managed object (if any).
147 void clear();
148
149 /// Reset this object to have the same `pointer` as the specified
150 /// `other` object, and, if `0 != other->pointer()`, the same deleter as
151 /// `other`, then put `other` into an unset state. This method has no
152 /// effect on the previously managed object (if any).
153 ///
154 /// \pre The behavior is undefined unless `this != other`.
155 void move(ManagedPtr_Members *other);
156
157 /// Destroy the currently managed object (if any), reset this object to
158 /// have the same `pointer` as the specified `other` object, and, if
159 /// `0 != other->pointer()`, the same deleter as `other`, then put
160 /// `other` into an unset state. This method has no effect if
161 /// `this == other`.
162 void moveAssign(ManagedPtr_Members *other);
163
164 /// Reset this object to have the specified `object`, `factory`, and
165 /// `deleter` with no effect on the previously managed object (if any).
166 /// The object does not manage a pointer if `0 == object`.
167 ///
168 /// \pre The behavior is undefined unless `object` is null if `deleter` is null.
169 void set(void *object, void *factory, DeleterFunc deleter);
170
171 /// Set `pointer` to have the specified `alias`. If `0 == alias`, then
172 /// this object will have an unset state with no effect on the
173 /// previously managed object (if any).
174 ///
175 /// \pre The behavior is undefined unless `0 == pointer()` if and only if `0 == alias`.
176 void setAliasPtr(void *alias);
177
178 /// Efficiently exchange the state of this object with the state of the
179 /// specified `other` object. This method provides the no-throw exception-safety guarantee.
180 ///
181 /// \note Note that if either object is in an
182 /// unset state, then the only guarantee about the unset state that may
183 /// be exchanged is that the `pointer` value shall be null.
185
186 // ACCESSORS
187
188 /// Return a reference providing non-modifiable access to the deleter
189 /// used to destroy the currently managed object (if any).
190 ///
191 /// \pre The behavior is undefined unless `pointer` is not null.
192 const ManagedPtrDeleter& deleter() const;
193
194 /// Return the address providing modifiable access to the currently
195 /// managed object, or 0 if this object is in an unset state.
196 ///
197 /// \note Note that the returned pointer may be an alias to the managed object.
198 void *pointer() const;
199
200 /// Destroy the currently managed object (if any).
201 /// \note Note that calling
202 /// this method twice on an object that is not in an unset state,
203 /// without assigning a new pointer to manage between the two calls,
204 /// results in undefined behavior unless this object's deleter
205 /// specifically supports such usage.
206 void runDeleter() const;
207};
208
209// ============================================================================
210// INLINE DEFINITIONS
211// ============================================================================
212
213 // ------------------------
214 // class ManagedPtr_Members
215 // ------------------------
216
217// CREATORS
218inline
220: d_obj_p(0)
221{
222}
223
224inline
226: d_obj_p(other.d_obj_p)
227{
228 if (d_obj_p) {
229 d_deleter = other.d_deleter;
230 }
231 other.clear();
232}
233
234inline
236 void *factory,
237 DeleterFunc deleter)
238: d_obj_p(object)
239, d_deleter(object, factory, deleter)
240{
241 BSLS_ASSERT_SAFE(0 != deleter || 0 == object);
242}
243
244inline
246 void *factory,
247 DeleterFunc deleter,
248 void *alias)
249: d_obj_p(alias)
250, d_deleter(object, factory, deleter)
251{
252 BSLS_ASSERT_SAFE(0 != deleter || 0 == object);
253 BSLS_ASSERT_SAFE(!object == !alias); // both are null, or neither is null
254}
255
256// MANIPULATORS
257inline
259{
260 d_obj_p = 0;
261}
262
263inline
265{
266 BSLS_ASSERT_SAFE(other);
267 BSLS_ASSERT_SAFE(this != other);
268
269 // If 'other->d_obj_p' is null, then 'other->d_deleter' has an unspecified
270 // value.
271
272 d_obj_p = other->d_obj_p;
273 if (other->d_obj_p) {
274 d_deleter = other->d_deleter;
275 }
276
277 other->clear();
278}
279
280inline
282{
283 BSLS_ASSERT_SAFE(other);
284
285 // Must protect against self-assignment due to destructive move.
286
287 if (this != other) {
288 runDeleter();
289 move(other);
290 }
291}
292
293inline
294void ManagedPtr_Members::set(void *object, void *factory, DeleterFunc deleter)
295{
296 BSLS_ASSERT_SAFE(0 != deleter || 0 == object);
297
298 // Note that 'factory' may be null if 'deleter' supports it, so that cannot
299 // be asserted here.
300
301 d_obj_p = object;
302 if (object) {
303 d_deleter.set(object, factory, deleter);
304 }
305}
306
307inline
309{
310 BSLS_ASSERT_SAFE(!alias == !d_obj_p); // both are null, or neither is null
311
312 d_obj_p = alias;
313}
314
315// ACCESSORS
316inline
318{
319 BSLS_ASSERT_SAFE(d_obj_p);
320
321 return d_deleter;
322}
323
324inline
326{
327 return d_obj_p;
328}
329
330inline
332{
333 if (d_obj_p) {
334 d_deleter.deleteManagedObject();
335 }
336}
337
338} // close package namespace
339
340// TYPE TRAITS
341namespace bslmf {
342
343template <>
344struct IsBitwiseMoveable<bslma::ManagedPtr_Members> : bsl::true_type
345{
346};
347
348} // close namespace bslmf
349
350
351#endif
352
353// ----------------------------------------------------------------------------
354// Copyright 2016 Bloomberg Finance L.P.
355//
356// Licensed under the Apache License, Version 2.0 (the "License");
357// you may not use this file except in compliance with the License.
358// You may obtain a copy of the License at
359//
360// http://www.apache.org/licenses/LICENSE-2.0
361//
362// Unless required by applicable law or agreed to in writing, software
363// distributed under the License is distributed on an "AS IS" BASIS,
364// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
365// See the License for the specific language governing permissions and
366// limitations under the License.
367// ----------------------------- END-OF-FILE ----------------------------------
368
369/** @} */
370/** @} */
371/** @} */
Definition bslma_managedptrdeleter.h:114
void(* Deleter)(void *managedObject, void *cookie)
Deleter function prototype used to destroy the managed pointer.
Definition bslma_managedptrdeleter.h:120
void set(void *object, void *factory, Deleter deleter)
Definition bslma_managedptrdeleter.h:247
void deleteManagedObject() const
Definition bslma_managedptrdeleter.h:256
Definition bslma_managedptr_members.h:87
void moveAssign(ManagedPtr_Members *other)
Definition bslma_managedptr_members.h:281
void clear()
Definition bslma_managedptr_members.h:258
ManagedPtr_Members()
Definition bslma_managedptr_members.h:219
const ManagedPtrDeleter & deleter() const
Definition bslma_managedptr_members.h:317
void swap(ManagedPtr_Members &other)
void move(ManagedPtr_Members *other)
Definition bslma_managedptr_members.h:264
void setAliasPtr(void *alias)
Definition bslma_managedptr_members.h:308
void runDeleter() const
Definition bslma_managedptr_members.h:331
void set(void *object, void *factory, DeleterFunc deleter)
Definition bslma_managedptr_members.h:294
void * pointer() const
Definition bslma_managedptr_members.h:325
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bslmf_isbitwisemoveable.h:718