BDE 4.39.x 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_pointerutil.h>
237#include <bslma_sharedptrrep.h>
239
240#include <bslmf_allocatorargt.h>
241#include <bslmf_conditional.h>
244#include <bslmf_isconvertible.h>
245#include <bslmf_isfunction.h>
246#include <bslmf_ispointer.h>
247#include <bslmf_issame.h>
249
250#include <bsls_keyword.h>
251#include <bsls_util.h>
252
253#include <typeinfo>
254
255
256namespace bslma {
257
258template <class TYPE, class DELETER>
259struct SharedPtrOutofplaceRep_InitProctor;
260struct SharedPtrOutofplaceRep_DeleterHelper;
261struct SharedPtrOutofplaceRep_DeleterType;
262template <class DELETER>
263class SharedPtrOutofplaceRep_DeleterDiscriminator;
264
265 // =========================================
266 // struct SharedPtrOutofplaceRep_DeleterType
267 // =========================================
268
269/// This `struct` enumerates four kinds of deleters, the first two are
270/// factory deleters, and the last two are function-like deleters.
271///
272/// See @ref bslma_sharedptroutofplacerep
274
275 enum {
276 // Enumeration used to discriminate among the different deleters.
277
278 BSLMA_ALLOCATOR_PTR = 0, // Used to indicate that a deleter is a
279 // pointer that follows the 'Allocator'
280 // protocol.
281
282 BSLMA_FACTORY_PTR = 1, // Used to indicate that a deleter is a
283 // pointer to a factory object that
284 // implements the 'deleteObject' protocol.
285
286 BSLMA_FUNCTOR_WITH_ALLOC = 2,// Used to indicate that a deleter is a
287 // functor that takes an allocator at
288 // construction.
289
291 // Used to indicate that a deleter is a
292 // functor that takes an allocator at
293 // construction using the
294 // 'bsl::allocator_arg' idiom.
295
297 // Used to indicate that a deleter is a
298 // functor that does not take an allocator
299 // at construction.
300 };
301};
302
303 // ============================
304 // class SharedPtrOutofplaceRep
305 // ============================
306
307/// This class provides a concrete implementation of the `SharedPtrRep`
308/// protocol for out-of-place instances of the parameterized `TYPE`. Upon
309/// destruction of this object, the parameterized `DELETER` type is invoked
310/// on the pointer to the shared object.
311///
312/// See @ref bslma_sharedptroutofplacerep
313template <class TYPE, class DELETER>
315
316 // PRIVATE TYPES
317
318 /// `DeleterType` is an alias for the `struct` that defines the types of
319 /// deleter used to destroy the shared object.
321
322 /// `Deleter` is an alias for the type of deleter used to destroy the
323 /// shared object.
324 typedef typename
326
327 // DATA
328
329 // deleter for this out-of-place instance
330 Deleter d_deleter;
331
332 // pointer to out-of-place instance (held, not owned)
333 TYPE *d_ptr_p;
334
335 // memory allocator (held, not owned)
336 Allocator *d_allocator_p;
337
338 private:
339 // NOT IMPLEMENTED
342
343 // PRIVATE CREATORS
344
345 /// Create a `SharedPtrOutofplaceRep` that manages the lifetime of the
346 /// specified `ptr`, using the specified `deleter` to destroy `ptr`, and
347 /// using the specified `basicAllocator` to supply memory.
348 ///
349 /// \note Note that `basicAllocator` will be used to destroy this representation object,
350 /// but not necessarily to destroy `ptr`. Also note that
351 /// `SharedPtrOutofplaceRep` should be created using
352 /// `makeOutofplaceRep`, which will call the appropriate private
353 /// constructor depending on the parameterized `DELETER` type.
355 TYPE *ptr,
356 const DELETER& deleter,
357 Allocator *basicAllocator,
360 TYPE *ptr,
361 const DELETER& deleter,
362 Allocator *basicAllocator,
365 TYPE *ptr,
366 const DELETER& deleter,
367 Allocator *basicAllocator,
370 TYPE *ptr,
371 const DELETER& deleter,
372 Allocator *basicAllocator,
376 TYPE *ptr,
377 const DELETER& deleter,
378 Allocator *basicAllocator,
380
381 /// Destroy this representation object and if the shared object has not
382 /// been deleted, delete the shared object using the associated deleter.
383 ///
384 /// \note Note that this destructor is never called explicitly. Instead,
385 /// `disposeObject` destroys the shared object object and `disposeRep`
386 /// deallocates this representation object.
388
389 public:
390 // CLASS METHODS
391
392 /// Return the address of a newly created `SharedPtrOutofplaceRep`
393 /// object that manages the lifetime of the specified `ptr`, using the
394 /// specified `deleter` to destroy `ptr`. Optionally, specify a
395 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
396 ///
397 /// \note Note that the
398 /// parameterized `DELETER` type will be used to deallocate the memory
399 /// pointed to by `ptr`.
401 TYPE *ptr,
402 const DELETER& deleter,
403 Allocator *basicAllocator = 0);
404
405 // MANIPULATORS
406
407 /// Destroy the object being referred to by this representation. This
408 /// method is automatically invoked by `releaseRef` when the number of
409 /// shared references reaches zero and should not be explicitly invoked
410 /// otherwise.
412
413 /// Destroy this representation object and deallocate the associated
414 /// memory. This method is automatically invoked by `releaseRef` and
415 /// `releaseWeakRef` when the number of weak references and the number
416 /// of shared references both reach zero and should not be explicitly invoked otherwise.
417 ///
418 /// \pre The behavior is undefined unless `disposeObject` has already been called for this representation.
419 ///
420 /// \note Note that this
421 /// `disposeRep` method effectively serves as the representation
422 /// object's destructor.
424
425 /// Return a pointer to the deleter stored by the derived representation
426 /// (if any) if the deleter has the same type as that described by the
427 /// specified `type`, and a null pointer otherwise.
428 void *getDeleter(const std::type_info& type) BSLS_KEYWORD_OVERRIDE;
429
430 // ACCESSORS
431
432 /// Return the (untyped) address of the modifiable shared object to
433 /// which this object refers.
435
436 /// Return the address of the modifiable shared object to which this
437 /// object refers.
438 TYPE *ptr() const;
439};
440
441 // =================================================
442 // class SharedPtrOutofplaceRep_DeleterDiscriminator
443 // =================================================
444
445/// This `class` provides the implementation of the
446/// `SharedPtrOutofplaceRep_DeleterDiscriminator` for the `DELETER` template
447/// parameter type, which is not `Allocator *`.
448///
449/// See @ref bslma_sharedptroutofplacerep
450template <class DELETER, bool IS_ALLOC_PTR>
452
453 // PRIVATE TYPES
454 enum {
455 // Enumeration that calls meta-functions to describe properties of the
456 // deleter.
457
458 BSLMA_USES_ALLOC = UsesBslmaAllocator<DELETER>::value,
459
460 BSLMA_USES_ALLOC_ARG_T = bslmf::UsesAllocatorArgT<DELETER>::value,
461
462 BSLMA_IS_OBJ_PTR = bsl::is_pointer<DELETER>::value
464 };
465
466 /// `DeleterType` is an alias for the `struct` that defines the types of
467 /// deleter used to destroy the shared object.
469
470 public:
471 // TYPES
472 enum {
473 // This enumeration contains the return value of the meta-function.
474 VALUE = BSLMA_USES_ALLOC
475 ? BSLMA_USES_ALLOC_ARG_T
478 : !BSLMA_IS_OBJ_PTR
481 };
482
483 /// `Type` represents the type of the deleter used to destroy the shared
484 /// object.
486 DELETER *,
487 DELETER>::type Type;
488};
489
490/// This `class` provides the implementation of the
491/// `SharedPtrOutofplaceRep_DeleterDiscriminator` for the `DELETER` template
492/// parameter type, which is `Allocator *`.
493template <class DELETER>
495
496 // PRIVATE TYPES
497
498 /// `DeleterType` is an alias for the `struct` that defines the types of
499 /// deleter used to destroy the shared object.
501
502 public:
503 // TYPES
504 enum {
505 // This enumeration contains the return value of the meta-function.
507 };
508
509 /// `Type` represents the type of the deleter used to destroy the shared
510 /// object.
511 typedef Allocator *Type;
512};
513
514/// This `class` provides two meta-functions for determining the enumerated
515/// type and the C++ type of a deleter based on whether it is a pointer to a
516/// function, a pointer to a factory deleter, or an instance of a
517/// function-like deleter.
518///
519/// See @ref bslma_sharedptroutofplacerep
520template <class DELETER>
522
523 // PRIVATE TYPES
525 DELETER,
527 ImpType;
528
529 public:
530 // TYPES
531 enum {
532 // This enumeration contains the return value of the meta-function.
533 VALUE = ImpType::VALUE
534 };
535
536 /// `Type` represents the type of the deleter used to destroy the shared
537 /// object.
538 typedef typename ImpType::Type Type;
539};
540
541 // ===========================================
542 // struct SharedPtrOutofplaceRep_DeleterHelper
543 // ===========================================
544
545/// This `struct` provides utility functions to apply a deleter to a shared
546/// object referred to by `SharedPtrOutofplaceRep`.
547///
548/// See @ref bslma_sharedptroutofplacerep
550
551 // PUBLIC TYPES
552
553 /// `DeleterType` is an alias for the `struct` that defines the types of
554 /// deleter used to destroy the shared object.
556
557 private:
558 // PRIVATE CLASS METHODS
559
560 /// Delete the specified `ptr` using the specified `deleter` that
561 /// implements the `Allocator` protocol, which provides a `deleteObject`
562 /// function that can be invoked to delete `ptr`.
563 template <class TYPE, class DELETER>
564 static void deleteObject(
565 TYPE *ptr,
566 DELETER& deleter,
568
569 /// Delete the specified `ptr` using the specified `deleter` that
570 /// provides a `deleteObject` function that can be invoked to delete
571 /// `ptr`.
572 template <class TYPE, class DELETER>
573 static void deleteObject(
574 TYPE *ptr,
575 DELETER& deleter,
577
578 /// Delete the specified `ptr` using the specified `deleter` that is a
579 /// functor that takes an allocator at construction and can be invoked
580 /// to delete `ptr`.
581 template <class TYPE, class DELETER>
582 static void deleteObject(
583 TYPE *ptr,
584 DELETER& deleter,
586
587 /// Delete the specified `ptr` using the specified `deleter` that is a
588 /// functor that takes an allocator at construction using the
589 /// `bsl::allocator_arg` idiom and can be invoked to delete `ptr`.
590 template <class TYPE, class DELETER>
591 static void deleteObject(
592 TYPE *ptr,
593 DELETER& deleter,
596
597 /// Delete the specified `ptr` using the specified `deleter` that is a
598 /// functor that does not take an allocator at construction and can be
599 /// invoked to delete `ptr`.
600 template <class TYPE, class DELETER>
601 static void deleteObject(
602 TYPE *ptr,
603 DELETER& deleter,
605
606 public:
607 // CLASS METHODS
608
609 /// Delete the specified `ptr` using the specified `deleter`.
610 template <class TYPE, class DELETER>
611 static void deleteObject(TYPE *ptr, DELETER& deleter);
612};
613
614 // =========================================
615 // struct SharedPtrOutofplaceRep_InitProctor
616 // =========================================
617
618/// This proctor is used for out-of-place shared pointer instantiations.
619/// Generally, a proctor is created prior to constructing a
620/// `SharedPtrOutofplaceRep` and released after successful construction. In
621/// the event that an exception is thrown during construction of the
622/// representation, the proctor will delete the provided pointer using the provided deleter.
623///
624/// \note Note that the provided deleter is held by reference
625/// and must remain valid for the lifetime of the proctor. If the proctor
626/// is not released before it's destruction, a copy of the deleter is
627/// instantiated to delete the pointer (in case `operator()` is
628/// non-`const`). Also note that if the deleter throws during copy
629/// construction, the provided pointer will not be destroyed.
630///
631/// See @ref bslma_sharedptroutofplacerep
632template <class TYPE, class DELETER>
634
635 // DATA
636 TYPE *d_ptr_p; // address of the managed object (held, not
637 // owned)
638
639 const DELETER& d_deleter; // deleter used to destroy managed object
640
641 public:
642 // CREATORS
643
644 /// Create a proctor referring to the specified `ptr` and using the
645 /// specified `deleter` to destroy `ptr` when the proctor is destroyed.
646 SharedPtrOutofplaceRep_InitProctor(TYPE *ptr, const DELETER& deleter);
647
648 /// Destroy this proctor and the object (if any) referred to by this
649 /// proctor.
651
652 // MANIPULATORS
653
654 /// Release from management the object referred to by this proctor.
655 void release();
656};
657
658// ============================================================================
659// INLINE DEFINITIONS
660// ============================================================================
661
662 // ----------------------------
663 // class SharedPtrOutofplaceRep
664 // ----------------------------
665
666// CLASS FUNCTIONS
667template <class TYPE, class DELETER>
670 TYPE *ptr,
671 const DELETER& deleter,
672 Allocator *basicAllocator)
673{
675
676 enum { BSLMA_DELETER_TYPE =
678
680
681 basicAllocator = Default::allocator(basicAllocator);
682 rep = new (*basicAllocator) SharedPtrOutofplaceRep(
683 ptr,
684 deleter,
685 basicAllocator,
687
688 proctor.release();
689
690 return rep;
691}
692
693// CREATORS
694template <class TYPE, class DELETER>
696 TYPE *ptr,
697 const DELETER& deleter,
698 Allocator *basicAllocator,
700: d_deleter(Default::allocator(deleter))
701, d_ptr_p(ptr)
702, d_allocator_p(basicAllocator)
703{
704}
705
706template <class TYPE, class DELETER>
707SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
708 TYPE *ptr,
709 const DELETER& deleter,
710 Allocator *basicAllocator,
712: d_deleter(deleter)
713, d_ptr_p(ptr)
714, d_allocator_p(basicAllocator)
715{
716}
717
718template <class TYPE, class DELETER>
719SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
720 TYPE *ptr,
721 const DELETER& deleter,
722 Allocator *basicAllocator,
724: d_deleter(deleter, basicAllocator)
725, d_ptr_p(ptr)
726, d_allocator_p(basicAllocator)
727{
728}
729
730template <class TYPE, class DELETER>
731SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
732 TYPE *ptr,
733 const DELETER& deleter,
734 Allocator *basicAllocator,
736: d_deleter(bsl::allocator_arg, basicAllocator, deleter)
737, d_ptr_p(ptr)
738, d_allocator_p(basicAllocator)
739{
740}
741
742template <class TYPE, class DELETER>
743SharedPtrOutofplaceRep<TYPE, DELETER>::SharedPtrOutofplaceRep(
744 TYPE *ptr,
745 const DELETER& deleter,
746 Allocator *basicAllocator,
748: d_deleter(deleter)
749, d_ptr_p(ptr)
750, d_allocator_p(basicAllocator)
751{
752}
753
754template <class TYPE, class DELETER>
755SharedPtrOutofplaceRep<TYPE, DELETER>::~SharedPtrOutofplaceRep()
756{
757}
758
759// MANIPULATORS
760template <class TYPE, class DELETER>
762{
763 SharedPtrOutofplaceRep_DeleterHelper::deleteObject(d_ptr_p, d_deleter);
764 d_ptr_p = 0;
765}
766
767template <class TYPE, class DELETER>
768inline
770{
771 // If 'd_allocator_p->deleteObject' is used to destroy the
772 // 'SharedPtrOutofplaceRep' object, a virtual function call will be used
773 // and a @ref dynamic_cast is required to obtain the address of the most
774 // derived object to deallocate it. Knowing 'SharedPtrOutofplaceRep' is
775 // the most derived class, this unnecessary overhead of a virtual function
776 // call can be avoided by explicitly calling the destructor. This behavior
777 // is guaranteed by the standard ([class.virtual] 13: "Explicit
778 // qualification with the scope operator (5.1) suppresses the virtual call
779 // mechanism.", page 224 of Working Draft 2007-10).
780
781 Allocator *alloc = d_allocator_p;
783 alloc->deallocate(this);
784}
785
786template <class TYPE, class DELETER>
787inline
788void *
790{
791 return (typeid(d_deleter) == type)
792 ? bsls::Util::addressOf(d_deleter)
793 : 0;
794}
795
796// ACCESSORS
797template <class TYPE, class DELETER>
798inline
803
804template <class TYPE, class DELETER>
805inline
807{
808 return d_ptr_p;
809}
810
811 // -------------------------------------------
812 // struct SharedPtrOutofplaceRep_DeleterHelper
813 // -------------------------------------------
814
815// CLASS METHODS
816template <class TYPE, class DELETER>
817inline
818void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
819 TYPE *ptr,
820 DELETER& deleter,
822{
823 deleter->deleteObject(ptr);
824}
825
826template <class TYPE, class DELETER>
827inline
828void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
829 TYPE *ptr,
830 DELETER& deleter,
832{
833 deleter->deleteObject(ptr);
834}
835
836template <class TYPE, class DELETER>
837inline
838void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
839 TYPE *ptr,
840 DELETER& deleter,
842{
843 deleter(ptr);
844}
845
846template <class TYPE, class DELETER>
847inline
848void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
849 TYPE *ptr,
850 DELETER& deleter,
852{
853 deleter(ptr);
854}
855
856template <class TYPE, class DELETER>
857inline
858void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
859 TYPE *ptr,
860 DELETER& deleter,
862{
863 deleter(ptr);
864}
865
866template <class TYPE, class DELETER>
867inline
868void SharedPtrOutofplaceRep_DeleterHelper::deleteObject(TYPE *ptr,
869 DELETER& deleter)
870{
871 enum { BSLMA_DELETER_TYPE =
873
874 SharedPtrOutofplaceRep_DeleterHelper::deleteObject(
875 ptr,
876 deleter,
878}
879
880 // ---------------------------------------
881 // struct SharedPtrOutofplaceRep_InitProctor
882 // ---------------------------------------
883
884// CREATORS
885template <class TYPE, class DELETER>
886inline
888SharedPtrOutofplaceRep_InitProctor(TYPE *ptr, const DELETER& deleter)
889: d_ptr_p(ptr)
890, d_deleter(deleter)
891{
892}
893
894template <class TYPE, class DELETER>
895inline
898{
899 // The definition of this function is intentionally *not* written as:
900 //..
901 // if (d_ptr_p) {
902 // DELETER tempDeleter(d_deleter);
903 // SharedPtrOutofplaceRep_DeleterHelper::deleteObject(d_ptr_p,
904 // tempDeleter);
905 // }
906 //..
907 // to work around a CC (Studio 12v4 on Solaris) compilation failure when
908 // optimizations are enabled (@ref opt_exc_mt and @ref opt_exc_mt_64 ).
909
910 if (!d_ptr_p) {
911 return; // RETURN
912 }
913
915 DELETER *,
916 DELETER>::type tempDeleter(d_deleter);
917 SharedPtrOutofplaceRep_DeleterHelper::deleteObject(d_ptr_p, tempDeleter);
918}
919
920// MANIPULATORS
921template <class TYPE, class DELETER>
922inline
927
928// ============================================================================
929// TYPE TRAITS
930// ============================================================================
931
932template <class TYPE, class DELETER>
937
938} // close package namespace
939
940
941#endif
942
943// ----------------------------------------------------------------------------
944// Copyright 2013 Bloomberg Finance L.P.
945//
946// Licensed under the Apache License, Version 2.0 (the "License");
947// you may not use this file except in compliance with the License.
948// You may obtain a copy of the License at
949//
950// http://www.apache.org/licenses/LICENSE-2.0
951//
952// Unless required by applicable law or agreed to in writing, software
953// distributed under the License is distributed on an "AS IS" BASIS,
954// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
955// See the License for the specific language governing permissions and
956// limitations under the License.
957// ----------------------------- END-OF-FILE ----------------------------------
958
959/** @} */
960/** @} */
961/** @} */
Definition bslma_allocator.h:545
virtual void deallocate(void *address)=0
Allocator * Type
Definition bslma_sharedptroutofplacerep.h:511
Definition bslma_sharedptroutofplacerep.h:451
bsl::conditional< bsl::is_function< DELETER >::value, DELETER *, DELETER >::type Type
Definition bslma_sharedptroutofplacerep.h:487
@ VALUE
Definition bslma_sharedptroutofplacerep.h:474
Definition bslma_sharedptroutofplacerep.h:521
ImpType::Type Type
Definition bslma_sharedptroutofplacerep.h:538
@ VALUE
Definition bslma_sharedptroutofplacerep.h:533
Definition bslma_sharedptroutofplacerep.h:314
void disposeObject() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:761
void disposeRep() BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:769
static SharedPtrOutofplaceRep< TYPE, DELETER > * makeOutofplaceRep(TYPE *ptr, const DELETER &deleter, Allocator *basicAllocator=0)
Definition bslma_sharedptroutofplacerep.h:669
void * originalPtr() const BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:799
void * getDeleter(const std::type_info &type) BSLS_KEYWORD_OVERRIDE
Definition bslma_sharedptroutofplacerep.h:789
TYPE * ptr() const
Definition bslma_sharedptroutofplacerep.h:806
Definition bslma_sharedptrrep.h:338
#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 bdlat_valuetypefunctions.h:939
Definition baljsn_encoder_testtypes.h:76
Definition bslmf_conditional.h:123
Definition bslmf_integralconstant.h:261
Definition bslmf_isconvertible.h:875
Definition bslmf_ispointer.h:138
Definition bslma_default.h:745
static Allocator * allocator(Allocator *basicAllocator=0)
Definition bslma_default.h:913
static BSLS_KEYWORD_CONSTEXPR void * voidify(TYPE *address) BSLS_KEYWORD_NOEXCEPT
Definition bslma_pointerutil.h:350
Definition bslma_sharedptroutofplacerep.h:549
SharedPtrOutofplaceRep_DeleterType DeleterType
Definition bslma_sharedptroutofplacerep.h:555
Definition bslma_sharedptroutofplacerep.h:273
@ BSLMA_FUNCTOR_WITH_ALLOC_ARG_T
Definition bslma_sharedptroutofplacerep.h:290
@ BSLMA_FUNCTOR_WITHOUT_ALLOC
Definition bslma_sharedptroutofplacerep.h:296
@ BSLMA_ALLOCATOR_PTR
Definition bslma_sharedptroutofplacerep.h:278
@ BSLMA_FACTORY_PTR
Definition bslma_sharedptroutofplacerep.h:282
@ BSLMA_FUNCTOR_WITH_ALLOC
Definition bslma_sharedptroutofplacerep.h:286
Definition bslma_sharedptroutofplacerep.h:633
void release()
Release from management the object referred to by this proctor.
Definition bslma_sharedptroutofplacerep.h:923
SharedPtrOutofplaceRep_InitProctor(TYPE *ptr, const DELETER &deleter)
Definition bslma_sharedptroutofplacerep.h:888
const DELETER & d_deleter
Definition bslma_sharedptroutofplacerep.h:639
TYPE * d_ptr_p
Definition bslma_sharedptroutofplacerep.h:636
~SharedPtrOutofplaceRep_InitProctor()
Definition bslma_sharedptroutofplacerep.h:897
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_functionpointertraits.h:163
Definition bslmf_usesallocatorargt.h:100
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:312