BDE 4.14.0 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_sharedptrrep.h>
198
199#include <bslmf_movableref.h>
200#include <bslmf_util.h> // 'forward(V)'
201
202#include <bsls_assert.h>
204#include <bsls_keyword.h>
205#include <bsls_util.h>
206
207#include <stddef.h>
208#include <typeinfo>
209
210#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
211// Include version that can be compiled with C++03
212// Generated on Thu Oct 21 10:11:37 2021
213// Command line: sim_cpp11_features.pl bslma_sharedptrinplacerep.h
214# define COMPILING_BSLMA_SHAREDPTRINPLACEREP_H
216# undef COMPILING_BSLMA_SHAREDPTRINPLACEREP_H
217#else
218
219
220namespace bslma {
221
222 // =========================
223 // class SharedPtrInplaceRep
224 // =========================
225
226/// This class provides a concrete implementation of the `SharedPtrRep`
227/// protocol for "in-place" instances of the parameterized `TYPE`. Upon
228/// destruction of this object, the destructor of `TYPE` is invoked.
229///
230/// See @ref bslma_sharedptrinplacerep
231template <class TYPE>
233
234 // DATA
235 Allocator *d_allocator_p; // memory allocator (held, not owned)
236
237 TYPE d_instance; // Beginning of the in-place buffer. Note that
238 // this must be last in this layout to allow for
239 // the possibility of creating in-place
240 // uninitialized buffer, where it is possible to
241 // access memory beyond the 'd_instance'
242 // footprint (refer to 'bsl::shared_ptr::
243 // createInplaceUninitializedBuffer' for sample
244 // usage)
245
246 private:
247 // NOT IMPLEMENTED
249 SharedPtrInplaceRep& operator=(const SharedPtrInplaceRep&);
250
251 // PRIVATE CREATORS
252
253 /// Destroy this representation object and the embedded instance of
254 /// parameterized `TYPE`. Note that this destructor is never called.
255 /// Instead, `disposeObject` destroys the in-place object and
256 /// `disposeRep` deallocates this representation object (including the
257 /// shared object's footprint).
259
260 public:
261 // CREATORS
262#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
263
264 /// Create a `SharedPtrInplaceRep` object having an "in-place" instance
265 /// of the parameterized `TYPE` using the `TYPE` constructor that takes
266 /// the specified arguments, `args...`. Use the specified
267 /// `basicAllocator` to supply memory and, upon a call to `disposeRep`,
268 /// to destroy this representation (and the "in-place" shared object).
269 /// If construction of `TYPE` with `args` does not throw, then
270 /// invocation of this constructor does not throw.
271 template <class... ARGS>
272 explicit SharedPtrInplaceRep(Allocator *basicAllocator,
273 ARGS&&... args);
274#endif
275
276 // MANIPULATORS
277
278 /// Destroy the object being referred to by this representation. This
279 /// method is automatically invoked by `releaseRef` when the number of
280 /// shared references reaches zero and should not be explicitly invoked
281 /// otherwise. Note that this function calls the destructor for the
282 /// shared object, but does not deallocate its footprint.
284
285 /// Deallocate the memory associated with this representation object
286 /// (including the shared object's footprint). This method is
287 /// automatically invoked by `releaseRef` and `releaseWeakRef` when the
288 /// number of weak references and the number of shared references both
289 /// reach zero and should not be explicitly invoked otherwise. The
290 /// behavior is undefined unless `disposeObject` has already been called
291 /// for this representation. Note that this `disposeRep` method
292 /// effectively serves as the representation object's destructor.
294
295 /// Return a null pointer. Note that the specified `type` is not used
296 /// as an in-place representation for a shared pointer can never store a
297 /// user-supplied deleter (there is no function that might try to create
298 /// one).
299 void *getDeleter(const std::type_info& type) BSLS_KEYWORD_OVERRIDE;
300
301 /// Return the address of the modifiable (in-place) object referred to
302 /// by this representation object.
303 TYPE *ptr();
304
305 // ACCESSORS
306
307 /// Return the (untyped) address of the modifiable (in-place) object
308 /// referred to by this representation object.
310};
311
312 //============================
313 // SharedPtrInplaceRep_ImpUtil
314 //============================
315
316/// This struct provides a namespace for several static methods that ease
317/// the implementation of many methods of the `SharedPtrInplaceRep` class.
319
320 // CLASS METHODS
321
322 /// Return the specified `reference`. Note that this pair of overloaded
323 /// functions is necessary to correctly forward movable references when
324 /// providing explicit move-semantics for C++03; otherwise the
325 /// `MovableRef` is likely to be wrapped in multiple layers of reference
326 /// wrappers, and not be recognized as the movable vocabulary type.
327 template <class TYPE>
328 static const TYPE& forward(const TYPE& reference);
329 template <class TYPE>
330 static BloombergLP::bslmf::MovableRef<TYPE> forward(
331 const BloombergLP::bslmf::MovableRef<TYPE>& reference);
332
333 /// Return the specified `address` cast as a pointer to `void`, even if
334 /// (the template parameter) `TYPE` is cv-qualified.
335 template <class TYPE>
336 static void *voidify(TYPE *address);
337
338 /// Destroy the specified `object`.
339 template <class TYPE>
340 static void dispose(const TYPE& object);
341
342 /// Destroy each element of the specified `object`.
343 template <class TYPE, size_t SIZE>
344 static void dispose(const TYPE (&object)[SIZE]);
345};
346
347// ============================================================================
348// INLINE DEFINITIONS
349// ============================================================================
350
351
352 // ---------------------------
353 // SharedPtrInplaceRep_ImpUtil
354 // ---------------------------
355
356template <class TYPE>
357inline
358const TYPE& SharedPtrInplaceRep_ImpUtil::forward(const TYPE& reference)
359{
360 return reference;
361}
362
363template <class TYPE>
364inline
365BloombergLP::bslmf::MovableRef<TYPE> SharedPtrInplaceRep_ImpUtil::forward(
366 const BloombergLP::bslmf::MovableRef<TYPE>& reference)
367{
368 return reference;
369}
370
371template <class TYPE>
372inline
374 return static_cast<void *>(
375 const_cast<typename bsl::remove_cv<TYPE>::type *>(address));
376}
377
378template <class TYPE>
379inline
381{
382 object.~TYPE();
383}
384
385template <class TYPE, size_t SIZE>
386inline
387void SharedPtrInplaceRep_ImpUtil::dispose(const TYPE (&object)[SIZE])
388{
389 for (size_t i = 0; i < SIZE; ++i) {
390 dispose(object[i]);
391 }
392}
393
394 // -------------------------
395 // class SharedPtrInplaceRep
396 // -------------------------
397
398// CREATORS
399#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
400template <class TYPE>
401template <class... ARGS>
403 ARGS&&... args)
404: d_allocator_p(basicAllocator)
405, d_instance(BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...)
406{
407}
408#endif
409
410template <class TYPE>
412{
413 BSLS_ASSERT(0);
414}
415
416// MANIPULATORS
417template <class TYPE>
418inline
423
424template <class TYPE>
425inline
427{
428 d_allocator_p->deallocate(this);
429}
430
431template <class TYPE>
432inline
433void *SharedPtrInplaceRep<TYPE>::getDeleter(const std::type_info&)
434{
435 return 0;
436}
437
438template <class TYPE>
439inline
441{
442 return bsls::Util::addressOf(d_instance);
443}
444
445// ACCESSORS
446template <class TYPE>
447inline
449{
450 return const_cast<void *>(static_cast<const void *>(
451 bsls::Util::addressOf(d_instance)));
452}
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:457
Definition bslma_sharedptrinplacerep.h:232
void * getDeleter(const std::type_info &type) BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:433
void * originalPtr() const BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:448
void disposeObject() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:419
void disposeRep() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptrinplacerep.h:426
TYPE * ptr()
Definition bslma_sharedptrinplacerep.h:440
Definition bslma_sharedptrrep.h:338
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition balxml_encoderoptions.h:68
Definition bslmf_integralconstant.h:244
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:126
Definition bslma_sharedptrinplacerep.h:318
static void * voidify(TYPE *address)
Definition bslma_sharedptrinplacerep.h:373
static const TYPE & forward(const TYPE &reference)
Definition bslma_sharedptrinplacerep.h:358
static void dispose(const TYPE &object)
Destroy the specified object.
Definition bslma_sharedptrinplacerep.h:380
Definition bslma_usesbslmaallocator.h:343
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305