BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslma_sharedptrinplacerep.h
Go to the documentation of this file.
1/// @file bslma_sharedptrinplacerep.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_sharedptrinplacerep.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_SHAREDPTRINPLACEREP
9#define INCLUDED_BSLMA_SHAREDPTRINPLACEREP
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$ $CSID$")
13
14/// @defgroup bslma_sharedptrinplacerep bslma_sharedptrinplacerep
15/// @brief Provide an in-place implementation of `bslma::SharedPtrRep`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_sharedptrinplacerep
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_sharedptrinplacerep-purpose"> Purpose</a>
25/// * <a href="#bslma_sharedptrinplacerep-classes"> Classes </a>
26/// * <a href="#bslma_sharedptrinplacerep-description"> Description </a>
27/// * <a href="#bslma_sharedptrinplacerep-thread-safety"> Thread Safety </a>
28/// * <a href="#bslma_sharedptrinplacerep-usage"> Usage </a>
29///
30/// # Purpose {#bslma_sharedptrinplacerep-purpose}
31/// Provide an in-place implementation of `bslma::SharedPtrRep`.
32///
33/// # Classes {#bslma_sharedptrinplacerep-classes}
34///
35/// - bslma::SharedPtrInplaceRep: in-place `bslma::SharedPtrRep` implementation
36///
37/// @see bslma_sharedptr, bslma_sharedptr_rep, bslma_sharedptroutofplacerep
38///
39/// # Description {#bslma_sharedptrinplacerep-description}
40/// This component provides a concrete implementation of
41/// `bslma::SharedPtrRep` for managing objects of the parameterized `TYPE` that
42/// are stored in-place in the representation . Thus, only one memory
43/// allocation is required to create both the representation and the managed
44/// object. When all references to the in-place object are released (using
45/// `releaseRef`), the destructor of `TYPE` is invoked.
46///
47/// ## Thread Safety {#bslma_sharedptrinplacerep-thread-safety}
48///
49///
50/// `bslma::SharedPtrInplaceRep` is thread-safe provided that `disposeObject`
51/// and `disposeRep` are not called explicitly, meaning that all non-creator
52/// operations other than `disposeObject` and `disposeRep` on a given instance
53/// can be safely invoked simultaneously from multiple threads (`disposeObject`
54/// and `disposeRep` are meant to be invoked only by `releaseRef` and
55/// `releaseWeakRef`). Note that there is no thread safety guarantees for
56/// operations on the managed object contained in `bslma::SharedPtrInplaceRep`.
57///
58/// ## Usage {#bslma_sharedptrinplacerep-usage}
59///
60///
61/// The following example demonstrates how to implement a shared
62/// `bdlt::Datetime` using `bslma::SharedPtrInplaceRep`:
63/// @code
64/// class MySharedDatetimePtr {
65/// // This class provide a reference counted smart pointer to support
66/// // shared ownership of a 'bdlt::Datetime' object.
67///
68/// bdlt::Datetime *d_ptr_p; // pointer to the managed object
69/// bslma::SharedPtrRep *d_rep_p; // pointer to the representation object
70///
71/// private:
72/// // NOT IMPLEMENTED
73/// MySharedDatetimePtr& operator=(const MySharedDatetimePtr&);
74///
75/// public:
76/// // CREATORS
77/// MySharedDatetimePtr();
78/// // Create an empty shared datetime.
79///
80/// MySharedDatetimePtr(bdlt::Datetime* ptr, bslma::SharedPtrRep* rep);
81/// // Create a shared datetime that adopts ownership of the specified
82/// // 'ptr' and the specified 'rep.
83///
84/// MySharedDatetimePtr(const MySharedDatetimePtr& original);
85/// // Create a shared datetime that refers to the same object managed
86/// // by the specified 'original'
87///
88/// ~MySharedDatetimePtr();
89/// // Destroy this shared datetime and release the reference to the
90/// // 'bdlt::Datetime' object to which it might be referring. If this
91/// // is the last shared reference, deleted the managed object.
92///
93/// // MANIPULATORS
94/// void createInplace(bslma::Allocator *basicAllocator,
95/// int year,
96/// int month,
97/// int day);
98/// // Create a new 'bslma::SharedPtrInplaceRep', using the specified
99/// // 'basicAllocator' to supply memory, using the specified 'year',
100/// // 'month' and 'day' to initialize the 'bdlt::Datetime' within the
101/// // newly created 'bslma::SharedPtrInplaceRep', and make this
102/// // object refer to the newly created 'bdlt::Datetime' object.
103///
104/// bdlt::Datetime& operator*() const;
105/// // Return a reference offering modifiable access to the shared
106/// // 'bdlt::Datetime' object.
107///
108/// bdlt::Datetime *operator->() const;
109/// // Return the address of the modifiable 'bdlt::Datetime' to which
110/// // this object refers.
111///
112/// bdlt::Datetime *ptr() const;
113/// // Return the address of the modifiable 'bdlt::Datetime' to which
114/// // this object refers.
115/// };
116/// @endcode
117/// Finally, we define the implementation.
118/// @code
119/// MySharedDatetimePtr::MySharedDatetimePtr()
120/// : d_ptr_p(0)
121/// , d_rep_p(0)
122/// {
123/// }
124///
125/// MySharedDatetimePtr::MySharedDatetimePtr(bdlt::Datetime *ptr,
126/// bslma::SharedPtrRep *rep)
127/// : d_ptr_p(ptr)
128/// , d_rep_p(rep)
129/// {
130/// }
131///
132/// MySharedDatetimePtr::MySharedDatetimePtr(
133/// const MySharedDatetimePtr& original)
134/// : d_ptr_p(original.d_ptr_p)
135/// , d_rep_p(original.d_rep_p)
136/// {
137/// if (d_ptr_p) {
138/// d_rep_p->acquireRef();
139/// } else {
140/// d_rep_p = 0;
141/// }
142/// }
143///
144/// MySharedDatetimePtr::~MySharedDatetimePtr()
145/// {
146/// if (d_rep_p) {
147/// d_rep_p->releaseRef();
148/// }
149/// }
150///
151/// void MySharedDatetimePtr::createInplace(bslma::Allocator *basicAllocator,
152/// int year,
153/// int month,
154/// int day)
155/// {
156/// basicAllocator = bslma::Default::allocator(basicAllocator);
157/// bslma::SharedPtrInplaceRep<bdlt::Datetime> *rep = new (*basicAllocator)
158/// bslma::SharedPtrInplaceRep<bdlt::Datetime>(basicAllocator,
159/// year,
160/// month,
161/// day);
162/// MySharedDatetimePtr temp(rep->ptr(), rep);
163/// bsl::swap(d_ptr_p, temp.d_ptr_p);
164/// bsl::swap(d_rep_p, temp.d_rep_p);
165/// }
166///
167/// bdlt::Datetime& MySharedDatetimePtr::operator*() const {
168/// return *d_ptr_p;
169/// }
170///
171/// bdlt::Datetime *MySharedDatetimePtr::operator->() const {
172/// return d_ptr_p;
173/// }
174///
175/// bdlt::Datetime *MySharedDatetimePtr::ptr() const {
176/// return d_ptr_p;
177/// }
178/// @endcode
179/// @}
180/** @} */
181/** @} */
182
183/** @addtogroup bsl
184 * @{
185 */
186/** @addtogroup bslma
187 * @{
188 */
189/** @addtogroup bslma_sharedptrinplacerep
190 * @{
191 */
192
193#include <bslscm_version.h>
194
195#include <bslma_allocator.h>
196#include <bslma_pointerutil.h>
197#include <bslma_sharedptrrep.h>
199
200#include <bslmf_movableref.h>
201#include <bslmf_util.h> // 'forward(V)'
202
203#include <bsls_assert.h>
205#include <bsls_keyword.h>
206#include <bsls_util.h> // 'Util::addressOf'
207
208#include <stddef.h>
209#include <typeinfo>
210
211#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
212// clang-format off
213// Include version that can be compiled with C++03
214// Generated on Mon Jan 13 08:31:27 2025
215// Command line: sim_cpp11_features.pl bslma_sharedptrinplacerep.h
216
217# define COMPILING_BSLMA_SHAREDPTRINPLACEREP_H
219# undef COMPILING_BSLMA_SHAREDPTRINPLACEREP_H
220
221// clang-format on
222#else
223
224
225namespace bslma {
226
227 // =========================
228 // class SharedPtrInplaceRep
229 // =========================
230
231/// This class provides a concrete implementation of the `SharedPtrRep`
232/// protocol for "in-place" instances of the parameterized `TYPE`. Upon
233/// destruction of this object, the destructor of `TYPE` is invoked.
234///
235/// See @ref bslma_sharedptrinplacerep
236template <class TYPE>
238
239 // DATA
240 Allocator *d_allocator_p; // memory allocator (held, not owned)
241
242 TYPE d_instance; // Beginning of the in-place buffer. Note that
243 // this must be last in this layout to allow for
244 // the possibility of creating in-place
245 // uninitialized buffer, where it is possible to
246 // access memory beyond the 'd_instance'
247 // footprint (refer to 'bsl::shared_ptr::
248 // createInplaceUninitializedBuffer' for sample
249 // usage)
250
251 private:
252 // NOT IMPLEMENTED
254 SharedPtrInplaceRep& operator=(const SharedPtrInplaceRep&);
255
256 // PRIVATE CREATORS
257
258 /// Destroy this representation object and the embedded instance of parameterized `TYPE`.
259 ///
260 /// \note Note that this destructor is never called.
261 /// Instead, `disposeObject` destroys the in-place object and
262 /// `disposeRep` deallocates this representation object (including the
263 /// shared object's footprint).
265
266 public:
267 // CREATORS
268#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
269
270 /// Create a `SharedPtrInplaceRep` object having an "in-place" instance
271 /// of the parameterized `TYPE` using the `TYPE` constructor that takes
272 /// the specified arguments, `args...`. Use the specified
273 /// `basicAllocator` to supply memory and, upon a call to `disposeRep`,
274 /// to destroy this representation (and the "in-place" shared object).
275 /// If construction of `TYPE` with `args` does not throw, then
276 /// invocation of this constructor does not throw.
277 template <class... ARGS>
278 explicit SharedPtrInplaceRep(Allocator *basicAllocator,
279 ARGS&&... args);
280#endif
281
282 // MANIPULATORS
283
284 /// Destroy the object being referred to by this representation. This
285 /// method is automatically invoked by `releaseRef` when the number of
286 /// shared references reaches zero and should not be explicitly invoked otherwise.
287 ///
288 /// \note Note that this function calls the destructor for the
289 /// shared object, but does not deallocate its footprint.
291
292 /// Deallocate the memory associated with this representation object
293 /// (including the shared object's footprint). This method is
294 /// automatically invoked by `releaseRef` and `releaseWeakRef` when the
295 /// number of weak references and the number of shared references both
296 /// reach zero and should not be explicitly invoked otherwise.
297 ///
298 /// \pre The behavior is undefined unless `disposeObject` has already been called for this representation.
299 ///
300 /// \note Note that this `disposeRep` method
301 /// effectively serves as the representation object's destructor.
303
304 /// Return a null pointer.
305 /// \note Note that the specified `type` is not used
306 /// as an in-place representation for a shared pointer can never store a
307 /// user-supplied deleter (there is no function that might try to create
308 /// one).
309 void *getDeleter(const std::type_info& type) BSLS_KEYWORD_OVERRIDE;
310
311 /// Return the address of the modifiable (in-place) object referred to
312 /// by this representation object.
313 TYPE *ptr();
314
315 // ACCESSORS
316
317 /// Return the (untyped) address of the modifiable (in-place) object
318 /// referred to by this representation object.
320};
321
322 //============================
323 // SharedPtrInplaceRep_ImpUtil
324 //============================
325
326/// This struct provides a namespace for several static methods that ease
327/// the implementation of many methods of the `SharedPtrInplaceRep` class.
328///
329/// See @ref bslma_sharedptrinplacerep
331
332 // CLASS METHODS
333
334 /// Return the specified `reference`.
335 /// \note Note that this pair of overloaded
336 /// functions is necessary to correctly forward movable references when
337 /// providing explicit move-semantics for C++03; otherwise the
338 /// `MovableRef` is likely to be wrapped in multiple layers of reference
339 /// wrappers, and not be recognized as the movable vocabulary type.
340 template <class TYPE>
341 static const TYPE& forward(const TYPE& reference);
342 template <class TYPE>
343 static BloombergLP::bslmf::MovableRef<TYPE> forward(
344 const BloombergLP::bslmf::MovableRef<TYPE>& reference);
345
346 /// Destroy the specified `object`.
347 template <class TYPE>
348 static void dispose(const TYPE& object);
349
350 /// Destroy each element of the specified `object`.
351 template <class TYPE, size_t SIZE>
352 static void dispose(const TYPE (&object)[SIZE]);
353};
354
355// ============================================================================
356// INLINE DEFINITIONS
357// ============================================================================
358
359
360 // ---------------------------
361 // SharedPtrInplaceRep_ImpUtil
362 // ---------------------------
363
364template <class TYPE>
365inline
366const TYPE& SharedPtrInplaceRep_ImpUtil::forward(const TYPE& reference)
367{
368 return reference;
369}
370
371template <class TYPE>
372inline
373BloombergLP::bslmf::MovableRef<TYPE> SharedPtrInplaceRep_ImpUtil::forward(
374 const BloombergLP::bslmf::MovableRef<TYPE>& reference)
375{
376 return reference;
377}
378
379template <class TYPE>
380inline
382{
383 object.~TYPE();
384}
385
386template <class TYPE, size_t SIZE>
387inline
388void SharedPtrInplaceRep_ImpUtil::dispose(const TYPE (&object)[SIZE])
389{
390 for (size_t i = 0; i < SIZE; ++i) {
391 dispose(object[i]);
392 }
393}
394
395 // -------------------------
396 // class SharedPtrInplaceRep
397 // -------------------------
398
399// CREATORS
400#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
401template <class TYPE>
402template <class... ARGS>
404 ARGS&&... args)
405: d_allocator_p(basicAllocator)
406, d_instance(BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...)
407{
408}
409#endif
410
411template <class TYPE>
413{
414 BSLS_ASSERT(0);
415}
416
417// MANIPULATORS
418template <class TYPE>
419inline
424
425template <class TYPE>
426inline
428{
429 d_allocator_p->deallocate(this);
430}
431
432template <class TYPE>
433inline
434void *SharedPtrInplaceRep<TYPE>::getDeleter(const std::type_info&)
435{
436 return 0;
437}
438
439template <class TYPE>
440inline
442{
443 return bsls::Util::addressOf(d_instance);
444}
445
446// ACCESSORS
447template <class TYPE>
448inline
453
454// ============================================================================
455// TYPE TRAITS
456// ============================================================================
457
458/// The class template `SharedPtrInplaceRep` appears to use allocators, but
459/// passes its allocator argument in the first position, rather than in the
460/// last position, so is not compatible with BDE APIs that use this trait.
461template <class ELEMENT_TYPE>
464};
465
466} // close package namespace
467
468
469#endif // End C++11 code
470
471#endif
472
473// ----------------------------------------------------------------------------
474// Copyright 2013 Bloomberg Finance L.P.
475//
476// Licensed under the Apache License, Version 2.0 (the "License");
477// you may not use this file except in compliance with the License.
478// You may obtain a copy of the License at
479//
480// http://www.apache.org/licenses/LICENSE-2.0
481//
482// Unless required by applicable law or agreed to in writing, software
483// distributed under the License is distributed on an "AS IS" BASIS,
484// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
485// See the License for the specific language governing permissions and
486// limitations under the License.
487// ----------------------------- END-OF-FILE ----------------------------------
488
489/** @} */
490/** @} */
491/** @} */
Definition bslma_allocator.h:545
Definition bslma_sharedptrinplacerep.h:237
void * getDeleter(const std::type_info &type) BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:434
void * originalPtr() const BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:449
void disposeObject() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:420
void disposeRep() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:427
TYPE * ptr()
Definition bslma_sharedptrinplacerep.h:441
Definition bslma_sharedptrrep.h:338
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition baljsn_encoder_testtypes.h:76
Definition bslmf_integralconstant.h:261
static BSLS_KEYWORD_CONSTEXPR void * voidify(TYPE *address) BSLS_KEYWORD_NOEXCEPT
Definition bslma_pointerutil.h:350
Definition bslma_sharedptrinplacerep.h:330
static const TYPE & forward(const TYPE &reference)
Definition bslma_sharedptrinplacerep.h:366
static void dispose(const TYPE &object)
Destroy the specified object.
Definition bslma_sharedptrinplacerep.h:381
Definition bslma_usesbslmaallocator.h:344
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:312