BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_sharedptroutofplacerep.h
Go to the documentation of this file.
1/// @file bslma_sharedptroutofplacerep.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_sharedptroutofplacerep.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_SHAREDPTROUTOFPLACEREP
9#define INCLUDED_BSLMA_SHAREDPTROUTOFPLACEREP
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$ $CSID$")
13
14/// @defgroup bslma_sharedptroutofplacerep bslma_sharedptroutofplacerep
15/// @brief Provide an out-of-place implementation of `bslma::SharedPtrRep`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_sharedptroutofplacerep
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_sharedptroutofplacerep-purpose"> Purpose</a>
25/// * <a href="#bslma_sharedptroutofplacerep-classes"> Classes </a>
26/// * <a href="#bslma_sharedptroutofplacerep-description"> Description </a>
27/// * <a href="#bslma_sharedptroutofplacerep-thread-safety"> Thread Safety </a>
28/// * <a href="#bslma_sharedptroutofplacerep-deleters"> Deleters </a>
29/// * <a href="#bslma_sharedptroutofplacerep-usage"> Usage </a>
30///
31/// # Purpose {#bslma_sharedptroutofplacerep-purpose}
32/// Provide an out-of-place implementation of `bslma::SharedPtrRep`.
33///
34/// # Classes {#bslma_sharedptroutofplacerep-classes}
35///
36/// - bslma::SharedPtrOutofplaceRep: out-of-place shared pointer implementation
37///
38/// @see bslma_sharedptr, bslma_sharedptrrep, bslma_sharedptrinplacerep
39///
40/// # Description {#bslma_sharedptroutofplacerep-description}
41/// This component provides a concrete implementation of
42/// `bslma::SharedPtrRep` for managing objects of the parameterized `TYPE` that
43/// are stored outside of the representation. When all references to the
44/// out-of-place object are released using `releaseRef`, the deleter of the
45/// parameterized `DELETER` type is invoked to delete the shared object.
46///
47/// ## Thread Safety {#bslma_sharedptroutofplacerep-thread-safety}
48///
49///
50/// `bslma::SharedPtrOutofplaceRep` 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.
57///
58/// ## Deleters {#bslma_sharedptroutofplacerep-deleters}
59///
60///
61/// When the last shared reference to a shared object is released, the object is
62/// destroyed using the "deleter" provided when the associated shared pointer
63/// representation was created. `bslma::SharedPtrOutofplaceRep` supports two
64/// kinds of "deleter" objects, which vary in how they are invoked. A
65/// "function-like" deleter is any language entity that can be invoked such that
66/// the expression `deleterInstance(objectPtr)` is a valid expression, and a
67/// "factory" deleter is any language entity that can be invoked such that the
68/// expression `deleterInstance.deleteObject(objectPtr)` is a valid expression,
69/// where `deleterInstance` is an instance of the "deleter" object, and
70/// `objectPtr` is a pointer to the shared object. In summary:
71/// @code
72/// Deleter Expression used to destroy 'objectPtr'
73/// - - - - - - - - - - - - - - - - - - - - - - - - - - -
74/// "function-like" deleterInstance(objectPtr);
75/// "factory" deleterInstance.deleteObject(objectPtr);
76/// @endcode
77/// The following are examples of function-like deleters that delete an object
78/// of `MyType`:
79/// @code
80/// void deleteObject(MyType *object);
81/// // Delete the specified 'object'.
82///
83/// void releaseObject(MyType *object);
84/// // Release the specified 'object'.
85///
86/// struct FunctionLikeDeleterObject {
87/// // This 'struct' provides an 'operator()' that can be used to delete a
88/// // 'MyType' object.
89///
90/// void operator()(MyType *object);
91/// // Destroy the specified 'object'.
92/// };
93/// @endcode
94/// The following on the other hand is an example of a factory deleter:
95/// @code
96/// class MyFactory {
97///
98/// // . . .
99///
100/// // MANIPULATORS
101/// MyType *createObject(bslma::Allocator *basicAllocator = 0);
102/// // Create a 'MyType' object. Optionally specify a
103/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
104/// // 0, the currently installed default allocator is used.
105///
106/// void deleteObject(MyType *object);
107/// // Delete the specified 'object'.
108/// };
109/// @endcode
110/// Note that `deleteObject` is provided by all `bslma` allocators and by any
111/// object that implements the `bdlma::Deleter` protocol. Thus, any of these
112/// objects can be used as a factory deleter. The purpose of this design is to
113/// allow `bslma` allocators and factories to be used seamlessly as deleters.
114///
115/// The selection of which expression is used by `bslma::SharedPtrOutofplaceRep`
116/// to destroy a shared object is based on how the deleter is passed to the
117/// shared pointer object: Deleters that are passed by *address* are assumed to
118/// be factory deleters, while those that are passed by *value* are assumed to
119/// be function-like. Note that if the wrong interface is used for a deleter,
120/// i.e., if a function-like deleter is passed by pointer, or a factory deleter
121/// is passed by value, and the expression used to delete the object is invalid,
122/// a compiler diagnostic will be emitted indicating the error.
123///
124/// ## Usage {#bslma_sharedptroutofplacerep-usage}
125///
126///
127/// The following example demonstrates how to implement a shared
128/// `bdlt::Datetime` object using `bslma::SharedPtrOutofplaceRep`:
129/// @code
130/// class MySharedDatetimePtr {
131/// // This class provide a reference counted smart pointer to support
132/// // shared ownership of a 'bdlt::Datetime' object.
133///
134/// private:
135/// bdlt::Datetime *d_ptr_p; // pointer to the managed object
136/// bslma::SharedPtrRep *d_rep_p; // pointer to the representation object
137///
138/// private:
139/// // NOT IMPLEMENTED
140/// MySharedDatetimePtr& operator=(const MySharedDatetimePtr&);
141///
142/// public:
143/// // CREATORS
144/// MySharedDatetimePtr(bdlt::Datetime *ptr,
145/// bslma::Allocator *basicAllocator = 0);
146/// // Create a 'MySharedDatetimePtr' object to managed the specified
147/// // 'ptr'. Optionally specify an 'basicAllocator' to allocate and
148/// // deallocate the internal representation and to destroy 'ptr' when
149/// // all references have been released. The behavior is undefined
150/// // unless 'ptr' was allocated using memory supplied by
151/// // 'basicAllocator'.
152///
153/// MySharedDatetimePtr(const MySharedDatetimePtr& original);
154/// // Create a shared datetime that refers to the same object managed
155/// // by the specified 'original'
156///
157/// ~MySharedDatetimePtr();
158/// // Destroy this shared datetime and release the reference to the
159/// // 'bdlt::Datetime' object to which it might be referring. If this
160/// // is the last shared reference, deleted the managed object.
161///
162/// // MANIPULATORS
163/// bdlt::Datetime& operator*() const;
164/// // Return a reference offering modifiable access to the shared
165/// // datetime.
166///
167/// bdlt::Datetime *operator->() const;
168/// // Return the address of the modifiable 'bdlt::Datetime' to which
169/// // this object refers.
170///
171/// bdlt::Datetime *ptr() const;
172/// // Return the address of the modifiable 'bdlt::Datetime' to which
173/// // this object refers.
174/// };
175/// @endcode
176/// Finally, we define the implementation.
177/// @code
178/// MySharedDatetimePtr::MySharedDatetimePtr(bdlt::Datetime *ptr,
179/// bslma::Allocator *basicAllocator)
180/// {
181/// d_ptr_p = ptr;
182/// d_rep_p =
183/// bslma::SharedPtrOutofplaceRep<bdlt::Datetime, bslma::Allocator *>::
184/// makeOutofplaceRep(ptr, basicAllocator, basicAllocator);
185/// }
186///
187/// MySharedDatetimePtr::MySharedDatetimePtr(
188/// const MySharedDatetimePtr& original)
189/// : d_ptr_p(original.d_ptr_p)
190/// , d_rep_p(original.d_rep_p)
191/// {
192/// if (d_ptr_p) {
193/// d_rep_p->acquireRef();
194/// } else {
195/// d_rep_p = 0;
196/// }
197/// }
198///
199/// MySharedDatetimePtr::~MySharedDatetimePtr()
200/// {
201/// if (d_rep_p) {
202/// d_rep_p->releaseRef();
203/// }
204/// }
205///
206/// bdlt::Datetime& MySharedDatetimePtr::operator*() const {
207/// return *d_ptr_p;
208/// }
209///
210/// bdlt::Datetime *MySharedDatetimePtr::operator->() const {
211/// return d_ptr_p;
212/// }
213///
214/// bdlt::Datetime *MySharedDatetimePtr::ptr() const {
215/// return d_ptr_p;
216/// }
217/// @endcode
218/// @}
219/** @} */
220/** @} */
221
222/** @addtogroup bsl
223 * @{
224 */
225/** @addtogroup bslma
226 * @{
227 */
228/** @addtogroup bslma_sharedptroutofplacerep
229 * @{
230 */
231
232#include <bslscm_version.h>
233
234#include <bslma_allocator.h>
235#include <bslma_default.h>
236#include <bslma_sharedptrrep.h>
238
239#include <bslmf_allocatorargt.h>
240#include <bslmf_conditional.h>
243#include <bslmf_isconvertible.h>
244#include <bslmf_isfunction.h>
245#include <bslmf_ispointer.h>
246#include <bslmf_issame.h>
248
249#include <bsls_keyword.h>
250#include <bsls_util.h>
251
252#include <typeinfo>
253
254
255namespace bslma {
256
257template <class TYPE, class DELETER>
258struct SharedPtrOutofplaceRep_InitProctor;
259struct SharedPtrOutofplaceRep_DeleterHelper;
260struct SharedPtrOutofplaceRep_DeleterType;
261template <class DELETER>
262class SharedPtrOutofplaceRep_DeleterDiscriminator;
263
264 // =========================================
265 // struct SharedPtrOutofplaceRep_DeleterType
266 // =========================================
267
268/// This `struct` enumerates four kinds of deleters, the first two are
269/// factory deleters, and the last two are function-like deleters.
271
272 enum {
273 // Enumeration used to discriminate among the different deleters.
274
275 BSLMA_ALLOCATOR_PTR = 0, // Used to indicate that a deleter is a
276 // pointer that follows the 'Allocator'
277 // protocol.
278
279 BSLMA_FACTORY_PTR = 1, // Used to indicate that a deleter is a
280 // pointer to a factory object that
281 // implements the 'deleteObject' protocol.
282
283 BSLMA_FUNCTOR_WITH_ALLOC = 2,// Used to indicate that a deleter is a
284 // functor that takes an allocator at
285 // construction.
286
288 // Used to indicate that a deleter is a
289 // functor that takes an allocator at
290 // construction using the
291 // 'bsl::allocator_arg' idiom.
292
294 // Used to indicate that a deleter is a
295 // functor that does not take an allocator
296 // at construction.
297 };
298};
299
300 // ============================
301 // class SharedPtrOutofplaceRep
302 // ============================
303
304/// This class provides a concrete implementation of the `SharedPtrRep`
305/// protocol for out-of-place instances of the parameterized `TYPE`. Upon
306/// destruction of this object, the parameterized `DELETER` type is invoked
307/// on the pointer to the shared object.
308///
309/// See @ref bslma_sharedptroutofplacerep
310template <class TYPE, class DELETER>
312
313 // PRIVATE TYPES
314
315 /// `DeleterType` is an alias for the `struct` that defines the types of
316 /// deleter used to destroy the shared object.
318
319 /// `Deleter` is an alias for the type of deleter used to destroy the
320 /// shared object.
321 typedef typename
323
324 // DATA
325
326 // deleter for this out-of-place instance
327 Deleter d_deleter;
328
329 // pointer to out-of-place instance (held, not owned)
330 TYPE *d_ptr_p;
331
332 // memory allocator (held, not owned)
333 Allocator *d_allocator_p;
334
335 private:
336 // NOT IMPLEMENTED
339
340 // PRIVATE CREATORS
341
343 TYPE *ptr,
344 const DELETER& deleter,
345 Allocator *basicAllocator,
348 TYPE *ptr,
349 const DELETER& deleter,
350 Allocator *basicAllocator,
353 TYPE *ptr,
354 const DELETER& deleter,
355 Allocator *basicAllocator,
358 TYPE *ptr,
359 const DELETER& deleter,
360 Allocator *basicAllocator,
363 /// Create a `SharedPtrOutofplaceRep` that manages the lifetime of the
364 /// specified `ptr`, using the specified `deleter` to destroy `ptr`, and
365 /// using the specified `basicAllocator` to supply memory. Note that
366 /// `basicAllocator` will be used to destroy this representation object,
367 /// but not necessarily to destroy `ptr`. Also note that
368 /// `SharedPtrOutofplaceRep` should be created using
369 /// `makeOutofplaceRep`, which will call the appropriate private
370 /// constructor depending on the parameterized `DELETER` type.
372 TYPE *ptr,
373 const DELETER& deleter,
374 Allocator *basicAllocator,
376
377 /// Destroy this representation object and if the shared object has not
378 /// been deleted, delete the shared object using the associated deleter.
379 /// Note that this destructor is never called explicitly. Instead,
380 /// `disposeObject` destroys the shared object object and `disposeRep`
381 /// deallocates this representation object.
383
384 public:
385 // CLASS METHODS
386
387 /// Return the address of a newly created `SharedPtrOutofplaceRep`
388 /// object that manages the lifetime of the specified `ptr`, using the
389 /// specified `deleter` to destroy `ptr`. Optionally, specify a
390 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
391 /// the currently installed default allocator is used. Note that the
392 /// parameterized `DELETER` type will be used to deallocate the memory
393 /// pointed to by `ptr`.
395 TYPE *ptr,
396 const DELETER& deleter,
397 Allocator *basicAllocator = 0);
398
399 // MANIPULATORS
400
401 /// Destroy the object being referred to by this representation. This
402 /// method is automatically invoked by `releaseRef` when the number of
403 /// shared references reaches zero and should not be explicitly invoked
404 /// otherwise.
406
407 /// Destroy this representation object and deallocate the associated
408 /// memory. This method is automatically invoked by `releaseRef` and
409 /// `releaseWeakRef` when the number of weak references and the number
410 /// of shared references both reach zero and should not be explicitly
411 /// invoked otherwise. The behavior is undefined unless `disposeObject`
412 /// has already been called for this representation. Note that this
413 /// `disposeRep` method effectively serves as the representation
414 /// object's destructor.
416
417 /// Return a pointer to the deleter stored by the derived representation
418 /// (if any) if the deleter has the same type as that described by the
419 /// specified `type`, and a null pointer otherwise.
420 void *getDeleter(const std::type_info& type) BSLS_KEYWORD_OVERRIDE;
421
422 // ACCESSORS
423
424 /// Return the (untyped) address of the modifiable shared object to
425 /// which this object refers.
427
428 /// Return the address of the modifiable shared object to which this
429 /// object refers.
430 TYPE *ptr() const;
431};
432
433 // =================================================
434 // class SharedPtrOutofplaceRep_DeleterDiscriminator
435 // =================================================
436
437/// This `class` provides the implementation of the
438/// `SharedPtrOutofplaceRep_DeleterDiscriminator` for the `DELETER` template
439/// parameter type, which is not `Allocator *`.
440///
441/// See @ref bslma_sharedptroutofplacerep
442template <class DELETER, bool IS_ALLOC_PTR>
444
445 // PRIVATE TYPES
446 enum {
447 // Enumeration that calls meta-functions to describe properties of the
448 // deleter.
449
450 BSLMA_USES_ALLOC = UsesBslmaAllocator<DELETER>::value,
451
452 BSLMA_USES_ALLOC_ARG_T = bslmf::UsesAllocatorArgT<DELETER>::value,
453
454 BSLMA_IS_OBJ_PTR = bsl::is_pointer<DELETER>::value
456 };
457
458 /// `DeleterType` is an alias for the `struct` that defines the types of
459 /// deleter used to destroy the shared object.
461
462 public:
463 // TYPES
464 enum {
465 // This enumeration contains the return value of the meta-function.
466 VALUE = BSLMA_USES_ALLOC
467 ? BSLMA_USES_ALLOC_ARG_T
470 : !BSLMA_IS_OBJ_PTR
473 };
474
475 /// `Type` represents the type of the deleter used to destroy the shared
476 /// object.
478 DELETER *,
479 DELETER>::type Type;
480};
481
482/// This `class` provides the implementation of the
483/// `SharedPtrOutofplaceRep_DeleterDiscriminator` for the `DELETER` template
484/// parameter type, which is `Allocator *`.
485template <class DELETER>
487
488 // PRIVATE TYPES
489
490 /// `DeleterType` is an alias for the `struct` that defines the types of
491 /// deleter used to destroy the shared object.
493
494 public:
495 // TYPES
496 enum {
497 // This enumeration contains the return value of the meta-function.
499 };
500
501 /// `Type` represents the type of the deleter used to destroy the shared
502 /// object.
503 typedef Allocator *Type;
504};
505
506/// This `class` provides two meta-functions for determining the enumerated
507/// type and the C++ type of a deleter based on whether it is a pointer to a
508/// function, a pointer to a factory deleter, or an instance of a
509/// function-like deleter.
510///
511/// See @ref bslma_sharedptroutofplacerep
512template <class DELETER>
514
515 // PRIVATE TYPES
517 DELETER,
519 ImpType;
520
521 public:
522 // TYPES
523 enum {
524 // This enumeration contains the return value of the meta-function.
526 };
527
528 /// `Type` represents the type of the deleter used to destroy the shared
529 /// object.
530 typedef typename ImpType::Type Type;
531};
532
533 // ===========================================
534 // struct SharedPtrOutofplaceRep_DeleterHelper
535 // ===========================================
536
537/// This `struct` provides utility functions to apply a deleter to a shared
538/// object referred to by `SharedPtrOutofplaceRep`.
540
541 // PUBLIC TYPES
542
543 /// `DeleterType` is an alias for the `struct` that defines the types of
544 /// deleter used to destroy the shared object.
546
547 private:
548 // PRIVATE CLASS METHODS
549
550 /// Delete the specified `ptr` using the specified `deleter` that
551 /// implements the `Allocator` protocol, which provides a `deleteObject`
552 /// function that can be invoked to delete `ptr`.
553 template <class TYPE, class DELETER>
554 static void deleteObject(
555 TYPE *ptr,
556 DELETER& deleter,
558
559 /// Delete the specified `ptr` using the specified `deleter` that
560 /// provides a `deleteObject` function that can be invoked to delete
561 /// `ptr`.
562 template <class TYPE, class DELETER>
563 static void deleteObject(
564 TYPE *ptr,
565 DELETER& deleter,
567
568 /// Delete the specified `ptr` using the specified `deleter` that is a
569 /// functor that takes an allocator at construction and can be invoked
570 /// to delete `ptr`.
571 template <class TYPE, class DELETER>
572 static void deleteObject(
573 TYPE *ptr,
574 DELETER& deleter,
576
577 /// Delete the specified `ptr` using the specified `deleter` that is a
578 /// functor that takes an allocator at construction using the
579 /// `bsl::allocator_arg` idiom and can be invoked to delete `ptr`.
580 template <class TYPE, class DELETER>
581 static void deleteObject(
582 TYPE *ptr,
583 DELETER& deleter,
586
587 /// Delete the specified `ptr` using the specified `deleter` that is a
588 /// functor that does not take an allocator at construction and can be
589 /// invoked to delete `ptr`.
590 template <class TYPE, class DELETER>
591 static void deleteObject(
592 TYPE *ptr,
593 DELETER& deleter,
595
596 public:
597 // CLASS METHODS
598
599 /// Delete the specified `ptr` using the specified `deleter`.
600 template <class TYPE, class DELETER>
601 static void deleteObject(TYPE *ptr, DELETER& deleter);
602};
603
604 // =========================================
605 // struct SharedPtrOutofplaceRep_InitProctor
606 // =========================================
607
608/// This proctor is used for out-of-place shared pointer instantiations.
609/// Generally, a proctor is created prior to constructing a
610/// `SharedPtrOutofplaceRep` and released after successful construction. In
611/// the event that an exception is thrown during construction of the
612/// representation, the proctor will delete the provided pointer using the
613/// provided deleter. Note that the provided deleter is held by reference
614/// and must remain valid for the lifetime of the proctor. If the proctor
615/// is not released before it's destruction, a copy of the deleter is
616/// instantiated to delete the pointer (in case `operator()` is
617/// non-`const`). Also note that if the deleter throws during copy
618/// construction, the provided pointer will not be destroyed.
619template <class TYPE, class DELETER>
621
622 // DATA
623 TYPE *d_ptr_p; // address of the managed object (held, not
624 // owned)
625
626 const DELETER& d_deleter; // deleter used to destroy managed object
627
628 public:
629 // CREATORS
630
631 /// Create a proctor referring to the specified `ptr` and using the
632 /// specified `deleter` to destroy `ptr` when the proctor is destroyed.
633 SharedPtrOutofplaceRep_InitProctor(TYPE *ptr, const DELETER& deleter);
634
635 /// Destroy this proctor and the object (if any) referred to by this
636 /// proctor.
638
639 // MANIPULATORS
640
641 /// Release from management the object referred to by this proctor.
642 void release();
643};
644
645// ============================================================================
646// INLINE DEFINITIONS
647// ============================================================================
648
649 // ----------------------------
650 // class SharedPtrOutofplaceRep
651 // ----------------------------
652
653// CLASS FUNCTIONS
654template <class TYPE, class DELETER>
657 TYPE *ptr,
658 const DELETER& deleter,
659 Allocator *basicAllocator)
660{
662
663 enum { BSLMA_DELETER_TYPE =
665
667
668 basicAllocator = Default::allocator(basicAllocator);
669 rep = new (*basicAllocator) SharedPtrOutofplaceRep(
670 ptr,
671 deleter,
672 basicAllocator,
674
675 proctor.release();
676
677 return rep;
678}
679
680// CREATORS
681template <class TYPE, class DELETER>
683 TYPE *ptr,
684 const DELETER& deleter,
685 Allocator *basicAllocator,
687: d_deleter(Default::allocator(deleter))
688, d_ptr_p(ptr)
689, d_allocator_p(basicAllocator)
690{
691}
692
693template <class TYPE, class DELETER>
694SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
695 TYPE *ptr,
696 const DELETER& deleter,
697 Allocator *basicAllocator,
699: d_deleter(deleter)
700, d_ptr_p(ptr)
701, d_allocator_p(basicAllocator)
702{
703}
704
705template <class TYPE, class DELETER>
706SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
707 TYPE *ptr,
708 const DELETER& deleter,
709 Allocator *basicAllocator,
711: d_deleter(deleter, basicAllocator)
712, d_ptr_p(ptr)
713, d_allocator_p(basicAllocator)
714{
715}
716
717template <class TYPE, class DELETER>
718SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
719 TYPE *ptr,
720 const DELETER& deleter,
721 Allocator *basicAllocator,
723: d_deleter(bsl::allocator_arg, basicAllocator, deleter)
724, d_ptr_p(ptr)
725, d_allocator_p(basicAllocator)
726{
727}
728
729template <class TYPE, class DELETER>
730SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
731 TYPE *ptr,
732 const DELETER& deleter,
733 Allocator *basicAllocator,
735: d_deleter(deleter)
736, d_ptr_p(ptr)
737, d_allocator_p(basicAllocator)
738{
739}
740
741template <class TYPE, class DELETER>
742SharedPtrOutofplaceRep<TYPE, DELETER>::~SharedPtrOutofplaceRep()
743{
744}
745
746// MANIPULATORS
747template <class TYPE, class DELETER>
749{
750 SharedPtrOutofplaceRep_DeleterHelper::deleteObject(d_ptr_p, d_deleter);
751 d_ptr_p = 0;
752}
753
754template <class TYPE, class DELETER>
755inline
757{
758 // If 'd_allocator_p->deleteObject' is used to destroy the
759 // 'SharedPtrOutofplaceRep' object, a virtual function call will be used
760 // and a @ref dynamic_cast is required to obtain the address of the most
761 // derived object to deallocate it. Knowing 'SharedPtrOutofplaceRep' is
762 // the most derived class, this unnecessary overhead of a virtual function
763 // call can be avoided by explicitly calling the destructor. This behavior
764 // is guaranteed by the standard ([class.virtual] 13: "Explicit
765 // qualification with the scope operator (5.1) suppresses the virtual call
766 // mechanism.", page 224 of Working Draft 2007-10).
767
768 Allocator *alloc = d_allocator_p;
770 alloc->deallocate(this);
771}
772
773template <class TYPE, class DELETER>
774inline
775void *
777{
778 return (typeid(d_deleter) == type)
779 ? bsls::Util::addressOf(d_deleter)
780 : 0;
781}
782
783// ACCESSORS
784template <class TYPE, class DELETER>
785inline
787{
788 return const_cast<void *>(static_cast<const void *>(d_ptr_p));
789}
790
791template <class TYPE, class DELETER>
792inline
794{
795 return d_ptr_p;
796}
797
798 // -------------------------------------------
799 // struct SharedPtrOutofplaceRep_DeleterHelper
800 // -------------------------------------------
801
802// CLASS METHODS
803template <class TYPE, class DELETER>
804inline
805void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
806 TYPE *ptr,
807 DELETER& deleter,
809{
810 deleter->deleteObject(ptr);
811}
812
813template <class TYPE, class DELETER>
814inline
815void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
816 TYPE *ptr,
817 DELETER& deleter,
819{
820 deleter->deleteObject(ptr);
821}
822
823template <class TYPE, class DELETER>
824inline
825void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
826 TYPE *ptr,
827 DELETER& deleter,
829{
830 deleter(ptr);
831}
832
833template <class TYPE, class DELETER>
834inline
835void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
836 TYPE *ptr,
837 DELETER& deleter,
839{
840 deleter(ptr);
841}
842
843template <class TYPE, class DELETER>
844inline
845void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
846 TYPE *ptr,
847 DELETER& deleter,
849{
850 deleter(ptr);
851}
852
853template <class TYPE, class DELETER>
854inline
855void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(TYPE *ptr,
856 DELETER& deleter)
857{
858 enum { BSLMA_DELETER_TYPE =
860
861 SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
862 ptr,
863 deleter,
865}
866
867 // ---------------------------------------
868 // struct SharedPtrOutofplaceRep_InitProctor
869 // ---------------------------------------
870
871// CREATORS
872template <class TYPE, class DELETER>
873inline
875SharedPtrOutofplaceRep_InitProctor(TYPE *ptr, const DELETER& deleter)
876: d_ptr_p(ptr)
877, d_deleter(deleter)
878{
879}
880
881template <class TYPE, class DELETER>
882inline
885{
886 // The definition of this function is intentionally *not* written as:
887 //..
888 // if (d_ptr_p) {
889 // DELETER tempDeleter(d_deleter);
890 // SharedPtrOutofplaceRep_DeleterHelper::deleteObject(d_ptr_p,
891 // tempDeleter);
892 // }
893 //..
894 // to work around a CC (Studio 12v4 on Solaris) compilation failure when
895 // optimizations are enabled ('opt_exc_mt' and 'opt_exc_mt_64').
896
897 if (!d_ptr_p) {
898 return; // RETURN
899 }
900
902 DELETER *,
903 DELETER>::type tempDeleter(d_deleter);
904 SharedPtrOutofplaceRep_DeleterHelper::deleteObject(d_ptr_p, tempDeleter);
905}
906
907// MANIPULATORS
908template <class TYPE, class DELETER>
909inline
914
915// ============================================================================
916// TYPE TRAITS
917// ============================================================================
918
919template <class TYPE, class DELETER>
924
925} // close package namespace
926
927
928#endif
929
930// ----------------------------------------------------------------------------
931// Copyright 2013 Bloomberg Finance L.P.
932//
933// Licensed under the Apache License, Version 2.0 (the "License");
934// you may not use this file except in compliance with the License.
935// You may obtain a copy of the License at
936//
937// http://www.apache.org/licenses/LICENSE-2.0
938//
939// Unless required by applicable law or agreed to in writing, software
940// distributed under the License is distributed on an "AS IS" BASIS,
941// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
942// See the License for the specific language governing permissions and
943// limitations under the License.
944// ----------------------------- END-OF-FILE ----------------------------------
945
946/** @} */
947/** @} */
948/** @} */
Definition bslma_allocator.h:457
virtual void deallocate(void *address)=0
Allocator * Type
Definition bslma_sharedptroutofplacerep.h:503
Definition bslma_sharedptroutofplacerep.h:443
bsl::conditional< bsl::is_function< DELETER >::value, DELETER *, DELETER >::type Type
Definition bslma_sharedptroutofplacerep.h:479
@ VALUE
Definition bslma_sharedptroutofplacerep.h:466
Definition bslma_sharedptroutofplacerep.h:513
@ VALUE
Definition bslma_sharedptroutofplacerep.h:525
ImpType::Type Type
Definition bslma_sharedptroutofplacerep.h:530
Definition bslma_sharedptroutofplacerep.h:311
void disposeObject() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:748
void disposeRep() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:756
static SharedPtrOutofplaceRep< TYPE, DELETER > * makeOutofplaceRep(TYPE *ptr, const DELETER &deleter, Allocator *basicAllocator=0)
Definition bslma_sharedptroutofplacerep.h:656
void * originalPtr() const BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:786
void * getDeleter(const std::type_info &type) BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:776
TYPE * ptr() const
Definition bslma_sharedptroutofplacerep.h:793
Definition bslma_sharedptrrep.h:338
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
Definition bslmf_conditional.h:120
Definition bslmf_integralconstant.h:244
Definition bslmf_isconvertible.h:867
Definition bslmf_ispointer.h:138
Definition bslma_default.h:740
static Allocator * allocator(Allocator *basicAllocator=0)
Definition bslma_default.h:897
Definition bslma_sharedptroutofplacerep.h:539
SharedPtrOutofplaceRep_DeleterType DeleterType
Definition bslma_sharedptroutofplacerep.h:545
Definition bslma_sharedptroutofplacerep.h:270
@ BSLMA_FUNCTOR_WITH_ALLOC_ARG_T
Definition bslma_sharedptroutofplacerep.h:287
@ BSLMA_FUNCTOR_WITHOUT_ALLOC
Definition bslma_sharedptroutofplacerep.h:293
@ BSLMA_ALLOCATOR_PTR
Definition bslma_sharedptroutofplacerep.h:275
@ BSLMA_FACTORY_PTR
Definition bslma_sharedptroutofplacerep.h:279
@ BSLMA_FUNCTOR_WITH_ALLOC
Definition bslma_sharedptroutofplacerep.h:283
Definition bslma_sharedptroutofplacerep.h:620
void release()
Release from management the object referred to by this proctor.
Definition bslma_sharedptroutofplacerep.h:910
SharedPtrOutofplaceRep_InitProctor(TYPE *ptr, const DELETER &deleter)
Definition bslma_sharedptroutofplacerep.h:875
const DELETER & d_deleter
Definition bslma_sharedptroutofplacerep.h:626
TYPE * d_ptr_p
Definition bslma_sharedptroutofplacerep.h:623
~SharedPtrOutofplaceRep_InitProctor()
Definition bslma_sharedptroutofplacerep.h:884
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_functionpointertraits.h:153
Definition bslmf_usesallocatorargt.h:100
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305