BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_sharedptr.h
Go to the documentation of this file.
1/// @file bslstl_sharedptr.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_sharedptr.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_SHAREDPTR
9#define INCLUDED_BSLSTL_SHAREDPTR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$ $CSID$")
13
14/// @defgroup bslstl_sharedptr bslstl_sharedptr
15/// @brief Provide a generic reference-counted shared pointer wrapper.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_sharedptr
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_sharedptr-purpose"> Purpose</a>
25/// * <a href="#bslstl_sharedptr-classes"> Classes </a>
26/// * <a href="#bslstl_sharedptr-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_sharedptr-description"> Description </a>
28/// * <a href="#bslstl_sharedptr-thread-safety"> Thread Safety </a>
29/// * <a href="#bslstl_sharedptr-shared-and-weak-references"> Shared and Weak References </a>
30/// * <a href="#bslstl_sharedptr-in-placeout-of-place-representations"> In-placeOut-of-place Representations </a>
31/// * <a href="#bslstl_sharedptr-weak-pointers-using-in-place-or-pooled-shared-pointer-representations"> Weak Pointers using "in-place" or Pooled Shared Pointer Representations </a>
32/// * <a href="#bslstl_sharedptr-correct-usage-of-the-allocator-model"> Correct Usage of the Allocator Model </a>
33/// * <a href="#bslstl_sharedptr-deleters"> Deleters </a>
34/// * <a href="#bslstl_sharedptr-aliasing"> Aliasing </a>
35/// * <a href="#bslstl_sharedptr-type-casting"> Type Casting </a>
36/// * <a href="#bslstl_sharedptr-implicit-casting"> Implicit Casting </a>
37/// * <a href="#bslstl_sharedptr-explicit-casting"> Explicit Casting </a>
38/// * <a href="#bslstl_sharedptr-converting-to-and-from-bloomberglp-bslma-managedptr"> Converting to and from BloombergLP::bslma::ManagedPtr </a>
39/// * <a href="#bslstl_sharedptr-weak-pointers-using-in-place-or-pooled-shared-pointer-representations"> Weak Pointers using "in-place" or Pooled Shared Pointer Representations </a>
40/// * <a href="#bslstl_sharedptr-c-standard-compliance"> C++ Standard Compliance </a>
41/// * <a href="#bslstl_sharedptr-usage"> Usage </a>
42/// * <a href="#bslstl_sharedptr-example-1-basic-usage"> Example 1: Basic Usage </a>
43/// * <a href="#bslstl_sharedptr-using-custom-deleters"> Using Custom Deleters </a>
44/// * <a href="#bslstl_sharedptr-example-2-nil-deleters"> Example 2: Nil Deleters </a>
45/// * <a href="#bslstl_sharedptr-example-3-basic-weak-pointer-usage"> Example 3: Basic Weak Pointer Usage </a>
46/// * <a href="#bslstl_sharedptr-example-4-breaking-cyclical-dependencies"> Example 4: Breaking Cyclical Dependencies </a>
47/// * <a href="#bslstl_sharedptr-example-5-caching"> Example 5: Caching </a>
48/// * <a href="#bslstl_sharedptr-example-6-custom-deleters"> Example 6: Custom Deleters </a>
49/// * <a href="#bslstl_sharedptr-implementation-hiding"> Implementation Hiding </a>
50/// * <a href="#bslstl_sharedptr-example-7-hidden-interfaces"> Example 7: Hidden Interfaces </a>
51/// * <a href="#bslstl_sharedptr-example-8-opaque-types"> Example 8: Opaque Types </a>
52///
53/// # Purpose {#bslstl_sharedptr-purpose}
54/// Provide a generic reference-counted shared pointer wrapper.
55///
56/// # Classes {#bslstl_sharedptr-classes}
57///
58/// - bsl::enable_shared_from_this: base class to allow shared ownership of self
59/// - bsl::shared_ptr: shared pointer
60/// - bsl::weak_ptr: "weak" reference to reference-counted shared object
61/// - bslstl::SharedPtrUtil: shared pointer utility functions
62/// - bslstl::SharedPtrNilDeleter: no-op deleter
63///
64/// # Canonical Header {#bslstl_sharedptr-canonical-header}
65/// bsl_memory.h
66///
67/// @see bslma_managedptr, bslma_sharedptrrep
68///
69/// # Description {#bslstl_sharedptr-description}
70/// This component implements a thread-safe, generic,
71/// reference-counted "smart pointer" to support "shared ownership" of objects
72/// of (template parameter) `ELEMENT_TYPE`. Shared pointers implement a form of
73/// the "envelope/letter" idiom. For each shared object, a representation that
74/// manages the number of references to it is created. Many shared pointers can
75/// simultaneously refer to the same shared object by storing a reference to the
76/// same representation. Shared pointers also implement the "construction is
77/// acquisition, destruction is release" idiom. When a shared pointer is
78/// created it increments the number of shared references to the shared object
79/// that was specified to its constructor (or was referred to by a shared
80/// pointer passed to the copy constructor). When a shared pointer is assigned
81/// to or destroyed, then the number of shared references to the shared object
82/// is decremented. When all references to the shared object are released, both
83/// the representation and the object are destroyed. `bsl::shared_ptr` emulates
84/// the interface of a native pointer. The shared object may be accessed
85/// directly using the `->` operator, or the dereference operator (operator `*`)
86/// can be used to obtain a reference to the shared object.
87///
88/// This component also provides a mechanism, `bsl::weak_ptr`, used to create
89/// weak references to reference-counted shared (`bsl::shared_ptr`) objects. A
90/// weak reference provides conditional access to a shared object managed by a
91/// `bsl::shared_ptr`, but, unlike a shared (or "strong") reference, does not
92/// affect the shared object's lifetime. An object having even one shared
93/// reference to it will not be destroyed, but an object having only weak
94/// references would have been destroyed when the last shared reference was
95/// released.
96///
97/// A weak pointer can be constructed from another weak pointer or a
98/// `bsl::shared_ptr`. To access the shared object referenced by a weak pointer
99/// clients must first obtain a shared pointer to that object using the `lock`
100/// method. If the shared object has been destroyed (as indicated by the
101/// `expired` method), then `lock` returns a shared pointer in the default
102/// constructed (empty) state.
103///
104/// This component also provides a mechanism, `bsl::enable_shared_from_this`,
105/// which can be used to create a type that participates in its own ownership
106/// through the reference-counting of a `shared_ptr`.
107///
108/// This component also provides a functor, `bslstl::SharedPtrNilDeleter`, which
109/// may used to create a shared pointer that takes no action when the last
110/// shared reference is destroyed.
111///
112/// This component also provides a utility class, `bslstl::SharedPtrUtil`, which
113/// provides several functions that are frequently used with shared pointers.
114///
115///
116/// ## Thread Safety {#bslstl_sharedptr-thread-safety}
117///
118///
119/// This section qualifies the thread safety of `bsl::shared_ptr` objects and
120/// `bsl::weak_ptr` objects themselves rather than the thread safety of the
121/// objects being referenced.
122///
123/// It is *not* *safe* to access or modify a `bsl::shared_ptr` (or
124/// `bsl::weak_ptr`) object in one thread while another thread modifies the same
125/// object. However, it is safe to access or modify two distinct `shared_ptr`
126/// (or `bsl::weak_ptr`) objects simultaneously, each from a separate thread,
127/// even if they share ownership of a common object. It is safe to access a
128/// single `bsl::shared_ptr` (or `bsl::weak_ptr`) object simultaneously from two
129/// or more separate threads, provided no other thread is simultaneously
130/// modifying the object.
131///
132/// It is safe to access, modify, copy, or delete a shared pointer (or weak
133/// pointer) in one thread, while other threads access or modify other shared
134/// pointers and weak pointers pointing to or managing the same object (the
135/// reference count is managed using atomic operations). However, there is no
136/// guarantee regarding the safety of accessing or modifying the object
137/// *referred* *to* by the shared pointer simultaneously from multiple threads.
138///
139/// ## Shared and Weak References {#bslstl_sharedptr-shared-and-weak-references}
140///
141///
142/// There are two types of references to shared objects:
143///
144/// 1) A shared reference allows users to share the ownership of an object and
145/// control its lifetime. A shared object is destroyed only when the last
146/// shared reference to it is released. A shared reference to an object can be
147/// obtained by creating a `shared_ptr` referring to it.
148///
149/// 2) A weak reference provides users conditional access to an object without
150/// sharing its ownership (or affecting its lifetime). A shared object can be
151/// destroyed even if there are weak references to it. A weak reference to an
152/// object can be obtained by creating a `weak_ptr` referring to the object from
153/// a `shared_ptr` referring to that object.
154///
155/// ## In-placeOut-of-place Representations {#bslstl_sharedptr-in-placeout-of-place-representations}
156///
157///
158/// `shared_ptr` provides two types of representations: an out-of-place
159/// representation, and an in-place representation. Out-of-place
160/// representations are used to refer to objects that are constructed externally
161/// to their associated representations. Out-of-place objects are provided to a
162/// shared pointer by passing their address along with the deleter that should
163/// be used to destroy the object when all references to it have been released.
164/// In-place objects can be constructed directly within a shared pointer
165/// representation (see `createInplace`).
166///
167/// Below we provide a diagram illustrating the differences between the two
168/// representations for a shared pointer to an `int`. First we create an `int`
169/// object on the heap, initialized to 10, and pass its address to a shared
170/// pointer constructor, resulting in an out-of-place representation for the
171/// shared object:
172/// @code
173/// bslma::NewDeleteAllocator nda;
174/// int *value = new (nda) int(10);
175/// shared_ptr<int> outOfPlaceSharedPtr(value, &nda);
176/// @endcode
177/// Next we create an in-place representation of a shared `int` object that is
178/// also initialized to 10:
179/// @code
180/// shared_ptr<int> inPlaceSharedPtr;
181/// inPlaceSharedPtr.createInplace(&nda, 10);
182/// @endcode
183/// The memory layouts of these two representations are shown below (where
184/// `d_ptr_p` refers to the shared object and `d_rep_p` refers to the
185/// representation):
186/// @code
187/// Out-of-Place Representation In-Place Representation
188/// ---------------------------- ----------------------------
189///
190/// +------------+ +------------+
191/// | | | |
192/// | d_ptr_p ------>+-----------+ | d_ptr_p ---------+
193/// | | | 10 | | | |
194/// | | +-----------+ | | |
195/// | | | | |
196/// | d_rep_p ------>+-----------+ | d_rep_p ------>+-v---------+
197/// | | | reference | | | |+---------+|
198/// | | | counts | | | || 10 ||
199/// +------------+ +-----------+ +------------+ |+---------+|
200/// | reference |
201/// | counts |
202/// +-----------+
203/// @endcode
204/// An out-of-place representation is generally less efficient than an in-place
205/// representation since it usually requires at least two allocations (one to
206/// construct the object and one to construct the shared pointer representation
207/// for the object).
208///
209/// Creating an in-place shared pointer does not require the template parameter
210/// type to inherit from a special class (such as
211/// `bsl::enable_shared_from_this`); in that case, `shared_ptr` supports up to
212/// fourteen arguments that can be passed directly to the object's constructor.
213/// For in-place representations, both the object and the representation can be
214/// constructed in one allocation as opposed to two, effectively creating an
215/// "intrusive" reference counter. Note that the size of the allocation is
216/// determined at compile-time from the combined footprint of the object and of
217/// the reference counts. It is also possible to create shared pointers to
218/// buffers whose sizes are determined at runtime, although such buffers consist
219/// of raw (uninitialized) memory.
220///
221/// ### Weak Pointers using "in-place" or Pooled Shared Pointer Representations {#bslstl_sharedptr-weak-pointers-using-in-place-or-pooled-shared-pointer-representations}
222///
223///
224/// A weak pointer that is not in the empty state shares a common representation
225/// (used to refer to the shared object) with the shared (or other weak) pointer
226/// from which it was constructed, and holds this representation until it is
227/// either destroyed or reset. This common representation is not destroyed and
228/// deallocated (although the shared object itself may have been destroyed)
229/// until all weak references to that common representation have been released.
230///
231/// Due to this behavior the *memory* *footprint* of shared objects that are
232/// constructed "in-place" in the shared pointer representation (see above) is
233/// not deallocated until all weak references to that shared object are
234/// released. Note that a shared object is always destroyed when the last
235/// shared reference to it is released. Also note that the same behavior
236/// applies if the shared object were obtained from a class that pools shared
237/// pointer representations (for example, `bcec_SharedObjectPool`).
238///
239/// For example suppose we have a class with a large memory footprint:
240/// @code
241/// /// This class has a large memory footprint.
242/// class ClassWithLargeFootprint {
243///
244/// // TYPES
245///
246/// /// The size of the buffer owned by this `class`.
247/// enum { BUFFER_SIZE = 1024 };
248///
249/// // DATA
250/// char d_buffer[BUFFER_SIZE];
251///
252/// // ...
253/// };
254/// @endcode
255/// We then create an "in-place" shared pointer to an object of
256/// `ClassWithLargeFootprint` using the `createInplace` method of `shared_ptr`.
257/// The `sp` shared pointer representation of `sp` will create a
258/// `ClassWithLargeFootprint` object "in-place":
259/// @code
260/// shared_ptr<ClassWithLargeFootprint> sp;
261/// sp.createInplace();
262/// @endcode
263/// Next we construct a weak pointer from this (in-place) shared pointer:
264/// @code
265/// weak_ptr<ClassWithLargeFootprint> wp(sp);
266/// @endcode
267/// Now releasing all shared references to the shared object (using the `reset`
268/// function) causes the object's destructor to be called, but the
269/// representation is not destroyed (and the object's footprint is not
270/// deallocated) until `wp` releases its weak reference:
271/// @code
272/// sp.reset(); // The object's footprint is not deallocated until all weak
273/// // references to it are released.
274///
275/// wp.reset(); // The release of the *last* weak reference results in the
276/// // destruction and deallocation of the representation and the
277/// // object's footprint.
278/// @endcode
279/// If a shared object has a large footprint, and the client anticipates there
280/// will be weak references to it, then an out-of-place shared pointer
281/// representation may be preferred because it destroys the shared object and
282/// deallocates its footprint when the last *shared* reference is released,
283/// regardless of whether there are any outstanding weak references to the same
284/// representation.
285///
286/// ## Correct Usage of the Allocator Model {#bslstl_sharedptr-correct-usage-of-the-allocator-model}
287///
288///
289/// Note that once constructed, there is no difference in type, usage, or
290/// efficiency between in-place and out-of-place shared pointers, except that an
291/// in-place shared pointer will exhibit greater locality of reference and
292/// faster destruction (because there is only one allocated block). Also note
293/// that an object created with an allocator needs to have this allocator
294/// specified as its last constructor argument, but this allocator may be
295/// different from the one passed as the first argument to `createInplace`.
296///
297/// For example, consider the following snippet of code:
298/// @code
299/// bslma::Allocator *allocator1, *allocator2;
300/// // ...
301/// shared_ptr<bsl::string> ptr;
302/// ptr.createInplace(allocator1, bsl::string("my string"), allocator2);
303/// @endcode
304/// Here `allocator1` is used to obtain the shared pointer representation and
305/// the in-place `bsl::string` object, and `allocator2` is used by the
306/// `bsl::string` object (having the value "my string") for its memory
307/// allocations. Typically, both allocators will be the same, and so the same
308/// allocator will need to be specified twice.
309///
310/// ## Deleters {#bslstl_sharedptr-deleters}
311///
312///
313/// When the last shared reference to a shared object is released, the object is
314/// destroyed using the "deleter" provided when the associated shared pointer
315/// representation was created. `shared_ptr` supports two kinds of "deleter"
316/// objects, which vary in how they are invoked. A "function-like" deleter is
317/// any language entity that can be invoked such that the expression
318/// `deleterInstance(objectPtr)` is a valid expression. A "factory" deleter is
319/// any language entity that can be invoked such that the expression
320/// `deleterInstance.deleteObject(objectPtr)` is a valid expression, where
321/// `deleterInstance` is an instance of the "deleter" object, and `objectPtr` is
322/// a pointer to the shared object. Factory deleters are a BDE extension to the
323/// ISO C++ Standard Library specification for `shared_ptr`. In summary:
324/// @code
325/// Deleter Expression used to destroy 'objectPtr'
326/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
327/// "function-like" deleterInstance(objectPtr);
328/// "factory" deleterInstance.deleteObject(objectPtr);
329/// @endcode
330/// The following are examples of function-like deleters that delete an object
331/// of `my_Type`:
332/// @code
333/// /// Delete the specified `object`.
334/// void deleteObject(my_Type *object);
335///
336/// /// Release the specified `object`.
337/// void releaseObject(my_Type *object);
338///
339/// /// This `struct` provides an `operator()` that can be used to delete a
340/// /// `my_Type` object.
341/// struct FunctionLikeDeleterObject {
342///
343/// /// Destroy the specified `object`.
344/// void operator()(my_Type *object);
345/// };
346/// @endcode
347/// The following, on the other hand is an example of a factory deleter:
348/// @code
349/// class my_Factory {
350///
351/// // . . .
352///
353/// // MANIPULATORS
354///
355/// /// Create a `my_Type` object. Optionally specify a
356/// /// `basicAllocator` used to supply memory. If `basicAllocator` is
357/// /// 0, the currently installed default allocator is used.
358/// my_Type *createObject(bslma::Allocator *basicAllocator = 0);
359///
360/// /// Delete the specified `object`.
361/// void deleteObject(my_Type *object);
362/// };
363///
364/// class my_Allocator : public bslma::Allocator { /* ... */ };
365/// @endcode
366/// Note that `deleteObject` is provided by all `bslma` allocators and by any
367/// object that implements the `bdlma::Deleter` protocol. Thus, any of these
368/// objects can be used as a factory deleter. The purpose of this design is to
369/// allow `bslma` allocators and factories to be used seamlessly as deleters.
370///
371/// The selection of which expression is used by `shared_ptr` to destroy a
372/// shared object is based on how the deleter is passed to the shared pointer
373/// object: Deleters that are passed by *address* are assumed to be factory
374/// deleters (unless they are function pointers), while those that are passed by
375/// *value* are assumed to be function-like. Note that if the wrong interface
376/// is used for a deleter, i.e., if a function-like deleter is passed by
377/// pointer, or a factory deleter is passed by value, and the expression used to
378/// delete the object is invalid, a compiler diagnostic will be emitted
379/// indicating the error.
380///
381/// In general, deleters should have defined behavior when called with a null
382/// pointer. In all cases, throwing an exception out of a copy constructor for
383/// a deleter will yield undefined behavior.
384///
385/// The following are examples of constructing shared pointers with the
386/// addresses of factory deleters:
387/// @code
388/// my_Factory factory;
389/// my_Type *myPtr1 = factory.createObject();
390/// shared_ptr<my_Type> mySharedPtr1(myPtr1, &factory, 0);
391///
392/// bdema_SequentialAllocator sa;
393/// my_Type *myPtr2 = new (sa) my_Type(&sa);
394/// shared_ptr<my_Type> mySharedPtr2(myPtr2, &sa);
395/// @endcode
396/// Note that the deleters are passed *by address* in the above examples.
397///
398/// The following are examples of constructing shared pointers with
399/// function-like deleters:
400/// @code
401/// my_Type *getObject(bslma::Allocator *basicAllocator = 0);
402///
403/// my_Type *myPtr3 = getObject();
404/// shared_ptr<my_Type> mySharedPtr3(myPtr3, &deleteObject);
405///
406/// my_Type *myPtr4 = getObject();
407/// FunctionLikeDeleterObject deleter;
408/// shared_ptr<my_Type> mySharedPtr4(myPtr4, deleter, &sa);
409/// @endcode
410/// Note that `deleteObject` is also passed by address, but `deleter` is passed
411/// by value in the above examples. Function-like deleter objects (passed by
412/// value) are stored by value in the representation and therefore *must* be
413/// copy-constructible. Note that even though the deleter may be passed by
414/// reference, it is a copy (owned by the shared pointer representation) that is
415/// invoked and thus the `deleterInstance` is not required, nor assumed, to be
416/// non-modifiable. (For the example above, note that `operator()` is
417/// intentionally *not* defined `const`.)
418///
419/// ## Aliasing {#bslstl_sharedptr-aliasing}
420///
421///
422/// `shared_ptr` supports a powerful "aliasing" feature. That is, a shared
423/// pointer can be constructed to refer to a shared object of a certain type
424/// while the shared pointer representation it holds refers to a shared object
425/// of any (possibly different) type. All references are applied to the
426/// "aliased" shared object referred to by the representation and is used for
427/// reference counting. This "aliased" shared object is passed to the deleter
428/// upon destruction of the last instance of that shared pointer. Consider the
429/// following snippet of code:
430/// @code
431/// class Event { /* ... */ };
432/// void getEvents(bsl::list<Event> *list);
433///
434/// void enqueueEvents(bcec_Queue<shared_ptr<Event> > *queue)
435/// {
436/// bsl::list<Event> eventList;
437/// getEvents(&eventList);
438/// for (bsl::list<Event>::iterator it = eventList.begin();
439/// it != eventList.end();
440/// ++it) {
441/// shared_ptr<Event> e;
442/// e.createInplace(0, *it); // Copy construct the event into a new
443/// // shared ptr.
444/// queue->pushBack(e);
445/// }
446/// }
447/// @endcode
448/// In the above example, `getEvents` loads into the provided `bsl::list` a
449/// sequence of event objects. The `enqueueEvents` function constructs an empty
450/// list and calls `getEvents` to fill the list with `Event` objects. Once the
451/// event list is filled, each event item is pushed as a shared pointer
452/// (presumably because events are "expensive" to construct and may be
453/// referenced simultaneously from multiple threads) onto the provided queue.
454/// Since the individual event items are contained by value within the list,
455/// pointers to them cannot be passed if it cannot be guaranteed that they will
456/// not live beyond the lifetime of the list itself. Therefore, an expensive
457/// copy operation is required to create individually-managed instances of each
458/// of the list items. The `createInplace` operation is used to reduce the
459/// number of required allocations, but this might still be too expensive. Now
460/// consider the following alternate implementation of `enqueueEvents` using the
461/// `shared_ptr` aliasing feature:
462/// @code
463/// void enqueueEvents(bcec_Queue<shared_ptr<Event> > *queue)
464/// {
465/// shared_ptr<bsl::list<Event> > eventList;
466/// eventList.createInplace(0); // Construct a shared pointer
467/// // to the event list containing
468/// // all of the events.
469/// getEvents(eventList.get());
470///
471/// for (bsl::list<Event>::iterator it = eventList->begin();
472/// it != eventList->end();
473/// ++it) {
474/// // Push each event onto the queue as an alias of the `eventList`
475/// // shared pointer. When all the alias references have been
476/// // released, the event list will be destroyed deleting all the
477/// // events at once.
478///
479/// queue->pushBack(shared_ptr<Event>(eventList, &*it));
480/// }
481/// }
482/// @endcode
483/// In the implementation above, we create a single shared pointer to the
484/// `Event` list, `eventList`, and use that to create `Event` shared pointers
485/// that are aliased to `eventList`. The lifetime of each `Event` object is
486/// then tied to the `eventList` and it will not be destroyed until the
487/// `eventList` is destroyed.
488///
489/// ## Type Casting {#bslstl_sharedptr-type-casting}
490///
491///
492/// A `shared_ptr` object of a given type can be implicitly or explicitly cast
493/// to a `shared_ptr` of another type.
494///
495/// ### Implicit Casting {#bslstl_sharedptr-implicit-casting}
496///
497///
498/// As with native pointers, a shared pointer to a derived type can be directly
499/// assigned to a shared pointer to a base type. In other words, if the
500/// following statements are valid:
501/// @code
502/// class A { virtual void foo(); }; // polymorphic type
503/// class B : public A {};
504/// B *bp = 0;
505/// A *ap = bp;
506/// @endcode
507/// then the following statements:
508/// @code
509/// shared_ptr<B> spb;
510/// shared_ptr<A> spa;
511/// spa = spb;
512/// @endcode
513/// and:
514/// @code
515/// shared_ptr<B> spb;
516/// shared_ptr<A> spa(spb);
517/// @endcode
518/// are also valid. Note that in all of the above cases, the destructor of `B`
519/// will be invoked when the object is destroyed even if `A` does not provide a
520/// virtual destructor.
521///
522/// ### Explicit Casting {#bslstl_sharedptr-explicit-casting}
523///
524///
525/// Through "aliasing", a shared pointer of any type can be explicitly cast to a
526/// shared pointer of any other type using any legal cast expression. For
527/// example, to statically cast a shared pointer to type `A` (`shared_ptr<A>`)
528/// to a shared pointer to type `B` (`shared_ptr<B>`), one can simply do the
529/// following:
530/// @code
531/// shared_ptr<A> spa;
532/// shared_ptr<B> spb(spa, static_cast<B *>(spa.get()));
533/// @endcode
534/// or even the less safe C-style cast:
535/// @code
536/// shared_ptr<A> spa;
537/// shared_ptr<B> spb(spa, (B *)(spa.get()));
538/// @endcode
539/// For convenience, several utility functions are provided to perform common
540/// C++ casts. Dynamic casts, static casts, and `const` casts are all provided.
541/// Explicit casting is supported through the `bslstl::SharedPtrUtil` utility.
542/// The following example demonstrates the dynamic casting of a shared pointer
543/// to type `A` (`shared_ptr<A>`) to a shared pointer to type `B`
544/// (`shared_ptr<B>`):
545/// @code
546/// bslma::NewDeleteAllocator nda;
547/// shared_ptr<A> sp1(new (nda) A(), &nda);
548/// shared_ptr<B> sp2 = bslstl::SharedPtrUtil::dynamicCast<B>(sp1);
549/// shared_ptr<B> sp3;
550/// bslstl::SharedPtrUtil::dynamicCast(&sp3, sp1);
551/// shared_ptr<B> sp4;
552/// sp4 = bslstl::SharedPtrUtil::dynamicCast<B>(sp1);
553/// @endcode
554/// To test if the cast succeeded, simply test if the target shared pointer
555/// refers to a non-null value (assuming the source was not null, of course):
556/// @code
557/// if (sp2) {
558/// // The cast succeeded.
559/// } else {
560/// // The cast failed.
561/// }
562/// @endcode
563/// As previously stated, the shared object will be destroyed correctly
564/// regardless of how it is cast.
565///
566/// ## Converting to and from BloombergLP::bslma::ManagedPtr {#bslstl_sharedptr-converting-to-and-from-bloomberglp-bslma-managedptr}
567///
568///
569/// A `shared_ptr` can be converted to a `BloombergLP::bslma::ManagedPtr` while
570/// still retaining proper reference counting. When a shared pointer is
571/// converted to a `BloombergLP::bslma::ManagedPtr`, the number of references to
572/// the shared object is incremented. When the managed pointer is destroyed (if
573/// not transferred to another managed pointer first), the number of references
574/// will be decremented. If the number of references reaches zero, then the
575/// shared object will be destroyed. The `managedPtr` function can be used to
576/// create a managed pointer from a shared pointer.
577///
578/// A `shared_ptr` also can be constructed from a
579/// `BloombergLP::bslma::ManagedPtr`. The resulting shared pointer takes over
580/// the management of the object and will use the deleter from the original
581/// `BloombergLP::bslma::ManagedPtr` to destroy the managed object when all the
582/// references to that shared object are released.
583///
584/// ## Weak Pointers using "in-place" or Pooled Shared Pointer Representations {#bslstl_sharedptr-weak-pointers-using-in-place-or-pooled-shared-pointer-representations}
585///
586///
587/// A weak pointer that is not in the empty state shares a common representation
588/// (used to refer to the shared object) with the shared (or other weak) pointer
589/// from which it was constructed, and holds this representation until it is
590/// either destroyed or reset. This common representation is not destroyed and
591/// deallocated (although the shared object itself may have been destroyed)
592/// until all weak references to that common representation have been released.
593///
594/// Due to this behavior the memory footprint of shared objects that are
595/// constructed "in-place" in the shared pointer representation (refer to the
596/// component-level documentation of `bsl::shared_ptr` for more information on
597/// shared pointers with "in-place" representations) is not deallocated until
598/// all weak references to that shared object are released. Note that a shared
599/// object is always destroyed when the last shared reference to it is released.
600/// Also note that the same behavior is applicable if the shared objects were
601/// obtained from a class that pools shared pointer representations (for
602/// example, `bcec_SharedObjectPool`).
603///
604/// For example suppose we have a class with a large memory footprint:
605/// @code
606/// /// This class has a large memory footprint.
607/// class ClassWithLargeFootprint {
608///
609/// // TYPES
610///
611/// // The size of the buffer owned by this `class`.
612/// enum { BUFFER_SIZE = 1024 };
613///
614/// // DATA
615/// char d_buffer[BUFFER_SIZE];
616///
617/// // ...
618/// };
619/// @endcode
620/// We then create an "in-place" shared pointer to an object of
621/// `ClassWithLargeFootprint` using the `createInplace` method of
622/// `bsl::shared_ptr`. The `sp` shared pointer representation of `sp` will
623/// create a `ClassWithLargeFootprint` object "in-place":
624/// @code
625/// bsl::shared_ptr<ClassWithLargeFootprint> sp;
626/// sp.createInplace();
627/// @endcode
628/// Next we construct a weak pointer from this (in-place) shared pointer:
629/// @code
630/// bsl::weak_ptr<ClassWithLargeFootprint> wp(sp);
631/// @endcode
632/// Now releasing all shared references to the shared object (using the `reset`
633/// function) causes the object's destructor to be called, but the
634/// representation is not destroyed (and the object's footprint is not
635/// deallocated) until `wp` releases its weak reference:
636/// @code
637/// sp.reset(); // The object's footprint is not deallocated until all weak
638/// // references to it are released.
639///
640/// wp.reset(); // The release of the *last* weak reference results in the
641/// // destruction and deallocation of the representation and the
642/// // object's footprint.
643/// @endcode
644/// If a shared object has a large footprint, and the client anticipates there
645/// will be weak references to it, then it may be advisable to create an
646/// out-of-place shared pointer representation, which destroys the shared object
647/// and deallocates its footprint when the last *shared* reference to it is
648/// released, regardless of whether there are any outstanding weak references to
649/// the same representation.
650///
651/// ## C++ Standard Compliance {#bslstl_sharedptr-c-standard-compliance}
652///
653///
654/// This component provides an (extended) standard-compliant implementation of
655/// `std::shared_ptr` and `std::weak_ptr` (section 20.7.2, [util.smartptr], of
656/// the ISO C++11 standard)). However, it does not support the atomic shared
657/// pointer interface, nor provide the C++17 interface for `shared_ptr` of an
658/// array type. When using a C++03 compiler, its interface is limited to the
659/// set of operations that can be implemented by an implementation of the C++03
660/// language, e,g., there are no exception specifications, nor `constexpr`
661/// constructors, and move operations are emulated with `bslmf::MovableRef`.
662///
663/// In addition to the standard interface, this component supports allocators
664/// following the `bslma::Allocator` protocol in addition to the C++ Standard
665/// Allocators (section 17.6.3.5, [allocator.requirements]), supports "factory"
666/// style deleters in addition to function-like deleters, and interoperation
667/// with `bslma::ManagedPtr` smart pointers.
668///
669/// ## Usage {#bslstl_sharedptr-usage}
670///
671///
672/// The following examples demonstrate various features and uses of shared
673/// pointers.
674///
675/// ### Example 1: Basic Usage {#bslstl_sharedptr-example-1-basic-usage}
676///
677///
678/// The following example demonstrates the creation of a shared pointer. First,
679/// we declare the type of object that we wish to manage:
680/// @code
681/// class MyUser {
682/// // DATA
683/// bsl::string d_name;
684/// int d_id;
685///
686/// public:
687/// // CREATORS
688/// MyUser(bslma::Allocator *alloc = 0) : d_name(alloc), d_id(0) {}
689/// MyUser(const bsl::string& name, int id, bslma::Allocator *alloc = 0)
690/// : d_name(name, alloc)
691/// , d_id(id)
692/// {
693/// }
694/// MyUser(const MyUser& original, bslma::Allocator *alloc = 0)
695/// : d_name(original.d_name, alloc)
696/// , d_id(original.d_id)
697/// {
698/// }
699///
700/// // MANIPULATORS
701/// void setName(const bsl::string& name) { d_name = name; }
702/// void setId(int id) { d_id = id; }
703///
704/// // ACCESSORS
705/// const bsl::string& name() const { return d_name; }
706/// int id() const { return d_id; }
707/// };
708/// @endcode
709/// The `createUser` utility function (below) creates a `MyUser` object using
710/// the provided allocator and returns a shared pointer to the newly-created
711/// object. Note that the shared pointer's internal representation will also be
712/// allocated using the same allocator. Also note that if `allocator` is 0, the
713/// currently-installed default allocator is used.
714/// @code
715/// shared_ptr<MyUser> createUser(bsl::string name,
716/// int id,
717/// bslma::Allocator *allocator = 0)
718/// {
719/// allocator = bslma::Default::allocator(allocator);
720/// MyUser *user = new (*allocator) MyUser(name, id, allocator);
721/// return shared_ptr<MyUser>(user, allocator);
722/// }
723/// @endcode
724/// Since the `createUser` function both allocates the object and creates the
725/// shared pointer, it can benefit from the in-place facilities to avoid an
726/// extra allocation. Again, note that the representation will also be
727/// allocated using the same allocator (see the section "Correct Usage of the
728/// Allocator Model" above). Also note that if `allocator` is 0, the
729/// currently-installed default allocator is used.
730/// @code
731/// shared_ptr<MyUser> createUser2(bsl::string name,
732/// int id,
733/// bslma::Allocator *allocator = 0)
734/// {
735/// shared_ptr<MyUser> user;
736/// user.createInplace(allocator, name, id, allocator);
737/// return user;
738/// }
739/// @endcode
740/// Note that the shared pointer allocates both the reference count and the
741/// `MyUser` object in a single region of memory (which is the memory that will
742/// eventually be deallocated), but refers to the `MyUser` object only.
743///
744/// ### Using Custom Deleters {#bslstl_sharedptr-using-custom-deleters}
745///
746///
747/// The following examples demonstrate the use of custom deleters with shared
748/// pointers.
749///
750/// #### Example 2: Nil Deleters {#bslstl_sharedptr-example-2-nil-deleters}
751///
752///
753/// There are cases when an interface calls for an object to be passed as a
754/// shared pointer, but the object being passed is not owned by the caller
755/// (e.g., a pointer to a static variable). In these cases, it is possible to
756/// create a shared pointer specifying `bslstl::SharedPtrNilDeleter` as the
757/// deleter. The deleter function provided by `bslstl::SharedPtrNilDeleter` is
758/// a no-op and does not delete the object. The following example demonstrates
759/// the use of `shared_ptr` using a `bslstl::SharedPtrNilDeleter`. The code
760/// uses the `MyUser` class defined in Example 1. In this example, an
761/// asynchronous transaction manager is implemented. Transactions are enqueued
762/// into the transaction manager to be processed at some later time. The user
763/// associated with the transaction is passed as a shared pointer. Transactions
764/// can originate from the "system" or from "users".
765///
766/// We first declare the transaction manager and transaction info classes:
767/// @code
768/// class MyTransactionInfo {
769/// // Transaction Info...
770/// };
771///
772/// class MyTransactionManager {
773///
774/// // PRIVATE MANIPULATORS
775/// int enqueueTransaction(shared_ptr<MyUser> user,
776/// const MyTransactionInfo& transaction);
777/// public:
778/// // CLASS METHODS
779/// static MyUser *systemUser(bslma::Allocator *basicAllocator = 0);
780///
781/// // MANIPULATORS
782/// int enqueueSystemTransaction(const MyTransactionInfo& transaction);
783///
784/// int enqueueUserTransaction(const MyTransactionInfo& transaction,
785/// shared_ptr<MyUser> user);
786///
787/// };
788/// @endcode
789/// The `systemUser` class method returns the same `MyUser` object and should
790/// not be destroyed by its users:
791/// @code
792/// MyUser *MyTransactionManager::systemUser(
793/// bslma::Allocator * /* basicAllocator */)
794/// {
795/// static MyUser *systemUserSingleton;
796/// if (!systemUserSingleton) {
797/// // instantiate singleton in a thread-safe manner passing
798/// // `basicAllocator`
799///
800/// // . . .
801/// }
802/// return systemUserSingleton;
803/// }
804/// @endcode
805/// For enqueuing user transactions, simply proxy the information to
806/// `enqueueTransaction`.
807/// @code
808/// inline
809/// int MyTransactionManager::enqueueUserTransaction(
810/// const MyTransactionInfo& transaction,
811/// shared_ptr<MyUser> user)
812/// {
813/// return enqueueTransaction(user, transaction);
814/// }
815/// @endcode
816/// For system transactions, we must use the `MyUser` objected returned from the
817/// `systemUser` `static` method. Since we do not own the returned object, we
818/// cannot directly construct a `shared_ptr` object for it: doing so would
819/// result in the singleton being destroyed when the last reference to the
820/// shared pointer is released. To solve this problem, we construct a
821/// `shared_ptr` object for the system user using a nil deleter. When the last
822/// reference to the shared pointer is released, although the deleter will be
823/// invoked to destroy the object, it will do nothing.
824/// @code
825/// int MyTransactionManager::enqueueSystemTransaction(
826/// const MyTransactionInfo& transaction)
827/// {
828/// shared_ptr<MyUser> user(systemUser(),
829/// bslstl::SharedPtrNilDeleter(),
830/// 0);
831/// return enqueueTransaction(user, transaction);
832/// }
833/// @endcode
834///
835/// ### Example 3: Basic Weak Pointer Usage {#bslstl_sharedptr-example-3-basic-weak-pointer-usage}
836///
837///
838/// This example illustrates the basic syntax needed to create and use a
839/// `bsl::weak_ptr`. Suppose that we want to construct a weak pointer that
840/// refers to an `int` managed by a shared pointer. Next we define the shared
841/// pointer and assign a value to the shared `int`:
842/// @code
843/// bsl::shared_ptr<int> intPtr;
844/// intPtr.createInplace(bslma::Default::allocator());
845/// *intPtr = 10;
846/// assert(10 == *intPtr);
847/// @endcode
848/// Next we construct a weak pointer to the `int`:
849/// @code
850/// bsl::weak_ptr<int> intWeakPtr(intPtr);
851/// assert(!intWeakPtr.expired());
852/// @endcode
853/// `bsl::weak_ptr` does not provide direct access to the shared object being
854/// referenced. To access and manipulate the `int` from the weak pointer, we
855/// have to obtain a shared pointer from it:
856/// @code
857/// bsl::shared_ptr<int> intPtr2 = intWeakPtr.lock();
858/// assert(intPtr2);
859/// assert(10 == *intPtr2);
860///
861/// *intPtr2 = 20;
862/// assert(20 == *intPtr);
863/// assert(20 == *intPtr2);
864/// @endcode
865/// We remove the weak reference to the shared `int` by calling the `reset`
866/// method:
867/// @code
868/// intWeakPtr.reset();
869/// assert(intWeakPtr.expired());
870/// @endcode
871/// Note that resetting the weak pointer does not affect the shared pointers
872/// referencing the `int` object:
873/// @code
874/// assert(20 == *intPtr);
875/// assert(20 == *intPtr2);
876/// @endcode
877/// Now, we construct another weak pointer referencing the shared `int`:
878/// @code
879/// bsl::weak_ptr<int> intWeakPtr2(intPtr);
880/// assert(!intWeakPtr2.expired());
881/// @endcode
882/// Finally `reset` all shared references to the `int`, which will cause the
883/// weak pointer to become "expired"; any subsequent attempt to obtain a shared
884/// pointer from the weak pointer will return a shared pointer in the default
885/// constructed (empty) state:
886/// @code
887/// intPtr.reset();
888/// intPtr2.reset();
889/// assert(intWeakPtr2.expired());
890/// assert(!intWeakPtr2.lock());
891/// @endcode
892///
893/// ### Example 4: Breaking Cyclical Dependencies {#bslstl_sharedptr-example-4-breaking-cyclical-dependencies}
894///
895///
896/// Weak pointers are frequently used to break cyclical dependencies between
897/// objects that store references to each other via a shared pointer. Consider
898/// for example a simplified news alert system that sends news alerts to users
899/// based on keywords that they register for. The user information is stored in
900/// the `User` class and the details of the news alert are stored in the `Alert`
901/// class. The class definitions for `User` and `Alert` are provided below
902/// (with any code not relevant to this example elided):
903/// @code
904/// class Alert;
905///
906/// /// This class stores the user information required for listening to
907/// /// alerts.
908/// class User {
909///
910/// bsl::vector<bsl::shared_ptr<Alert> > d_alerts; // alerts user is
911/// // registered for
912///
913/// // ...
914///
915/// public:
916/// // MANIPULATORS
917///
918/// /// Add the specified `alertPtr` to the list of alerts being
919/// /// monitored by this user.
920/// void addAlert(const bsl::shared_ptr<Alert>& alertPtr)
921/// {
922/// d_alerts.push_back(alertPtr);
923/// }
924///
925/// // ...
926/// };
927/// @endcode
928/// Now we define an alert class, `Alert`:
929/// @code
930/// /// This class stores the alert information required for sending
931/// /// alerts.
932/// class Alert {
933///
934/// bsl::vector<bsl::shared_ptr<User> > d_users; // users registered
935/// // for this alert
936///
937/// public:
938/// // MANIPULATORS
939///
940/// /// Add the specified `userPtr` to the list of users monitoring this
941/// /// alert.
942/// void addUser(const bsl::shared_ptr<User>& userPtr)
943/// {
944/// d_users.push_back(userPtr);
945/// }
946///
947/// // ...
948/// };
949///
950/// @endcode
951/// Even though we have released `alertPtr` and `userPtr` there still exists a
952/// cyclic reference between the two objects, so none of the objects are
953/// destroyed.
954///
955/// We can break this cyclical dependency we define a modified alert class
956/// `ModifiedAlert` that stores a weak pointer to a `ModifiedUser` object.
957/// Below is the definition for the `ModifiedUser` class that is identical to
958/// the `User` class, the only difference being that it stores shared pointer to
959/// `ModifiedAlert`s instead of `Alert`s:
960/// @code
961/// class ModifiedAlert;
962///
963/// /// This class stores the user information required for listening to
964/// /// alerts.
965/// class ModifiedUser {
966///
967/// bsl::vector<bsl::shared_ptr<ModifiedAlert> > d_alerts;// alerts user is
968/// // registered for
969///
970/// // ...
971///
972/// public:
973/// // MANIPULATORS
974///
975/// /// Add the specified `alertPtr` to the list of alerts being
976/// /// monitored by this user.
977/// void addAlert(const bsl::shared_ptr<ModifiedAlert>& alertPtr)
978/// {
979/// d_alerts.push_back(alertPtr);
980/// }
981///
982/// // ...
983/// };
984/// @endcode
985/// Now we define the `ModifiedAlert` class:
986/// @code
987/// /// This class stores the alert information required for sending
988/// /// alerts.
989/// class ModifiedAlert {
990/// @endcode
991/// Note that the user is stored by a weak pointer instead of by a shared
992/// pointer:
993/// @code
994/// bsl::vector<bsl::weak_ptr<ModifiedUser> > d_users; // users registered
995/// // for this alert
996///
997/// public:
998/// // MANIPULATORS
999///
1000/// /// Add the specified `userPtr` to the list of users monitoring this
1001/// /// alert.
1002/// void addUser(const bsl::weak_ptr<ModifiedUser>& userPtr)
1003/// {
1004/// d_users.push_back(userPtr);
1005/// }
1006///
1007/// // ...
1008/// };
1009/// @endcode
1010///
1011/// ### Example 5: Caching {#bslstl_sharedptr-example-5-caching}
1012///
1013///
1014/// Suppose we want to implement a peer to peer file sharing system that allows
1015/// users to search for files that match specific keywords. A simplistic
1016/// version of such a system with code not relevant to the usage example elided
1017/// would have the following parts:
1018///
1019/// a) A peer manager class that maintains a list of all connected peers and
1020/// updates the list based on incoming peer requests and disconnecting peers.
1021/// The following would be a simple interface for the Peer and PeerManager
1022/// classes:
1023/// @code
1024/// /// This class stores all the relevant information for a peer.
1025/// class Peer {
1026///
1027/// // ...
1028/// };
1029///
1030/// /// This class acts as a manager of peers and adds and removes peers
1031/// /// based on peer requests and disconnections.
1032/// class PeerManager {
1033///
1034/// // DATA
1035/// @endcode
1036/// The peer objects are stored by shared pointer to allow peers to be passed to
1037/// search results and still allow their asynchronous destruction when peers
1038/// disconnect.
1039/// @code
1040/// bsl::map<int, bsl::shared_ptr<Peer> > d_peers;
1041///
1042/// // ...
1043/// };
1044/// @endcode
1045/// b) A peer cache class that stores a subset of the peers that are used for
1046/// sending search requests. The cache may select peers based on their
1047/// connection bandwidth, relevancy of previous search results, etc. For
1048/// brevity the population and flushing of this cache is not shown:
1049/// @code
1050/// /// This class caches a subset of all peers that match certain criteria
1051/// /// including connection bandwidth, relevancy of previous search
1052/// /// results, etc.
1053/// class PeerCache {
1054///
1055/// @endcode
1056/// Note that the cached peers are stored as a weak pointer so as not to
1057/// interfere with the cleanup of Peer objects by the PeerManager if a Peer goes
1058/// down.
1059/// @code
1060/// // DATA
1061/// bsl::list<bsl::weak_ptr<Peer> > d_cachedPeers;
1062///
1063/// public:
1064/// // TYPES
1065/// typedef bsl::list<bsl::weak_ptr<Peer> >::const_iterator PeerConstIter;
1066///
1067/// // ...
1068///
1069/// // ACCESSORS
1070/// PeerConstIter begin() const { return d_cachedPeers.begin(); }
1071/// PeerConstIter end() const { return d_cachedPeers.end(); }
1072/// };
1073/// @endcode
1074/// c) A search result class that stores a search result and encapsulates a peer
1075/// with the file name stored by the peer that best matches the specified
1076/// keywords:
1077/// @code
1078/// /// This class provides a search result and encapsulates a particular
1079/// /// peer and filename combination that matches a specified set of
1080/// /// keywords.
1081/// class SearchResult {
1082/// @endcode
1083/// The peer is stored as a weak pointer because when the user decides to select
1084/// a particular file to download from this peer, the peer might have
1085/// disconnected.
1086/// @code
1087/// // DATA
1088/// bsl::weak_ptr<Peer> d_peer;
1089/// bsl::string d_filename;
1090///
1091/// public:
1092/// // CREATORS
1093/// SearchResult(const bsl::weak_ptr<Peer>& peer,
1094/// const bsl::string& filename)
1095/// : d_peer(peer)
1096/// , d_filename(filename)
1097/// {
1098/// }
1099///
1100/// // ...
1101///
1102/// // ACCESSORS
1103/// const bsl::weak_ptr<Peer>& peer() const { return d_peer; }
1104/// const bsl::string& filename() const { return d_filename; }
1105/// };
1106/// @endcode
1107/// d) A search function that takes a list of keywords and returns available
1108/// results by searching the cached peers:
1109/// @code
1110/// void search(bsl::vector<SearchResult> * /* results */,
1111/// const PeerCache& peerCache,
1112/// const bsl::vector<bsl::string>& /* keywords */)
1113/// {
1114/// for (PeerCache::PeerConstIter iter = peerCache.begin();
1115/// iter != peerCache.end();
1116/// ++iter) {
1117/// @endcode
1118/// First we check if the peer is still connected by acquiring a shared pointer
1119/// to the peer. If the acquire operation succeeds, then we can send the peer a
1120/// request to send back the file best matching the specified keywords:
1121/// @code
1122/// bsl::shared_ptr<Peer> peerSharedPtr = iter->lock();
1123/// if (peerSharedPtr) {
1124///
1125/// // Search the peer for file best matching the specified
1126/// // keywords and if a file is found add the returned
1127/// // SearchResult object to result.
1128///
1129/// // ...
1130/// }
1131/// }
1132/// }
1133/// @endcode
1134/// e) A download function that downloads a file selected by the user:
1135/// @code
1136/// void download(const SearchResult& result)
1137/// {
1138/// bsl::shared_ptr<Peer> peerSharedPtr = result.peer().lock();
1139/// if (peerSharedPtr) {
1140/// // Download the result.filename() file from peer knowing that
1141/// // the peer is still connected.
1142/// }
1143/// }
1144/// @endcode
1145///
1146/// #### Example 6: Custom Deleters {#bslstl_sharedptr-example-6-custom-deleters}
1147///
1148///
1149/// The role of a "deleter" is to allow users to define a custom "cleanup" for a
1150/// shared object. Although cleanup generally involves destroying the object,
1151/// this need not be the case. The following example demonstrates the use of a
1152/// custom deleter to construct "locked" pointers. First we declare a custom
1153/// deleter that, when invoked, releases the specified mutex and signals the
1154/// specified condition variable.
1155/// @code
1156/// class my_MutexUnlockAndBroadcastDeleter {
1157///
1158/// // DATA
1159/// bslmt::Mutex *d_mutex_p; // mutex to lock (held, not owned)
1160/// bslmt::Condition *d_cond_p; // condition variable used to broadcast
1161/// // (held, not owned)
1162///
1163/// public:
1164/// // CREATORS
1165///
1166/// /// Create this `my_MutexUnlockAndBroadcastDeleter` object. Use
1167/// /// the specified `cond` to broadcast a signal and the specified
1168/// /// `mutex` to serialize access to `cond`. The behavior is
1169/// /// undefined unless `mutex` is not 0 and `cond` is not 0.
1170/// my_MutexUnlockAndBroadcastDeleter(bslmt::Mutex *mutex,
1171/// bslmt::Condition *cond)
1172/// : d_mutex_p(mutex)
1173/// , d_cond_p(cond)
1174/// {
1175/// BSLS_ASSERT(mutex);
1176/// BSLS_ASSERT(cond);
1177///
1178/// d_mutex_p->lock();
1179/// }
1180///
1181/// my_MutexUnlockAndBroadcastDeleter(
1182/// my_MutexUnlockAndBroadcastDeleter& original)
1183/// : d_mutex_p(original.d_mutex_p)
1184/// , d_cond_p(original.d_cond_p)
1185/// {
1186/// }
1187/// @endcode
1188/// Since this deleter does not actually delete anything, `void *` is used in
1189/// the signature of `operator()`, allowing it to be used with any type of
1190/// object.
1191/// @code
1192/// void operator()(void *)
1193/// {
1194/// d_cond_p->broadcast();
1195/// d_mutex_p->unlock();
1196/// }
1197/// };
1198/// @endcode
1199/// Next we declare a thread-safe queue `class`. The `class` uses a
1200/// non-thread-safe `bsl::deque` to implement the queue. Thread-safe `push` and
1201/// `pop` operations that push and pop individual items are provided. For
1202/// callers that wish to gain direct access to the queue, the `queue` method
1203/// returns a shared pointer to the queue using the
1204/// `my_MutexUnlockAndBroadcastDeleter`. Callers can safely access the queue
1205/// through the returned shared pointer. Once the last reference to the pointer
1206/// is released, the mutex will be unlocked and the condition variable will be
1207/// signaled to allow waiting threads to re-evaluate the state of the queue.
1208/// @code
1209/// template <class ELEMENT_TYPE>
1210/// class my_SafeQueue {
1211///
1212/// // DATA
1213/// bslmt::Mutex d_mutex;
1214/// bslmt::Condition d_cond;
1215/// bsl::deque<ELEMENT_TYPE> d_queue;
1216///
1217/// // . . .
1218///
1219/// public:
1220/// // MANIPULATORS
1221/// void push(const ELEMENT_TYPE& obj);
1222///
1223/// ELEMENT_TYPE pop();
1224///
1225/// shared_ptr<bsl::deque<ELEMENT_TYPE> > queue();
1226/// };
1227///
1228/// template <class ELEMENT_TYPE>
1229/// void my_SafeQueue<ELEMENT_TYPE>::push(const ELEMENT_TYPE& obj)
1230/// {
1231/// bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
1232/// d_queue.push_back(obj);
1233/// d_cond.signal();
1234/// }
1235///
1236/// template <class ELEMENT_TYPE>
1237/// ELEMENT_TYPE my_SafeQueue<ELEMENT_TYPE>::pop()
1238/// {
1239/// bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
1240/// while (!d_queue.size()) {
1241/// d_cond.wait(&d_mutex);
1242/// }
1243/// ELEMENT_TYPE value(d_queue.front());
1244/// d_queue.pop_front();
1245/// return value;
1246/// }
1247///
1248/// template <class ELEMENT_TYPE>
1249/// shared_ptr<bsl::deque<ELEMENT_TYPE> >
1250/// my_SafeQueue<ELEMENT_TYPE>::queue()
1251/// {
1252/// return shared_ptr<bsl::deque<ELEMENT_TYPE> >(
1253/// &d_queue,
1254/// MyMutexUnlockAndBroadcastDeleter(&d_mutex, &d_cond),
1255/// 0);
1256/// }
1257/// @endcode
1258///
1259/// ### Implementation Hiding {#bslstl_sharedptr-implementation-hiding}
1260///
1261///
1262/// `shared_ptr` refers to the template parameter type on which it is
1263/// instantiated "in name only". This allows for the instantiation of shared
1264/// pointers to incomplete or `void` types. This feature is useful for
1265/// constructing interfaces where returning a pointer to a shared object is
1266/// desirable, but in order to control access to the object its interface cannot
1267/// be exposed. The following examples demonstrate two techniques for achieving
1268/// this goal using a `shared_ptr`.
1269///
1270/// ### Example 7: Hidden Interfaces {#bslstl_sharedptr-example-7-hidden-interfaces}
1271///
1272///
1273/// Example 7 demonstrates the use of incomplete types to hide the interface of
1274/// a `my_Session` type. We begin by declaring the `my_SessionManager` `class`,
1275/// which allocates and manages `my_Session` objects. The interface (`.h`)
1276/// merely forward declares `my_Session`. The actual definition of the
1277/// interface is in the implementation (`.cpp`) file.
1278///
1279/// We forward-declare `my_Session` to be used (in name only) in the definition
1280/// of `my_SessionManager`:
1281/// @code
1282/// class my_Session;
1283/// @endcode
1284/// Next, we define the `my_SessionManager` class:
1285/// @code
1286/// class my_SessionManager {
1287///
1288/// // TYPES
1289/// typedef bsl::map<int, shared_ptr<my_Session> > HandleMap;
1290///
1291/// // DATA
1292/// bslmt::Mutex d_mutex;
1293/// HandleMap d_handles;
1294/// int d_nextSessionId;
1295/// bslma::Allocator *d_allocator_p;
1296///
1297/// @endcode
1298/// It is useful to have a designated name for the `shared_ptr` to `my_Session`:
1299/// @code
1300/// public:
1301/// // TYPES
1302/// typedef shared_ptr<my_Session> my_Handle;
1303/// @endcode
1304/// We need only a default constructor:
1305/// @code
1306/// // CREATORS
1307/// my_SessionManager(bslma::Allocator *allocator = 0);
1308/// @endcode
1309/// The 3 methods that follow construct a new session object and return a
1310/// `shared_ptr` to it. Callers can transfer the pointer, but they cannot
1311/// directly access the object's methods since they do not have access to its
1312/// interface.
1313/// @code
1314/// // MANIPULATORS
1315/// my_Handle openSession(const bsl::string& sessionName);
1316/// void closeSession(my_Handle handle);
1317///
1318/// // ACCESSORS
1319/// bsl::string getSessionName(my_Handle handle) const;
1320/// };
1321/// @endcode
1322/// Now, in the implementation of the code, we can define and implement the
1323/// `my_Session` class:
1324/// @code
1325/// class my_Session {
1326///
1327/// // DATA
1328/// bsl::string d_sessionName;
1329/// int d_handleId;
1330///
1331/// public:
1332/// // CREATORS
1333/// my_Session(const bsl::string& sessionName,
1334/// int handleId,
1335/// bslma::Allocator *basicAllocator = 0);
1336///
1337/// // ACCESSORS
1338/// int handleId() const;
1339/// const bsl::string& sessionName() const;
1340/// };
1341///
1342/// // CREATORS
1343/// inline
1344/// my_Session::my_Session(const bsl::string& sessionName,
1345/// int handleId,
1346/// bslma::Allocator *basicAllocator)
1347/// : d_sessionName(sessionName, basicAllocator)
1348/// , d_handleId(handleId)
1349/// {
1350/// }
1351///
1352/// // ACCESSORS
1353/// inline
1354/// int my_Session::handleId() const
1355/// {
1356/// return d_handleId;
1357/// }
1358///
1359/// inline
1360/// const bsl::string& my_Session::sessionName() const
1361/// {
1362/// return d_sessionName;
1363/// }
1364/// @endcode
1365/// The following shows the implementation of `my_SessionManager`. Note that
1366/// the interface for `my_Session` is not known:
1367/// @code
1368/// inline
1369/// my_SessionManager::my_SessionManager(bslma::Allocator *allocator)
1370/// : d_nextSessionId(1)
1371/// , d_allocator_p(bslma::Default::allocator(allocator))
1372/// {
1373/// }
1374///
1375/// inline
1376/// my_SessionManager::my_Handle
1377/// my_SessionManager::openSession(const bsl::string& sessionName)
1378/// {
1379/// bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
1380/// my_Handle session(new (*d_allocator_p) my_Session(sessionName,
1381/// d_nextSessionId++,
1382/// d_allocator_p));
1383/// d_handles[session->handleId()] = session;
1384/// return session;
1385/// }
1386///
1387/// inline
1388/// void my_SessionManager::closeSession(my_Handle handle)
1389/// {
1390/// bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
1391/// HandleMap::iterator it = d_handles.find(handle->handleId());
1392/// if (it != d_handles.end()) {
1393/// d_handles.erase(it);
1394/// }
1395/// }
1396///
1397/// inline
1398/// bsl::string my_SessionManager::getSessionName(my_Handle handle) const
1399/// {
1400/// return handle->sessionName();
1401/// }
1402/// @endcode
1403///
1404/// #### Example 8: Opaque Types {#bslstl_sharedptr-example-8-opaque-types}
1405///
1406///
1407/// In the above example, users could infer that `my_Handle` is a pointer to a
1408/// `my_Session` but have no way to directly access it's methods since the
1409/// interface is not exposed. In the following example, `my_SessionManager` is
1410/// re-implemented to provide an even more opaque session handle. In this
1411/// implementation, `my_Handle` is redefined using `void` providing no
1412/// indication of its implementation. Note that using `void` will require
1413/// casting in the implementation and, therefore, will be a little more
1414/// expensive.
1415///
1416/// In the interface, define `my_SessionManager` as follows:
1417/// @code
1418/// class my_SessionManager {
1419///
1420/// // TYPES
1421/// typedef bsl::map<int, shared_ptr<void> > HandleMap;
1422///
1423/// // DATA
1424/// bslmt::Mutex d_mutex;
1425/// HandleMap d_handles;
1426/// int d_nextSessionId;
1427/// bslma::Allocator *d_allocator_p;
1428/// @endcode
1429/// It is useful to have a name for the `void` `shared_ptr` handle.
1430/// @code
1431/// public:
1432/// // TYPES
1433/// typedef shared_ptr<void> my_Handle;
1434///
1435/// // CREATORS
1436/// my_SessionManager(bslma::Allocator *allocator = 0);
1437///
1438/// // MANIPULATORS
1439/// my_Handle openSession(const bsl::string& sessionName);
1440/// void closeSession(my_Handle handle);
1441///
1442/// // ACCESSORS
1443/// bsl::string getSessionName(my_Handle handle) const;
1444/// };
1445/// @endcode
1446/// Next we define the methods of `my_SessionManager`:
1447/// @code
1448/// // CREATORS
1449/// inline
1450/// my_SessionManager::my_SessionManager(bslma::Allocator *allocator)
1451/// : d_nextSessionId(1)
1452/// , d_allocator_p(bslma::Default::allocator(allocator))
1453/// {
1454/// }
1455///
1456/// // MANIPULATORS
1457/// inline
1458/// my_SessionManager::my_Handle
1459/// my_SessionManager::openSession(const bsl::string& sessionName)
1460/// {
1461/// bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
1462/// @endcode
1463/// Notice that `my_Handle`, which is a shared pointer to `void`, can be
1464/// transparently assigned to a shared pointer to a `my_Session` object. This
1465/// is because the `shared_ptr` interface allows shared pointers to types that
1466/// can be cast to one another to be assigned directly.
1467/// @code
1468/// my_Handle session(new (*d_allocator_p) my_Session(sessionName,
1469/// d_nextSessionId++,
1470/// d_allocator_p));
1471/// shared_ptr<my_Session> myhandle =
1472/// bslstl::SharedPtrUtil::staticCast<my_Session>(session);
1473/// d_handles[myhandle->handleId()] = session;
1474/// return session;
1475/// }
1476///
1477/// inline
1478/// void my_SessionManager::closeSession(my_Handle handle)
1479/// {
1480/// bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
1481/// @endcode
1482/// Perform a static cast from `shared_ptr<void>` to `shared_ptr<my_Session>`.
1483/// @code
1484/// shared_ptr<my_Session> myhandle =
1485/// bslstl::SharedPtrUtil::staticCast<my_Session>(handle);
1486/// @endcode
1487/// Test to make sure that the pointer is non-null before using `myhandle`:
1488/// @code
1489/// if (!myhandle.get()) {
1490/// return; // RETURN
1491/// }
1492///
1493/// HandleMap::iterator it = d_handles.find(myhandle->handleId());
1494/// if (it != d_handles.end()) {
1495/// d_handles.erase(it);
1496/// }
1497/// }
1498///
1499/// bsl::string my_SessionManager::getSessionName(my_Handle handle) const
1500/// {
1501/// shared_ptr<my_Session> myhandle =
1502/// bslstl::SharedPtrUtil::staticCast<my_Session>(handle);
1503///
1504/// if (!myhandle.get()) {
1505/// return bsl::string();
1506/// } else {
1507/// return myhandle->sessionName();
1508/// }
1509/// }
1510/// @endcode
1511/// @}
1512/** @} */
1513/** @} */
1514
1515/** @addtogroup bsl
1516 * @{
1517 */
1518/** @addtogroup bslstl
1519 * @{
1520 */
1521/** @addtogroup bslstl_sharedptr
1522 * @{
1523 */
1524
1525#include <bslscm_version.h>
1526
1527#include <bslstl_compare.h>
1528#include <bslstl_hash.h>
1529#include <bslstl_pair.h>
1532
1534#include <bslalg_arrayprimitives.h>
1535
1536#include <bslma_allocator.h>
1537#include <bslma_allocatortraits.h>
1538#include <bslma_default.h>
1539#include <bslma_managedptr.h>
1540#include <bslma_pointerutil.h>
1543#include <bslma_sharedptrrep.h>
1544#include <bslma_bslallocator.h>
1545
1547#include <bslmf_addpointer.h>
1548#include <bslmf_conditional.h>
1549#include <bslmf_enableif.h>
1551#include <bslmf_integralconstant.h>
1552#include <bslmf_isarray.h>
1554#include <bslmf_isconvertible.h>
1555#include <bslmf_isfunction.h>
1556#include <bslmf_ispointer.h>
1557#include <bslmf_movableref.h>
1559#include <bslmf_referencewrapper.h>
1560#include <bslmf_removeextent.h>
1561#include <bslmf_util.h> // `Util::declval`
1562
1563#include <bsls_assert.h>
1564#include <bsls_compilerfeatures.h>
1565#include <bsls_deprecatefeature.h>
1566#include <bsls_keyword.h>
1567#include <bsls_libraryfeatures.h>
1568#include <bsls_nullptr.h>
1569#include <bsls_platform.h>
1570#include <bsls_unspecifiedbool.h>
1571#include <bsls_util.h> // `forward<T>(V)` for C++11
1572
1573#include <functional> // use `std::less` to order pointers
1574#include <memory> // `std::auto_ptr`, `std::unique_ptr`
1575#include <ostream> // `std::basic_ostream`
1576
1577#include <stddef.h> // `size_t`, `ptrdiff_t`
1578
1579#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1580#include <type_traits> // std::extent
1581#endif
1582
1583#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
1584#include <bsls_nativestd.h>
1585#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
1586
1587#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1588// clang-format off
1589// Include version that can be compiled with C++03
1590// Generated on Mon Jan 13 08:31:39 2025
1591// Command line: sim_cpp11_features.pl bslstl_sharedptr.h
1592
1593# define COMPILING_BSLSTL_SHAREDPTR_H
1594# include <bslstl_sharedptr_cpp03.h>
1595# undef COMPILING_BSLSTL_SHAREDPTR_H
1596
1597// clang-format on
1598#else
1599
1600#if defined(BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC)
1601 // Here and throughout the file wherever `auto_ptr` is used, suspend
1602 // GCC reporting of deprecated declarations since the use of `auto_ptr`
1603 // in this standard interface is required.
1604# pragma GCC diagnostic push
1605# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1606#endif
1607
1608#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS)
1609# define BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS 1
1610
1611# if BSLS_PLATFORM_CMP_VERSION >= 1910 && \
1612 BSLS_PLATFORM_CMP_VERSION < 1920 && \
1613 BSLS_COMPILERFEATURES_CPLUSPLUS >= 201703L
1614// Visual Studio 2017 in C++17 mode crashes with an internal compiler error on
1615// the shared pointer SFINAE code. See {DRQS 148281696}.
1616# undef BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS
1617# endif
1618
1619// If the macro `BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS` is defined, then a
1620// conforming C++11 compiler will define the constructors in this component in
1621// such a way that they will not be selected during overload resolution unless
1622// they would instantiate correctly. This means that code depending on the
1623// result of `is_constructible` and similar traits will have the expected
1624// behavior. There is no attempt to support this feature in C++03.
1625//
1626// Support for SFINAE-queries on the constructability of a `shared_ptr` depend
1627// on a variety of C++11 language features, including "expression-SFINAE".
1628// However, the main language feature that enables SFINAE elimination of a
1629// constructor is the ability to use default template arguments in a function
1630// template. It is significantly preferred to use the template parameter list,
1631// rather than add additional default arguments to the constructor signatures,
1632// as there are so many constructor overloads in this component that there is a
1633// real risk of introducing ambiguities that would need to be worked around.
1634// Therefore, the `BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS` macro
1635// serves as our proxy for whether SFINAE-constructors are enabled in this
1636// component. Note that the MSVC 2015 compiler almost supported
1637// "expression-SFINAE", to the extent that it works for this component, unlike
1638// earlier versions of that compiler. We therefore make a special version-test
1639// on Microsoft in addition to the feature testing.
1640#endif
1641
1642#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
1643// Note the intentional comma in the first line of the definition of each
1644// macro, which allows these macros to be applied incrementally, even when the
1645// alternate definition is empty. This avoids the problem of introducing new
1646// template parameters along with the macros in the non-SFINAE-supporting case
1647// below.
1648# define BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE , \
1649 typename enable_if< \
1650 BloombergLP::bslstl::SharedPtr_IsPointerConvertible< \
1651 CONVERTIBLE_TYPE, \
1652 ELEMENT_TYPE>::value>::type * \
1653 = nullptr
1654
1655# define BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE , \
1656 typename enable_if< \
1657 BloombergLP::bslstl::SharedPtr_IsPointerConvertible< \
1658 CONVERTIBLE_TYPE, \
1659 ELEMENT_TYPE>::value>::type *
1660
1661
1662# define BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE , \
1663 typename enable_if< \
1664 BloombergLP::bslstl::SharedPtr_IsPointerCompatible< \
1665 COMPATIBLE_TYPE, \
1666 ELEMENT_TYPE>::value>::type * \
1667 = nullptr
1668
1669# define BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE , \
1670 typename enable_if< \
1671 BloombergLP::bslstl::SharedPtr_IsPointerCompatible< \
1672 COMPATIBLE_TYPE, \
1673 ELEMENT_TYPE>::value>::type *
1674
1675
1676# define BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(FUNCTOR, ARGUMENT) , \
1677 typename enable_if< \
1678 BloombergLP::bslstl::SharedPtr_IsCallable <FUNCTOR, \
1679 ARGUMENT *>::k_VALUE || \
1680 BloombergLP::bslstl::SharedPtr_IsFactoryFor<FUNCTOR, \
1681 ARGUMENT>::k_VALUE>::type * \
1682 = nullptr
1683
1684# define BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(FUNCTOR, ARGUMENT) , \
1685 typename enable_if< \
1686 BloombergLP::bslstl::SharedPtr_IsCallable <FUNCTOR, \
1687 ARGUMENT *>::k_VALUE || \
1688 BloombergLP::bslstl::SharedPtr_IsFactoryFor<FUNCTOR, \
1689 ARGUMENT >::k_VALUE>::type *
1690
1691
1692# define BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(FUNCTOR) , \
1693 typename enable_if< \
1694 BloombergLP::bslstl::SharedPtr_IsCallable <FUNCTOR, \
1695 nullptr_t>::k_VALUE || \
1696 BloombergLP::bslstl::SharedPtr_IsNullableFactory< \
1697 FUNCTOR>::k_VALUE>::type * = nullptr
1698
1699# define BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(FUNCTOR) , \
1700 typename enable_if< \
1701 BloombergLP::bslstl::SharedPtr_IsCallable <FUNCTOR, \
1702 nullptr_t>::k_VALUE || \
1703 BloombergLP::bslstl::SharedPtr_IsNullableFactory< \
1704 FUNCTOR>::k_VALUE>::type *
1705#else
1706// Do not attempt to support SFINAE in constructors in a C++03 compiler
1707# define BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
1708# define BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE
1709
1710# define BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE
1711# define BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE
1712
1713# define BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(FUNCTOR, ARGUMENT)
1714# define BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(FUNCTOR, ARGUMENT)
1715
1716# define BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(FUNCTOR)
1717# define BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(FUNCTOR)
1718#endif // BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS
1719
1720// Some SFINAE checks, when enabled, make use of discarded-value expressions
1721// (as the left-hand side of a comma operator). Clang compilers based on
1722// versions of LLVM earlier than 12 contain a bug in which substitution
1723// failures are not caught in discarded-value expressions when used in SFINAE
1724// contexts (this includes Clang 11 and earlier, and Apple Clang 13 and
1725// earlier). In order to ensure that these compilers catch substitution
1726// failures in such expressions, this component does not discard them. Note
1727// that this is dangerous, because not discarding the expression allows the
1728// possibility that the comma operator will be overloaded on the type of the
1729// expression, and so it is preferable to discard the expression where
1730// possible.
1731#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
1732#if !defined(BSLS_PLATFORM_CMP_CLANG) || \
1733 !defined(__apple_build_version__) && BSLS_PLATFORM_CMP_VERSION >= \
1734 120000 || \
1735 defined(__apple_build_version__) && BSLS_PLATFORM_CMP_VERSION > 130000
1736# define BSLSTL_SHAREDPTR_SFINAE_DISCARD(EXPRESSION) \
1737 static_cast<void>(EXPRESSION)
1738# else
1739# define BSLSTL_SHAREDPTR_SFINAE_DISCARD(EXPRESSION) \
1740 (EXPRESSION)
1741# endif
1742#endif
1743
1744
1745namespace bslstl {
1746
1747/// This `struct` is for internal use only, providing a tag for `shared_ptr`
1748/// constructors to recognize that a passed `SharedPtrRep` was obtained from
1749/// an existing `shared_ptr` object.
1750///
1751/// See @ref bslstl_sharedptr
1754
1755/// Forward declaration of `SharedPtr_ImpUtil`. This is needed because this
1756/// struct is a friend of @ref enable_shared_from_this in the `bsl` namespace.
1757struct SharedPtr_ImpUtil;
1758
1759#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
1760/// Forward declaration of component-private type trait to indicate whether
1761/// an object of (template parameter) type `FUNCTOR` can be called as a
1762/// function with an argument of (template parameter) type `ARG`
1763template <class FUNCTOR, class ARG>
1764struct SharedPtr_IsCallable;
1765
1766/// Forward declaration of component-private type trait to indicate whether
1767/// a pointer to a `FACTORY` has a `deleteObject` member that can be called
1768/// as `factory->deleteObject((ARG *)p)`.
1769template <class FACTORY, class ARG>
1770struct SharedPtr_IsFactoryFor;
1771
1772/// Forward declaration of component-private type trait to indicate whether
1773/// a pointer to a `FACTORY` has a `deleteObject` member that can be called
1774/// as `factory->deleteObject((ARG *)p)`.
1775template <class FACTORY>
1776struct SharedPtr_IsNullableFactory;
1777
1778/// Forward declaration of component-private type trait to indicate whether
1779/// a pointer to a `SOURCE_TYPE` can be converted to a pointer to a
1780/// `DEST_TYPE`. [util.smartptr.shared.const]/8 says "either DEST_TYPE is
1781/// U[N] and SOURCE_TYPE(*)[N] is convertible to DEST_TYPE*, or DEST_TYPE is
1782/// U[] and SOURCE_TYPE(*)[] is convertible to DEST_TYPE*".
1783template <class SOURCE_TYPE, class DEST_TYPE>
1784struct SharedPtr_IsPointerConvertible;
1785
1786/// Forward declaration of component-private type trait to indicate whether
1787/// a pointer to a `SOURCE_TYPE` is compatible with a pointer to
1788/// `DEST_TYPE`. [util.smartptr.shared]/5 says: "for the purposes of ...,
1789/// a pointer type SOURCE_TYPE* is said to be compatible with a pointer type
1790/// DEST_TYPE* when either SOURCE_TYPE* is convertible to DEST_TYPE* or
1791/// SOURCE_TYPE is U[N] and DEST_TYPE is cv U[]."
1792template <class SOURCE_TYPE, class DEST_TYPE>
1793struct SharedPtr_IsPointerCompatible;
1794
1795#endif
1796
1797} // close package namespace
1798
1799
1800namespace bsl {
1801
1802template<class ELEMENT_TYPE>
1803class enable_shared_from_this;
1804
1805template <class ELEMENT_TYPE>
1806class shared_ptr;
1807
1808template <class ELEMENT_TYPE>
1809class weak_ptr;
1810
1811 // ================
1812 // class shared_ptr
1813 // ================
1814
1815/// This class provides a thread-safe reference-counted "smart pointer" to
1816/// support "shared ownership" of objects: a shared pointer ensures that the
1817/// shared object is destroyed, using the appropriate deletion method, only
1818/// when there are no shared references to it. The object (of template
1819/// parameter type `ELEMENT_TYPE`) referred to by a shared pointer may be
1820/// accessed directly using the `->` operator, or the dereference operator
1821/// (operator `*`) can be used to obtain a reference to that object.
1822///
1823///
1824/// \note Note that the object referred to by a shared pointer representation is
1825/// usually the same as the object referred to by that shared pointer (of
1826/// the same `ELEMENT_TYPE`), but this need not always be true in the
1827/// presence of conversions or "aliasing": the object referred to (of
1828/// template parameter type `ELEMENT_TYPE`) by the shared pointer may differ
1829/// from the object of type `COMPATIBLE_TYPE` (see the "Aliasing" section in
1830/// the component-level documentation) referred to by the shared pointer
1831/// representation.
1832///
1833/// More generally, this class supports a complete set of *in*-*core*
1834/// pointer semantic operations.
1835///
1836/// See @ref bslstl_sharedptr
1837template <class ELEMENT_TYPE>
1839
1840 public:
1841 // TRAITS
1844
1845 // TYPES
1846
1847 /// For shared pointers to non-array types, @ref element_type is an alias
1848 /// to the `ELEMENT_TYPE` template parameter. Otherwise, it is an alias
1849 /// to the type contained in the array.
1851
1852 /// @ref weak_type is an alias to a weak pointer with the same element type
1853 /// as this `shared_ptr`.
1855
1856 private:
1857 // DATA
1858 element_type *d_ptr_p; // pointer to the shared object
1859
1860 BloombergLP::bslma::SharedPtrRep *d_rep_p; // pointer to the representation
1861 // object that manages the
1862 // shared object
1863
1864 // PRIVATE TYPES
1865
1866 /// `SelfType` is an alias to this `class`, for compilers that do not
1867 /// recognize plain `shared_ptr`.
1868 typedef shared_ptr<ELEMENT_TYPE> SelfType;
1869
1870 typedef typename BloombergLP::bsls::UnspecifiedBool<shared_ptr>::BoolType
1871 BoolType;
1872
1873 // FRIENDS
1874 template <class COMPATIBLE_TYPE>
1875 friend class shared_ptr;
1876
1878
1879 private:
1880 // PRIVATE CLASS METHODS
1881
1882 /// Return the specified `rep`.
1883 template <class INPLACE_REP>
1884 static BloombergLP::bslma::SharedPtrRep *makeInternalRep(
1885 ELEMENT_TYPE *,
1886 INPLACE_REP *,
1887 BloombergLP::bslma::SharedPtrRep *rep);
1888
1889 /// Return the address of a new out-of-place representation for a shared
1890 /// pointer that manages the specified `ptr` and uses the specified
1891 /// `allocator` to destroy the object pointed to by `ptr`. Use
1892 /// `allocator` to supply memory.
1893 template <class COMPATIBLE_TYPE, class ALLOCATOR>
1894 static BloombergLP::bslma::SharedPtrRep *makeInternalRep(
1895 COMPATIBLE_TYPE *ptr,
1896 ALLOCATOR *,
1897 BloombergLP::bslma::Allocator *allocator);
1898
1899 /// Return the address of a new out-of-place representation for a shared
1900 /// pointer that manages the specified `ptr` and uses the specified
1901 /// `deleter` to destroy the object pointed to by `ptr`. Use the
1902 /// currently installed default allocator to supply memory.
1903 template <class COMPATIBLE_TYPE, class DELETER>
1904 static BloombergLP::bslma::SharedPtrRep *makeInternalRep(
1905 COMPATIBLE_TYPE *ptr,
1906 DELETER *deleter,
1907 ...);
1908
1909 public:
1910 // CREATORS
1911
1912 /// Create an empty shared pointer, i.e., a shared pointer with no
1913 /// representation that does not refer to any object and has no
1914 /// deleter.
1917
1918 /// Create an empty shared pointer, i.e., a shared pointer with no
1919 /// representation that does not refer to any object and has no
1920 /// deleter.
1923
1924 /// Create a shared pointer that manages a modifiable object of
1925 /// (template parameter) type `CONVERTIBLE_TYPE` and refers to the
1926 /// specified `(ELEMENT_TYPE *)ptr`. The currently installed default
1927 /// allocator is used to allocate and deallocate the internal
1928 /// representation of the shared pointer. When all references have been
1929 /// released, the object pointed to by the managed pointer will be
1930 /// destroyed by a call to `delete ptr`. If `CONVERTIBLE_TYPE *` is not
1931 /// implicitly convertible to `ELEMENT_TYPE *`, then a compiler
1932 /// diagnostic will be emitted indicating the error. If `ptr` is 0,
1933 /// then this shared pointer will still allocate an internal
1934 /// representation to share ownership of that empty state, which will be
1935 /// reclaimed when the last reference is destroyed. If an exception is
1936 /// thrown allocating storage for the representation, then `delete ptr` will be called.
1937 ///
1938 /// \note Note that if `ptr` is a null-pointer constant, the
1939 /// compiler will actually select the `shared_ptr(bsl::nullptr_t)`
1940 /// constructor, resulting in an empty shared pointer.
1941 template <class CONVERTIBLE_TYPE
1943 explicit shared_ptr(CONVERTIBLE_TYPE *ptr);
1944
1945 /// Create a shared pointer that manages a modifiable object of
1946 /// (template parameter) type `CONVERTIBLE_TYPE` and refers to the
1947 /// specified `ptr` cast to a pointer to the (template parameter) type
1948 /// `ELEMENT_TYPE`. If the specified `basicAllocator` is not 0, then
1949 /// `basicAllocator` is used to allocate and deallocate the internal
1950 /// representation of the shared pointer and to destroy the shared
1951 /// object when all references have been released; otherwise, the
1952 /// currently installed default allocator is used. If
1953 /// `CONVERTIBLE_TYPE *` is not implicitly convertible to
1954 /// `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted
1955 /// indicating the error. If `ptr` is 0, then this shared pointer will
1956 /// still allocate an internal representation to share ownership of that
1957 /// empty state, which will be reclaimed when the last reference is destroyed.
1958 ///
1959 /// \note Note that if `ptr` is a null-pointer constant, the
1960 /// compiler will actually select the
1961 /// `shared_ptr(bsl::nullptr_t, BloombergLP::bslma::Allocator *)` constructor, resulting in an empty shared pointer.
1962 ///
1963 /// \note Note that if
1964 /// `basicAllocator` is a pointer to a class derived from
1965 /// `bslma::Allocator`, the compiler will actually select the following
1966 /// (more general) constructor that has the same behavior:
1967 /// @code
1968 /// template <class CONVERTIBLE_TYPE, class DELETER>
1969 /// shared_ptr(CONVERTIBLE_TYPE *ptr, DELETER * deleter);
1970 /// @endcode
1971 template <class CONVERTIBLE_TYPE
1973 shared_ptr(CONVERTIBLE_TYPE *ptr,
1974 BloombergLP::bslma::Allocator *basicAllocator);
1975
1976 /// Create a shared pointer that takes ownership of the specified `rep`
1977 /// and refers to the modifiable object at the specified `ptr` address.
1978 /// The number of references to `rep` is *NOT* incremented.
1979 ///
1980 /// \note Note that if `rep` is a pointer to a class derived from
1981 /// `BloombergLP::bslma::SharedPtrRep`, the compiler will actually
1982 /// select the following (more general) constructor that has the same
1983 /// behavior:
1984 /// @code
1985 /// template <class COMPATIBLE_TYPE, class DELETER>
1986 /// shared_ptr(COMPATIBLE_TYPE *ptr, DELETER * deleter);
1987 /// @endcode
1988 shared_ptr(element_type *ptr, BloombergLP::bslma::SharedPtrRep *rep);
1989
1990 /// Create a shared pointer that takes ownership of the specified `rep`
1991 /// and refers to the modifiable object at the specified `ptr` address.
1992 /// The number of references to `rep` is *NOT* incremented.
1993 ///
1994 /// \pre The behavior is undefined unless `rep` was previously obtained from an
1995 /// existing `shared_ptr`, `rep->disposeObject` has not been called, and `rep->numReferences() > 0`.
1996 ///
1997 /// \note Note that this constructor is intended
1998 /// for use by `weak_ptr::lock`, and it would be surprising to find
1999 /// another client. This solves an obscure problem that arises from
2000 /// unusual use of classes derived from @ref enable_shared_from_this .
2001 /// Further note that the caller is responsible for incrementing the
2002 /// `numReferences` count prior to calling this constructor, in order to
2003 /// maintain a consistent reference count when this `shared_ptr` object
2004 /// releases the shared object from its management.
2005 shared_ptr(ELEMENT_TYPE *ptr,
2006 BloombergLP::bslma::SharedPtrRep *rep,
2007 BloombergLP::bslstl::SharedPtr_RepFromExistingSharedPtr);
2008
2009 /// Create a shared pointer that manages a modifiable object of
2010 /// (template parameter) type `CONVERTIBLE_TYPE`, refers to the
2011 /// specified `ptr` cast to a pointer to the (template parameter) type
2012 /// `ELEMENT_TYPE`, and uses the specified `deleter` to delete the
2013 /// shared object when all references have been released. Use the
2014 /// currently installed default allocator to allocate and deallocate the
2015 /// internal representation of the shared pointer, unless `DELETER` is a
2016 /// class derived from either `bslma::Allocator` or
2017 /// `bslma::SharedPtrRep`; if `DELETER` is a class derived from
2018 /// `bslma::allocator`, create a shared pointer as if calling the
2019 /// constructor:
2020 /// @code
2021 /// template <class CONVERTIBLE_TYPE>
2022 /// shared_ptr(CONVERTIBLE_TYPE *ptr,
2023 /// BloombergLP::bslma::Allocator *basicAllocator);
2024 /// @endcode
2025 /// If `DELETER` is a class derived from `bslma::SharedPtrRep`, create a
2026 /// shared pointer as if calling the constructor:
2027 /// @code
2028 /// shared_ptr(ELEMENT_TYPE *ptr,
2029 /// BloombergLP::bslma::SharedPtrRep *rep);
2030 /// @endcode
2031 /// If `DELETER` does not derive from either `bslma::Allocator` or
2032 /// `BloombergLP::bslma::SharedPtrRep`, then `deleter` shall be a
2033 /// pointer to a factory object that exposes a member function that can
2034 /// be invoked as `deleteObject(ptr)` that will be called to destroy the
2035 /// object at the `ptr` address (i.e., `deleter->deleteObject(ptr)` will
2036 /// be called to delete the shared object). (See the "Deleters" section
2037 /// in the component-level documentation.) If `CONVERTIBLE_TYPE *` is
2038 /// not implicitly convertible to `ELEMENT_TYPE *`, then a compiler
2039 /// diagnostic will be emitted indicating the error. If `ptr` is 0,
2040 /// then the null pointer will be reference counted, and the deleter
2041 /// will be called when the last reference is destroyed. If an
2042 /// exception is thrown when allocating storage for the internal representation, then `deleter(ptr)` will be called.
2043 ///
2044 /// \note Note that this
2045 /// method is a BDE extension and not part of the C++ standard
2046 /// interface.
2047 template <class CONVERTIBLE_TYPE,
2048 class DELETER
2050 BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(DELETER *, CONVERTIBLE_TYPE)>
2051 shared_ptr(CONVERTIBLE_TYPE *ptr, DELETER *deleter);
2052
2053 /// Create a shared pointer that manages a modifiable object of
2054 /// (template parameter) type `CONVERTIBLE_TYPE`, refers to the
2055 /// specified `(ELEMENT_TYPE *)ptr`, and uses the specified `deleter` to
2056 /// delete the shared object when all references have been released.
2057 /// Optionally specify a `basicAllocator` to allocate and deallocate the
2058 /// internal representation of the shared pointer (including a copy of
2059 /// `deleter`). If `basicAllocator` is 0, the currently installed
2060 /// default allocator is used. `DELETER` shall be either a function
2061 /// pointer or a "factory" deleter that may be invoked to destroy the
2062 /// object referred to by a single argument of type `CONVERTIBLE_TYPE *`
2063 /// (i.e., `deleter(ptr)` or `deleter->deleteObject(ptr)` will be called
2064 /// to destroy the shared object). (See the "Deleters" section in the
2065 /// component-level documentation.) If `CONVERTIBLE_TYPE *` is not
2066 /// implicitly convertible to `ELEMENT_TYPE *`, then this constructor
2067 /// will not be selected by overload resolution. If `ptr` is 0, then
2068 /// the null pointer will be reference counted, and `deleter(ptr)` will
2069 /// be called when the last reference is destroyed. If an exception is
2070 /// thrown when allocating storage for the internal representation, then `deleter(ptr)` will be called.
2071 ///
2072 /// \pre The behavior is undefined unless the
2073 /// constructor making a copy of `deleter` does not throw an exception.
2074 template <class CONVERTIBLE_TYPE,
2075 class DELETER
2077 BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
2078 shared_ptr(CONVERTIBLE_TYPE *ptr,
2079 DELETER deleter,
2080 BloombergLP::bslma::Allocator *basicAllocator = 0);
2081
2082 /// Create a shared pointer that manages a modifiable object of
2083 /// (template parameter) type `CONVERTIBLE_TYPE`, refers to the
2084 /// specified `ptr` cast to a pointer to the (template parameter) type
2085 /// `ELEMENT_TYPE`, and uses the specified `deleter` to delete the
2086 /// shared object when all references have been released. Use the
2087 /// specified `basicAllocator` to allocate and deallocate the internal
2088 /// representation of the shared pointer (including a copy of the
2089 /// `deleter`). The (template parameter) type `DELETER` shall be either
2090 /// a function pointer or a function-like deleter that may be invoked to
2091 /// destroy the object referred to by a single argument of type
2092 /// `CONVERTIBLE_TYPE *` (i.e., `deleter(ptr)` will be called to destroy
2093 /// the shared object). (See the "Deleters" section in the component-
2094 /// level documentation.) The (template parameter) type `ALLOCATOR`
2095 /// shall satisfy the Allocator requirements of the C++ standard (C++11
2096 /// 17.6.3.5, [allocator.requirements]). If `CONVERTIBLE_TYPE *` is not
2097 /// implicitly convertible to `ELEMENT_TYPE *`, then a compiler
2098 /// diagnostic will be emitted indicating the error. If `ptr` is 0,
2099 /// then the null pointer will be reference counted, and `deleter(ptr)`
2100 /// will be called when the last reference is destroyed. If an
2101 /// exception is thrown when allocating storage for the internal
2102 /// representation, then `deleter(ptr)` will be called.
2103 ///
2104 /// \pre The behavior is undefined unless the constructor making a copy of `deleter` does not throw an exception.
2105 ///
2106 /// \note Note that the final dummy parameter is a simple
2107 /// SFINAE check that the (template parameter) `ALLOCATOR` type probably
2108 /// satisfies the standard allocator requirements; in particular, it
2109 /// will not match pointer types, so any pointers to `bslma::Allocator`
2110 /// derived classes will dispatch to the constructor above this, and not
2111 /// be greedily matched to a generic type parameter.
2112 template <class CONVERTIBLE_TYPE,
2113 class DELETER,
2114 class ALLOCATOR
2116 BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
2117 shared_ptr(CONVERTIBLE_TYPE *ptr,
2118 DELETER deleter,
2119 ALLOCATOR basicAllocator,
2120 typename ALLOCATOR::value_type * = 0);
2121
2122 /// Create an empty shared pointer. The specified `nullPointerLiteral` and `basicAllocator` are not used.
2123 ///
2124 /// \note Note that use of this
2125 /// constructor is equivalent to calling the default constructor.
2126 shared_ptr(nullptr_t nullPointerLiteral,
2127 BloombergLP::bslma::Allocator *basicAllocator);
2128
2129 /// Create a shared pointer that reference-counts the null pointer, and
2130 /// calls the specified `deleter` with a null pointer (i.e., invokes
2131 /// `deleter((ELEMENT_TYPE *)0)`) when the last shared reference is
2132 /// destroyed. The specified `nullPointerLiteral` is not used.
2133 /// Optionally specify a `basicAllocator` to allocate and deallocate the
2134 /// internal representation of the shared pointer (including a copy of
2135 /// `deleter`). If `basicAllocator` is 0, the currently installed
2136 /// default allocator is used. If an exception is thrown when
2137 /// allocating storage for the internal representation, then
2138 /// `deleter((ELEMENT_TYPE *)0)` will be called.
2139 ///
2140 /// \pre The behavior is undefined unless `deleter` can be called with a null pointer, and
2141 /// unless the constructor making a copy of `deleter` does not throw an
2142 /// exception.
2143 template <class DELETER
2145 shared_ptr(nullptr_t nullPointerLiteral,
2146 DELETER deleter,
2147 BloombergLP::bslma::Allocator *basicAllocator = 0);
2148
2149 /// Create a shared pointer that reference-counts the null pointer,
2150 /// calls the specified `deleter` with a null pointer (i.e., invokes
2151 /// `deleter((ELEMENT_TYPE *)0)`) when the last shared reference is
2152 /// destroyed, and uses the specified `basicAllocator` to allocate and
2153 /// deallocate the internal representation of the shared pointer
2154 /// (including a copy of the `deleter`). The (template parameter) type
2155 /// `DELETER` shall be either a function pointer or a function-like
2156 /// deleter (See the "Deleters" section in the component- level
2157 /// documentation). The (template parameter) type `ALLOCATOR` shall
2158 /// satisfy the Allocator requirements of the C++ standard (C++11
2159 /// 17.6.3.5, [allocator.requirements]). The specified
2160 /// `nullPointerLiteral` is not used. If an exception is thrown when
2161 /// allocating storage for the internal representation, then
2162 /// `deleter((ELEMENT_TYPE *)0)` will be called.
2163 ///
2164 /// \pre The behavior is undefined unless `deleter` can be called with a null pointer, and
2165 /// unless the constructor making a copy of `deleter` does not throw an exception.
2166 ///
2167 /// \note Note that the final dummy parameter is a simple SFINAE
2168 /// check that the `ALLOCATOR` type probably satisfies the standard
2169 /// allocator requirements; in particular, it will not match pointer
2170 /// types, so any pointers to `bslma::Allocator` derived classes will
2171 /// dispatch to the constructor above this, and not be greedily matched
2172 /// to a generic type parameter.
2173 template <class DELETER, class ALLOCATOR
2175 shared_ptr(nullptr_t nullPointerLiteral,
2176 DELETER deleter,
2177 ALLOCATOR basicAllocator,
2178 typename ALLOCATOR::value_type * = 0);
2179
2180 /// Create a shared pointer that takes over the management of the
2181 /// modifiable object (if any) previously managed by the specified
2182 /// `managedPtr` to the (template parameter) type `CONVERTIBLE_TYPE`,
2183 /// and that refers to `(ELEMENT_TYPE *)managedPtr.ptr()`. The deleter
2184 /// used in the `managedPtr` will be used to destroy the shared object
2185 /// when all references have been released. Optionally specify a
2186 /// `basicAllocator` used to allocate and deallocate the internal
2187 /// representation of the shared pointer. If `basicAllocator` is 0, the
2188 /// currently installed default allocator is used. If
2189 /// `CONVERTIBLE_TYPE *` is not implicitly convertible to
2190 /// `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2191 ///
2192 /// \note Note that if `managedPtr` is empty, then an
2193 /// empty shared pointer is created and `basicAllocator` is ignored.
2194 /// Also note that if `managedPtr` owns a reference to another shared
2195 /// object (due to a previous call to `shared_ptr<T>::managedPtr`) then
2196 /// no memory will be allocated, and this `shared_ptr` will adopt the
2197 /// `ManagedPtr`s ownership of that shared object.
2198 template <class CONVERTIBLE_TYPE
2201 BloombergLP::bslma::ManagedPtr<CONVERTIBLE_TYPE> managedPtr,
2202 BloombergLP::bslma::Allocator *basicAllocator = 0);
2203 // IMPLICIT
2204
2205#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
2206 /// Create a shared pointer that takes over the management of the
2207 /// modifiable object previously managed by the specified `autoPtr` to
2208 /// the (template parameter) type `CONVERTIBLE_TYPE`, and that refers to
2209 /// `(ELEMENT_TYPE *)autoPtr.get()`. `delete(autoPtr.release())` will
2210 /// be called to destroy the shared object when all references have been
2211 /// released. Optionally specify a `basicAllocator` used to allocate
2212 /// and deallocate the internal representation of the shared pointer.
2213 /// If `basicAllocator` is 0, the currently installed default allocator
2214 /// is used. If `CONVERTIBLE_TYPE *` is not implicitly convertible to
2215 /// `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted
2216 /// indicating the error.
2217 template <class CONVERTIBLE_TYPE
2219 explicit shared_ptr(std::auto_ptr<CONVERTIBLE_TYPE>& autoPtr,
2220 BloombergLP::bslma::Allocator *basicAllocator = 0);
2221
2222 /// Create a shared pointer that takes over the management of the
2223 /// modifiable object of (template parameter) type `COMPATIBLE_TYPE`
2224 /// previously managed by the auto pointer object that the specified
2225 /// `autoRef` refers to; this shared pointer refers to the same object
2226 /// that it manages, and `delete(get())` will be called to destroy the
2227 /// shared object when all references have been released. Optionally
2228 /// specify a `basicAllocator` used to allocate and deallocate the
2229 /// internal representation of the shared pointer. If `basicAllocator`
2230 /// is 0, the currently installed default allocator is used. This
2231 /// function does not exist unless `COMPATIBLE_TYPE *` is convertible to
2232 /// `ELEMENT_TYPE *`.
2233 explicit shared_ptr(std::auto_ptr_ref<ELEMENT_TYPE> autoRef,
2234 BloombergLP::bslma::Allocator *basicAllocator = 0);
2235#endif
2236
2237#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
2238# if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
2239 /// Create a shared pointer that takes over the management of the
2240 /// modifiable object previously managed by the specified `adoptee` to
2241 /// the (template parameter) type `COMPATIBLE_TYPE`, and that refers to
2242 /// `(ELEMENT_TYPE *)autoPtr.get()`. `delete(autoPtr.release())` will
2243 /// be called to destroy the shared object when all references have been
2244 /// released. Optionally specify a `basicAllocator` used to allocate
2245 /// and deallocate the internal representation of the shared pointer.
2246 /// If `basicAllocator` is 0, the currently installed default allocator
2247 /// is used. This function does not exist unless
2248 /// `unique_ptr<COMPATIBLE_TYPE, DELETER>::pointer` is convertible to `ELEMENT_TYPE *`.
2249 ///
2250 /// \note Note that this function creates a `shared_ptr`
2251 /// with an unspecified deleter type that has satisfies this contract,
2252 /// which might not be the deleter of `rhs`, which is specified by the
2253 /// C++ standard.
2254 template <class COMPATIBLE_TYPE,
2255 class UNIQUE_DELETER,
2256 typename enable_if<is_convertible<
2257 typename std::unique_ptr<COMPATIBLE_TYPE,
2258 UNIQUE_DELETER>::pointer,
2259 ELEMENT_TYPE *>::value>::type * = nullptr>
2260 shared_ptr(std::unique_ptr<COMPATIBLE_TYPE,
2261 UNIQUE_DELETER>&& adoptee,
2262 BloombergLP::bslma::Allocator *basicAllocator = 0);
2263 // IMPLICIT
2264# else
2265 /// Create a shared pointer that takes over the management of the
2266 /// modifiable object previously managed by the specified `adoptee` to
2267 /// the (template parameter) type `COMPATIBLE_TYPE`, and that refers to
2268 /// `(ELEMENT_TYPE *)autoPtr.get()`. `delete(autoPtr.release())` will
2269 /// be called to destroy the shared object when all references have been
2270 /// released. Optionally specify a `basicAllocator` used to allocate
2271 /// and deallocate the internal representation of the shared pointer.
2272 /// If `basicAllocator` is 0, the currently installed default allocator
2273 /// is used. This function does not exist unless
2274 /// `unique_ptr<COMPATIBLE_TYPE, DELETER>::pointer` is convertible to `ELEMENT_TYPE *`.
2275 ///
2276 /// \note Note that this function creates a `shared_ptr`
2277 /// with an unspecified deleter type that has satisfies this contract,
2278 /// which might not be the deleter of `rhs`, which is specified by the
2279 /// C++ standard.
2280 template <class COMPATIBLE_TYPE, class UNIQUE_DELETER>
2281 shared_ptr(std::unique_ptr<COMPATIBLE_TYPE,
2282 UNIQUE_DELETER>&& adoptee,
2283 BloombergLP::bslma::Allocator *basicAllocator = 0,
2284 typename enable_if<is_convertible<
2285 typename std::unique_ptr<COMPATIBLE_TYPE,
2286 UNIQUE_DELETER>::pointer,
2287 ELEMENT_TYPE *>::value,
2288 BloombergLP::bslstl::SharedPtr_ImpUtil>::type =
2289 BloombergLP::bslstl::SharedPtr_ImpUtil())
2290 // IMPLICIT
2291 : d_ptr_p(adoptee.get())
2292 , d_rep_p(0)
2293 {
2294 // This constructor template must be defined inline inside the class
2295 // definition, as Microsoft Visual C++ does not recognize the
2296 // definition as matching this signature when placed out-of-line.
2297
2298 typedef BloombergLP::bslma::SharedPtrInplaceRep<
2299 std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER> > Rep;
2300
2301 if (d_ptr_p) {
2302 basicAllocator =
2303 BloombergLP::bslma::Default::allocator(basicAllocator);
2304 Rep *rep = new (*basicAllocator) Rep(basicAllocator,
2305 BloombergLP::bslmf::MovableRefUtil::move(adoptee));
2306 d_rep_p = rep;
2307 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
2308 d_ptr_p,
2309 this);
2310 }
2311 }
2312# endif // BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS
2313#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR
2314
2315 /// Create a shared pointer that manages the same modifiable object (if
2316 /// any) as the specified `source` shared pointer to the (template
2317 /// parameter) type `ANY_TYPE`, and that refers to the modifiable object
2318 /// at the specified `object` address. The resulting shared pointer is known as an "alias" of `source`.
2319 ///
2320 /// \note Note that typically the objects
2321 /// referred to by `source` and `object` have identical lifetimes (e.g.,
2322 /// one might be a part of the other), so that the deleter for `source`
2323 /// will destroy them both, but they do not necessarily have the same
2324 /// type. Also note that if `source` is empty, then an empty shared
2325 /// pointer is created, even if `object` is not null (in which case this
2326 /// empty shared pointer will refer to the same object as `object`).
2327 /// Also note that if `object` is null and `source` is not empty, then a
2328 /// reference-counted null pointer alias will be created.
2329 template <class ANY_TYPE>
2331 ELEMENT_TYPE *object) BSLS_KEYWORD_NOEXCEPT;
2332
2333 /// Create a shared pointer that manages the same modifiable object (if
2334 /// any) as the specified `other` shared pointer to the (template
2335 /// parameter) type `COMPATIBLE_TYPE`, uses the same deleter as `other`
2336 /// to destroy the shared object, and refers to
2337 /// `(ELEMENT_TYPE*)other.get()`. If `COMPATIBLE_TYPE *` is not
2338 /// implicitly convertible to `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2339 ///
2340 /// \note Note that if
2341 /// `other` is empty, then an empty shared pointer is created, which may
2342 /// still point to an un-managed object if `other` were constructed
2343 /// through an aliasing constructor.
2344 template <class COMPATIBLE_TYPE
2347
2348 /// Create a shared pointer that refers to and manages the same object
2349 /// (if any) as the specified `original` shared pointer, and uses the
2350 /// same deleter as `original` to destroy the shared object.
2351 ///
2352 /// \note Note that if `original` is empty, then an empty shared pointer is created,
2353 /// which may still point to an un-managed object if `original` were
2354 /// constructed through an aliasing constructor.
2356
2357 /// Create a shared pointer that refers to and assumes management of the
2358 /// same object (if any) as the specified `original` shared pointer,
2359 /// using the same deleter as `original` to destroy the shared object,
2360 /// and reset `original` to an empty state, not pointing to any object.
2361 ///
2362 /// \note Note that if `original` is empty, then an empty shared pointer is
2363 /// created, which may still point to an un-managed object if `original`
2364 /// were constructed through an aliasing constructor.
2365 shared_ptr(BloombergLP::bslmf::MovableRef<shared_ptr> original)
2367
2368#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2369 /// Create a shared pointer that refers to and assumes management of the
2370 /// same object (if any) as the specified `other` shared pointer to the
2371 /// (template parameter) type `COMPATIBLE_TYPE`, using the same deleter
2372 /// as `other` to destroy the shared object, and refers to
2373 /// `(ELEMENT_TYPE*)other.get()`. If `COMPATIBLE_TYPE *` is not
2374 /// implicitly convertible to `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2375 ///
2376 /// \note Note that if
2377 /// `other` is empty, then an empty shared pointer is created, which may
2378 /// still point to an un-managed object if `other` were constructed
2379 /// through an aliasing constructor.
2380 template <class COMPATIBLE_TYPE
2383#else
2384 /// Create a shared pointer that refers to and assumes management of the
2385 /// same object (if any) as the specified `other` shared pointer to the
2386 /// (template parameter) type `COMPATIBLE_TYPE`, using the same deleter
2387 /// as `other` to destroy the shared object, and refers to
2388 /// `(ELEMENT_TYPE*)other.get()`. If `COMPATIBLE_TYPE *` is not
2389 /// implicitly convertible to `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2390 ///
2391 /// \note Note that if
2392 /// `other` is empty, then an empty shared pointer is created, which may
2393 /// still point to an un-managed object if `other` were constructed
2394 /// through an aliasing constructor.
2395 template <class COMPATIBLE_TYPE
2398 BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > other)
2400#endif
2401
2402 /// Create a shared pointer that refers to and manages the same object
2403 /// as the specified `ptr` if `ptr.expired()` is `false`; otherwise, create a shared pointer in the empty state.
2404 ///
2405 /// \note Note that the
2406 /// referenced and managed objects may be different if `ptr` was created
2407 /// from a `shared_ptr` in an aliasing state.
2408 template<class COMPATIBLE_TYPE
2411
2412#if !defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2413 /// Create a shared pointer that refers to and manages the same object
2414 /// as the specified `ptr` if `ptr.expired()` is `false`; otherwise, create a shared pointer in the empty state.
2415 ///
2416 /// \note Note that the
2417 /// referenced and managed objects may be different if `ptr` was created
2418 /// from a `shared_ptr` in an aliasing state. Also note that this
2419 /// overloaded constructor is necessary only for C++03 compilers that
2420 /// rely on the BDE move-emulation type, `bslmf::MovableRef`; a C++11
2421 /// compiler will pass rvalues directly to the constructor taking a
2422 /// `const weak_ptr&`, rendering this constructor redundant.
2423 template<class COMPATIBLE_TYPE
2425 explicit shared_ptr(
2426 BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > ptr);
2427#endif
2428
2429 /// Destroy this shared pointer. If this shared pointer refers to a
2430 /// (possibly shared) object, then release the reference to that object,
2431 /// and destroy the shared object using its associated deleter if this
2432 /// shared pointer is the last reference to that object.
2434
2435 // MANIPULATORS
2436
2437 /// Make this shared pointer manage the same modifiable object as the
2438 /// specified `rhs` shared pointer to the (template parameter) type
2439 /// `COMPATIBLE_TYPE`, use the same deleter as `rhs`, and refer to
2440 /// `(ELEMENT_TYPE *)rhs.get()`; return a reference providing modifiable access to this shared pointer.
2441 ///
2442 /// \note Note that if `rhs` is empty, then
2443 /// this shared pointer will also be empty after the assignment. Also
2444 /// note that if `*this` is the same object as `rhs`, then this method
2445 /// has no effect.
2447
2448 /// Make this shared pointer manage the same modifiable object as the
2449 /// specified `rhs` shared pointer to the (template parameter) type
2450 /// `COMPATIBLE_TYPE`, use the same deleter as `rhs`, and refer to
2451 /// `rhs.get()`; return a reference providing modifiable access to this
2452 /// shared pointer. Reset `rhs` to an empty state, not pointing to any object, unless `*this` is the same object as `rhs`.
2453 ///
2454 /// \note Note that if
2455 /// `rhs` is empty, then this shared pointer will also be empty after
2456 /// the assignment.
2457 shared_ptr& operator=(BloombergLP::bslmf::MovableRef<shared_ptr> rhs)
2459
2460 /// Make this shared pointer refer to and manage the same modifiable
2461 /// object as the specified `rhs` shared pointer to the (template
2462 /// parameter) type `COMPATIBLE_TYPE`, using the same deleter as `rhs`
2463 /// and referring to `(ELEMENT_TYPE *)rhs.get()`, and return a reference
2464 /// to this modifiable shared pointer. If this shared pointer is
2465 /// already managing a (possibly shared) object, then release the shared
2466 /// reference to that object, and destroy it using its associated
2467 /// deleter if this shared pointer held the last shared reference to that object.
2468 ///
2469 /// \note Note that if `rhs` is empty, then this shared pointer
2470 /// will also be empty after the assignment.
2471 template <class COMPATIBLE_TYPE>
2472 typename enable_if<
2474 shared_ptr&>::type
2476
2477#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2478 /// Make this shared pointer refer to and manage the same modifiable
2479 /// object as the specified `rhs` shared pointer to the (template
2480 /// parameter) type `COMPATIBLE_TYPE`, using the same deleter as `rhs`
2481 /// and referring to `(ELEMENT_TYPE *)rhs.get()`, and return a reference
2482 /// to this modifiable shared pointer. If this shared pointer is
2483 /// already managing a (possibly shared) object, then release the shared
2484 /// reference to that object, and destroy it using its associated
2485 /// deleter if this shared pointer held the last shared reference to
2486 /// that object. Reset `rhs` to an empty state, not pointing to any
2487 /// object, unless `*this` is the same object as `rhs`. This function
2488 /// does not exist unless a pointer to (template parameter)
2489 /// `COMPATIBLE_TYPE` is convertible to a pointer to the (template parameter) `ELEMENT_TYPE` of this `shared_ptr`.
2490 ///
2491 /// \note Note that if `rhs`
2492 /// is empty, then this shared pointer will also be empty after the
2493 /// assignment.
2494 template <class COMPATIBLE_TYPE>
2495 typename
2497 shared_ptr&>::type
2499#else
2500 /// Make this shared pointer refer to and manage the same modifiable
2501 /// object as the specified `rhs` shared pointer to the (template
2502 /// parameter) type `COMPATIBLE_TYPE`, using the same deleter as `rhs`
2503 /// and referring to `(ELEMENT_TYPE *)rhs.get()`, and return a reference
2504 /// to this modifiable shared pointer. If this shared pointer is
2505 /// already managing a (possibly shared) object, then release the shared
2506 /// reference to that object, and destroy it using its associated
2507 /// deleter if this shared pointer held the last shared reference to
2508 /// that object. Reset `rhs` to an empty state, not pointing to any
2509 /// object, unless `*this` is the same object as `rhs`. This function
2510 /// does not exist unless a pointer to (template parameter)
2511 /// `COMPATIBLE_TYPE` is convertible to a pointer to the (template parameter) `ELEMENT_TYPE` of this `shared_ptr`.
2512 ///
2513 /// \note Note that if `rhs`
2514 /// is empty, then this shared pointer will also be empty after the
2515 /// assignment.
2516 template <class COMPATIBLE_TYPE>
2517 typename
2519 shared_ptr&>::type
2520 operator=(BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > rhs)
2522#endif
2523
2524 /// Transfer, to this shared pointer, ownership of the modifiable object
2525 /// managed by the specified `rhs` managed pointer to the (template
2526 /// parameter) type `COMPATIBLE_TYPE`, and make this shared pointer
2527 /// refer to `(ELEMENT_TYPE *)rhs.ptr()`. The deleter used in the `rhs`
2528 /// will be used to destroy the shared object when all references have
2529 /// been released. The *default* *allocator* is used to allocate a
2530 /// `SharedPtrRep`, if needed (users must use the copy-constructor and
2531 /// swap instead of using this operator to supply an alternative
2532 /// allocator). If this shared pointer is already managing a (possibly
2533 /// shared) object, then release the reference to that shared object,
2534 /// and destroy it using its associated deleter if this shared pointer held the last shared reference to that object.
2535 ///
2536 /// \note Note that if `rhs`
2537 /// is empty, then this shared pointer will be empty after the
2538 /// assignment. Also note that if `rhs` owns a reference to another
2539 /// shared object (due to a previous call to
2540 /// `shared_ptr<T>::managedPtr`) then this `shared_ptr` will adopt the
2541 /// `ManagedPtr`s ownership of that shared object.
2542 template <class COMPATIBLE_TYPE>
2543 typename enable_if<
2545 shared_ptr&>::type
2546 operator=(BloombergLP::bslma::ManagedPtr<COMPATIBLE_TYPE> rhs);
2547
2548#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
2549 /// Transfer, to this shared pointer, ownership of the modifiable object
2550 /// managed by the specified `rhs` auto pointer to the (template
2551 /// parameter) type `COMPATIBLE_TYPE`, and make this shared pointer
2552 /// refer to `(ELEMENT_TYPE *)rhs.get()`. `delete(autoPtr.release())`
2553 /// will be called to destroy the shared object when all references have
2554 /// been released. If this shared pointer is already managing a
2555 /// (possibly shared) object, then release the reference to that shared
2556 /// object, and destroy it using its associated deleter if this shared pointer held the last shared reference to that object.
2557 ///
2558 /// \note Note that if
2559 /// `rhs` is empty, then this shared pointer will be empty after the
2560 /// assignment.
2561 template <class COMPATIBLE_TYPE>
2562 typename enable_if<
2564 shared_ptr&>::type
2565 operator=(std::auto_ptr<COMPATIBLE_TYPE> rhs);
2566#endif
2567
2568#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
2569 /// Transfer, to this shared pointer, ownership of the object managed by
2570 /// the specified `rhs` unique pointer to the (template parameter) type
2571 /// `COMPATIBLE_TYPE`, and make this shared pointer refer to
2572 /// `(ELEMENT_TYPE *)rhs.get()`. The deleter of `rhs` will be called to
2573 /// destroy the shared object when all references have been released.
2574 /// If this shared pointer is already managing a (possibly shared)
2575 /// object, then release the reference to that shared object, and
2576 /// destroy it using its associated deleter if this shared pointer held
2577 /// the last shared reference to that object. This function does not
2578 /// exist unless `unique_ptr<COMPATIBLE_TYPE, DELETER>::pointer` is convertible to `ELEMENT_TYPE *`.
2579 ///
2580 /// \note Note that if `rhs` is empty, then
2581 /// this shared pointer will be empty after the assignment. Also note
2582 /// that this function creates a `shared_ptr` with an unspecified
2583 /// deleter type that satisfies this contract; the C++11 standard
2584 /// specifies the exact deleter that should be in use after assignment,
2585 /// so this implementation may be non-conforming.
2586 template <class COMPATIBLE_TYPE, class UNIQUE_DELETER>
2587 typename enable_if<
2589 typename std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>::pointer,
2590 ELEMENT_TYPE *>::value,
2591 shared_ptr&>::type
2592 operator=(std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>&& rhs);
2593#endif
2594
2595 /// Reset this shared pointer to the empty state. If this shared
2596 /// pointer is managing a (possibly shared) object, then release the
2597 /// reference to the shared object, calling the associated deleter to
2598 /// destroy the shared object if this shared pointer is the last shared
2599 /// reference.
2601
2602 /// Modify this shared pointer to manage the modifiable object of the
2603 /// (template parameter) type `COMPATIBLE_TYPE` at the specified `ptr`
2604 /// address and to refer to `(ELEMENT_TYPE *)ptr`. If this shared
2605 /// pointer is already managing a (possibly shared) object, then, unless
2606 /// an exception is thrown allocating memory to manage `ptr`, release
2607 /// the reference to the shared object, calling the associated deleter
2608 /// to destroy the shared object if this shared pointer is the last
2609 /// reference. The currently installed default allocator is used to
2610 /// allocate the internal representation of this shared pointer, and the
2611 /// shared object will be destroyed by a call to `delete ptr` when all
2612 /// references have been released. If an exception is thrown allocating
2613 /// the internal representation, then `delete ptr` is called and this
2614 /// shared pointer retains ownership of its original object. If
2615 /// `COMPATIBLE_TYPE*` is not implicitly convertible to `ELEMENT_TYPE*`,
2616 /// then a compiler diagnostic will be emitted indicating the error.
2617 ///
2618 /// \note Note that if `ptr` is 0, then this shared pointer will still
2619 /// allocate an internal representation to share ownership of that empty
2620 /// state, which will be reclaimed when the last reference is destroyed.
2621 template <class COMPATIBLE_TYPE>
2622 typename
2623 enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
2624 reset(COMPATIBLE_TYPE *ptr);
2625
2626 /// Modify this shared pointer to manage the modifiable object of the
2627 /// (template parameter) type `COMPATIBLE_TYPE` at the specified `ptr`
2628 /// address, refer to `(ELEMENT_TYPE *)ptr`, and use the specified
2629 /// `deleter` to delete the shared object when all references have been
2630 /// released. If this shared pointer is already managing a (possibly
2631 /// shared) object, then unless an exception is thrown allocating memory
2632 /// to manage `ptr`, release the reference to the shared object, calling
2633 /// the associated deleter to destroy the shared object if this shared
2634 /// pointer is the last reference. If `DELETER` is an object type, then
2635 /// `deleter` is assumed to be a function-like deleter that may be
2636 /// invoked to destroy the object referred to by a single argument of
2637 /// type `COMPATIBLE_TYPE *` (i.e., `deleter(ptr)` will be called to
2638 /// destroy the shared object). If `DELETER` is a pointer type that is
2639 /// not a function pointer, then `deleter` shall be a pointer to a
2640 /// factory object that exposes a member function that can be invoked as
2641 /// `deleteObject(ptr)` that will be called to destroy the object at the
2642 /// `ptr` address (i.e., `deleter->deleteObject(ptr)` will be called to
2643 /// delete the shared object). (See the "Deleters" section in the
2644 /// component-level documentation.) If `DELETER` is also a pointer to
2645 /// `bslma::Allocator` or to a class derived from `bslma::Allocator`,
2646 /// then that allocator will also be used to allocate and destroy the
2647 /// internal representation of this shared pointer when all references
2648 /// have been released; otherwise, the currently installed default
2649 /// allocator is used to allocate and destroy the internal
2650 /// representation of this shared pointer when all references have been
2651 /// released. If an exception is thrown allocating the internal
2652 /// representation, then `deleter(ptr)` is called (or
2653 /// `deleter->deleteObject(ptr)` for factory-type deleters) and this
2654 /// shared pointer retains ownership of its original object. If
2655 /// `COMPATIBLE_TYPE*` is not implicitly convertible to `ELEMENT_TYPE*`,
2656 /// then a compiler diagnostic will be emitted indicating the error.
2657 ///
2658 /// \note Note that, for factory deleters, `deleter` must remain valid until
2659 /// all references to `ptr` have been released. If `ptr` is 0, then an
2660 /// internal representation will still be allocated, and this shared
2661 /// pointer will share ownership of a copy of `deleter`. Further note
2662 /// that this function is logically equivalent to:
2663 /// @code
2664 /// *this = shared_ptr<ELEMENT_TYPE>(ptr, deleter);
2665 /// @endcode
2666 template <class COMPATIBLE_TYPE, class DELETER>
2667 typename
2668 enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
2669 reset(COMPATIBLE_TYPE *ptr, DELETER deleter);
2670
2671
2672 /// Modify this shared pointer to manage the modifiable object of the
2673 /// (template parameter) type `COMPATIBLE_TYPE` at the specified `ptr`
2674 /// address, refer to `(ELEMENT_TYPE *)ptr` and use the specified
2675 /// `deleter` to delete the shared object when all references have been
2676 /// released. Use the specified `basicAllocator` to allocate and
2677 /// deallocate the internal representation of the shared pointer. If
2678 /// this shared pointer is already managing a (possibly shared) object,
2679 /// then, unless an exception is thrown allocating memory to manage
2680 /// `ptr`, release the shared reference to that shared object, and
2681 /// destroy it using its associated deleter if this shared pointer held
2682 /// the last shared reference to that object. If `DELETER` is a
2683 /// reference type, then `deleter` is assumed to be a function-like
2684 /// deleter that may be invoked to destroy the object referred to by a
2685 /// single argument of type `COMPATIBLE_TYPE *` (i.e., `deleter(ptr)`
2686 /// will be called to destroy the shared object). If `DELETER` is a
2687 /// pointer type, then `deleter` is assumed to be a pointer to a factory
2688 /// object that exposes a member function that can be invoked as
2689 /// `deleteObject(ptr)` that will be called to destroy the object at the
2690 /// `ptr` address (i.e., `deleter->deleteObject(ptr)` will be called to
2691 /// delete the shared object). (See the "Deleters" section in the
2692 /// component-level documentation.) If an exception is thrown
2693 /// allocating the internal representation, then `deleter(ptr)` is
2694 /// called (or `deleter->deleteObject(ptr)` for factory-type deleters)
2695 /// and this shared pointer retains ownership of its original object.
2696 ///
2697 /// \pre The behavior is undefined unless `deleter(ptr)` is a well-defined
2698 /// expression (or `deleter->deleteObject(ptr)` for factory-type
2699 /// deleters), and unless the copy constructor for `deleter` does not
2700 /// throw an exception. If `COMPATIBLE_TYPE *` is not implicitly
2701 /// convertible to `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2702 ///
2703 /// \note Note that, for factory deleters, the
2704 /// `deleter` must remain valid until all references to `ptr` have been
2705 /// released. Also note that if `ptr` is 0, then an internal
2706 /// representation will still be allocated, and this shared pointer will
2707 /// share ownership of a copy of `deleter`. Further note that this
2708 /// function is logically equivalent to:
2709 /// @code
2710 /// *this = shared_ptr<ELEMENT_TYPE>(ptr, deleter, basicAllocator);
2711 /// @endcode
2712 template <class COMPATIBLE_TYPE, class DELETER, class ALLOCATOR>
2713 typename
2714 enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
2715 reset(COMPATIBLE_TYPE *ptr,
2716 DELETER deleter,
2717 ALLOCATOR basicAllocator);
2718
2719 /// Modify this shared pointer to manage the same modifiable object (if
2720 /// any) as the specified `source` shared pointer to the (template
2721 /// parameter) type `ANY_TYPE`, and refer to the modifiable object at
2722 /// the specified `ptr` address (i.e., make this shared pointer an
2723 /// "alias" of `source`). If this shared pointer is already managing a
2724 /// (possibly shared) object, then release the reference to the shared
2725 /// object, calling the associated deleter to destroy the shared object if this shared pointer is the last reference.
2726 ///
2727 /// \note Note that typically
2728 /// the objects referred to by `source` and `ptr` have identical
2729 /// lifetimes (e.g., one might be a part of the other), so that the
2730 /// deleter for `source` will destroy them both, but do not necessarily
2731 /// have the same type. Also note that if `source` is empty, then this
2732 /// shared pointer will be reset to an empty state, even if `ptr` is not
2733 /// null (in which case this empty shared pointer will refer to the same
2734 /// object as `ptr`). Also note that if `ptr` is null and `source` is
2735 /// not empty, then this shared pointer will be reset to a
2736 /// (reference-counted) null pointer alias. Further note that the
2737 /// behavior of this method is the same as `loadAlias(source, ptr)`.
2738 /// Finally note that this is a non-standard BDE extension to the C++
2739 /// Standard `shared_ptr` interface, which does not provide an alias
2740 /// overload for the `reset` function.
2741 template <class ANY_TYPE>
2742 void reset(const shared_ptr<ANY_TYPE>& source, ELEMENT_TYPE *ptr);
2743
2744 /// Efficiently exchange the states of this shared pointer and the
2745 /// specified `other` shared pointer such that each will refer to the
2746 /// object formerly referred to by the other and each will manage the
2747 /// object formerly managed by the other.
2749
2750 // ADDITIONAL BSL MANIPULATORS
2751
2752 /// Create "in-place" in a large enough contiguous memory region both an
2753 /// internal representation for this shared pointer and a
2754 /// default-constructed object of `ELEMENT_TYPE`, and make this shared
2755 /// pointer refer to the newly-created `ELEMENT_TYPE` object. The
2756 /// currently installed default allocator is used to supply memory. If
2757 /// an exception is thrown during allocation or construction of the
2758 /// `ELEMENT_TYPE` object, this shared pointer will be unchanged.
2759 /// Otherwise, if this shared pointer is already managing a (possibly
2760 /// shared) object, then release the shared reference to that shared
2761 /// object, and destroy it using its associated deleter if this shared
2762 /// pointer held the last shared reference to that object.
2764
2765#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
2766
2767 /// Create "in-place" in a large enough contiguous memory region, using
2768 /// the specified `basicAllocator` to supply memory, both an internal
2769 /// representation for this shared pointer and an object of
2770 /// `ELEMENT_TYPE` using the `ELEMENT_TYPE` constructor that takes the
2771 /// specified `args...` arguments, and make this shared pointer refer to
2772 /// the newly-created `ELEMENT_TYPE` object. If an exception is thrown
2773 /// during the construction of the `ELEMENT_TYPE` object, this shared
2774 /// pointer will be unchanged. Otherwise, if this shared pointer is
2775 /// already managing a (possibly shared) object, then release the shared
2776 /// reference to that shared object, and destroy it using its associated
2777 /// deleter if this shared pointer held the last shared reference to that object.
2778 ///
2779 /// \note Note that the allocator argument is *not* implicitly
2780 /// passed to the constructor for `ELEMENT_TYPE`; to construct an object
2781 /// of `ELEMENT_TYPE` with an allocator, pass the allocator as one of
2782 /// the arguments (typically the last argument), or assign with a
2783 /// `shared_ptr` created using the standard @ref allocate_shared function.
2784 template <class... ARGS>
2785 void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
2786 ARGS&&... args);
2787#endif
2788
2789 /// Modify this shared pointer to manage the same modifiable object (if
2790 /// any) as the specified `source` shared pointer to the (template
2791 /// parameter) type `ANY_TYPE`, and refer to the modifiable object at
2792 /// the specified `object` address (i.e., make this shared pointer an
2793 /// "alias" of `source`). If this shared pointer is already managing a
2794 /// (possibly shared) object, then release the shared reference to that
2795 /// shared object, and destroy it using its associated deleter if this
2796 /// shared pointer held the last shared reference to that object.
2797 ///
2798 /// \note Note that typically the objects referred to by `source` and `object` have
2799 /// identical lifetimes (e.g., one might be a part of the other), so
2800 /// that the deleter for `source` will destroy them both, but they do
2801 /// not necessarily have the same type. Also note that if `source` is
2802 /// empty, then this shared pointer will be reset to an empty state,
2803 /// even if `object` is not null (in which case this empty shared
2804 /// pointer will refer to the same object as `object`). Also note that
2805 /// if `object` is null and `source` is not empty, then this shared
2806 /// pointer will be reset to a (reference-counted) null pointer alias.
2807 /// Also note that this function is logically equivalent to:
2808 /// @code
2809 /// *this = shared_ptr<ELEMENT_TYPE>(source, object);
2810 /// @endcode
2811 /// Further note that the behavior of this method is the same as
2812 /// `reset(source, object)`.
2813 ///
2814 /// @deprecated Use @ref reset instead.
2815 template <class ANY_TYPE>
2817 ELEMENT_TYPE *object);
2818
2819 /// Return the pair consisting of the addresses of the modifiable
2820 /// `ELEMENT_TYPE` object referred to, and the representation shared by,
2821 /// this shared pointer, and reset this shared pointer to the empty
2822 /// state, referring to no object, with no effect on the representation.
2823 /// The reference counter is not modified nor is the shared object
2824 /// deleted; if the reference count of the representation is greater
2825 /// than one, then it is not safe to release the representation (thereby
2826 /// destroying the shared object), but it is always safe to create
2827 /// another shared pointer with the representation using the constructor
2828 /// with the following signature:
2829 /// @code
2830 /// 'shared_ptr(ELEMENT_TYPE *ptr,
2831 /// BloombergLP::bslma::SharedPtrRep *rep)'
2832 /// @endcode
2833 ///
2834 /// \note Note that this function returns a pair of null pointers if this
2835 /// shared pointer is empty.
2838
2839#ifndef BDE_OMIT_INTERNAL_DEPRECATED
2840 // DEPRECATED BDE LEGACY MANIPULATORS
2841
2842 /// Reset this shared pointer to the empty state. If this shared
2843 /// pointer is managing a (possibly shared) object, then release the
2844 /// reference to the shared object, calling the associated deleter to
2845 /// destroy the shared object if this shared pointer is the last reference.
2846 ///
2847 /// \note Note that the behavior of this method is the same as
2848 /// `reset()`.
2849 ///
2850 /// @deprecated Use @ref reset instead.
2852
2853 /// Modify this shared pointer to manage the modifiable object of the
2854 /// (template parameter) type `COMPATIBLE_TYPE` at the specified `ptr`
2855 /// address and to refer to `(ELEMENT_TYPE *)ptr`. If this shared
2856 /// pointer is already managing a (possibly shared) object, then, unless
2857 /// an exception is thrown allocating memory to manage `ptr`, release
2858 /// the reference to the shared object, calling the associated deleter
2859 /// to destroy the shared object if this shared pointer is the last
2860 /// reference. The currently installed default allocator is used to
2861 /// allocate the internal representation of this shared pointer, and the
2862 /// shared object will be destroyed by a call to `delete ptr` when all
2863 /// references have been released. If an exception is thrown allocating
2864 /// the internal representation, then `delete ptr` is called and this
2865 /// shared pointer retains ownership of its original object. If
2866 /// `COMPATIBLE_TYPE*` is not implicitly convertible to `ELEMENT_TYPE*`,
2867 /// then a compiler diagnostic will be emitted indicating the error.
2868 ///
2869 /// \note Note that if `ptr` is 0, then this shared pointer will still
2870 /// allocate an internal representation to share ownership of that empty
2871 /// state, which will be reclaimed when the last reference is destroyed.
2872 /// Also note also that the behavior of this method is the same as
2873 /// `reset(ptr)`.
2874 ///
2875 /// @deprecated Use @ref reset instead.
2876 template <class COMPATIBLE_TYPE>
2877 void load(COMPATIBLE_TYPE *ptr);
2878
2879 /// Modify this shared pointer to manage the modifiable object of the
2880 /// (template parameter) type `COMPATIBLE_TYPE` at the specified `ptr`
2881 /// address and to refer to `(ELEMENT_TYPE *)ptr`. If this shared
2882 /// pointer is already managing a (possibly shared) object, then, unless
2883 /// an exception is thrown allocating memory to manage `ptr`, release
2884 /// the reference to the shared object, calling the associated deleter
2885 /// to destroy the shared object if this shared pointer is the last
2886 /// reference. Use the specified `basicAllocator` to allocate the
2887 /// internal representation of this shared pointer and to destroy the
2888 /// shared object when all references have been released; if
2889 /// `basicAllocator` is 0, the currently installed default allocator is
2890 /// used. If an exception is thrown allocating the internal
2891 /// representation, then destroy `*ptr` with a call to
2892 /// `alloc->deleteObject(ptr)` where `alloc` is the chosen allocator,
2893 /// and this shared pointer retains ownership of its original object.
2894 /// If `COMPATIBLE_TYPE *` is not implicitly convertible to
2895 /// `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2896 ///
2897 /// \note Note that if `ptr` is 0, then this shared
2898 /// pointer will still allocate an internal representation to share
2899 /// ownership of that empty state, which will be reclaimed when the last
2900 /// reference is destroyed. Also note that this function is logically
2901 /// equivalent to:
2902 /// @code
2903 /// *this = shared_ptr<ELEMENT_TYPE>(ptr, basicAllocator);
2904 /// @endcode
2905 ///
2906 /// @deprecated Use @ref reset instead.
2907 template <class COMPATIBLE_TYPE>
2908 void load(COMPATIBLE_TYPE *ptr,
2909 BloombergLP::bslma::Allocator *basicAllocator);
2910
2911 /// Modify this shared pointer to manage the modifiable object of the
2912 /// (template parameter) type `COMPATIBLE_TYPE` at the specified `ptr`
2913 /// address, refer to `(ELEMENT_TYPE *)ptr` and use the specified
2914 /// `deleter` to delete the shared object when all references have been
2915 /// released. Use the specified `basicAllocator` to allocate and
2916 /// deallocate the internal representation of the shared pointer. If
2917 /// `basicAllocator` is 0, the currently installed default allocator is
2918 /// used. If this shared pointer is already managing a (possibly
2919 /// shared) object, then, unless an exception is thrown creating storage
2920 /// to manage `ptr`, release the shared reference to that shared object,
2921 /// and destroy it using its associated deleter if this shared pointer
2922 /// held the last shared reference to that object. If `DELETER` is a
2923 /// reference type, then `deleter` is assumed to be a function-like
2924 /// deleter that may be invoked to destroy the object referred to by a
2925 /// single argument of type `COMPATIBLE_TYPE *` (i.e., `deleter(ptr)`
2926 /// will be called to destroy the shared object). If `DELETER` is a
2927 /// pointer type, then `deleter` is assumed to be a pointer to a factory
2928 /// object that exposes a member function that can be invoked as
2929 /// `deleteObject(ptr)` that will be called to destroy the object at the
2930 /// `ptr` address (i.e., `deleter->deleteObject(ptr)` will be called to
2931 /// delete the shared object). (See the "Deleters" section in the
2932 /// component-level documentation.) If an exception is thrown
2933 /// allocating the internal representation, then `deleter(ptr)` is
2934 /// called (or `deleter->deleteObject(ptr)` for factory-type deleters)
2935 /// and this shared pointer retains ownership of its original object.
2936 ///
2937 /// \pre The behavior is undefined unless `deleter(ptr)` is a well-defined
2938 /// expression (or `deleter->deleteObject(ptr)` for factory-type
2939 /// deleters), and unless the copy constructor for `deleter` does not
2940 /// throw an exception. If `COMPATIBLE_TYPE *` is not implicitly
2941 /// convertible to `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted indicating the error.
2942 ///
2943 /// \note Note that, for factory deleters, the
2944 /// `deleter` must remain valid until all references to `ptr` have been
2945 /// released. Also note that if `ptr` is 0, then an internal
2946 /// representation will still be allocated, and this shared pointer will
2947 /// share ownership of a copy of `deleter`. Further note that this
2948 /// function is logically equivalent to:
2949 /// @code
2950 /// *this = shared_ptr<ELEMENT_TYPE>(ptr, deleter, basicAllocator);
2951 /// @endcode
2952 ///
2953 /// @deprecated Use @ref reset instead.
2954 template <class COMPATIBLE_TYPE, class DELETER>
2955 void load(COMPATIBLE_TYPE *ptr,
2956 const DELETER& deleter,
2957 BloombergLP::bslma::Allocator *basicAllocator);
2958
2959#endif // BDE_OMIT_INTERNAL_DEPRECATED
2960
2961 // ACCESSORS
2962
2963 /// Return a value of an "unspecified bool" type that evaluates to
2964 /// `false` if this shared pointer does not refer to an object, and `true` otherwise.
2965 ///
2966 /// \note Note that this conversion operator allows a
2967 /// shared pointer to be used within a conditional context (e.g., within
2968 /// an `if` or `while` statement), but does *not* allow shared pointers
2969 /// to unrelated types to be compared (e.g., via `<` or `>`).
2970 operator BoolType() const BSLS_KEYWORD_NOEXCEPT;
2971
2972 /// Return a reference providing modifiable access to the object
2973 /// referred to by this shared pointer.
2974 ///
2975 /// \pre The behavior is undefined unless this shared pointer refers to an object, and `ELEMENT_TYPE`
2976 /// is not (potentially `const` or `volatile` qualified) `void`.
2977 typename add_lvalue_reference<ELEMENT_TYPE>::type
2978 operator*() const BSLS_KEYWORD_NOEXCEPT;
2979
2980 /// Return the address providing modifiable access to the object
2981 /// referred to by this shared pointer, or 0 if this shared pointer does not refer to an object.
2982 ///
2983 /// \note Note that applying this operator
2984 /// conventionally (e.g., to invoke a method) to an shared pointer that
2985 /// does not refer to an object will result in undefined behavior.
2986 ELEMENT_TYPE *operator->() const BSLS_KEYWORD_NOEXCEPT;
2987
2988 /// Return the address providing modifiable access to the object
2989 /// referred to by this shared pointer, or 0 if this shared pointer does
2990 /// not refer to an object.
2992
2993 /// Return a reference providing modifiable access to the object at the
2994 /// specified `index` offset in the object referred to by this shared pointer.
2995 ///
2996 /// \pre The behavior is undefined unless this shared pointer is
2997 /// not empty, `ELEMENT_TYPE` is not `void` (a compiler error will be
2998 /// generated if this operator is instantiated within the
2999 /// `shared_ptr<void>` class), and this shared pointer refers to an
3000 /// array of `ELEMENT_TYPE` objects. Instead of `element_type &`, we
3001 /// use `add_lvalue_reference<element_type>::type` for the return type
3002 /// because that allows people to instantiate `shared_ptr<cv_void>`, as long as they don't use this method.
3003 ///
3004 /// \note Note that this method is
3005 /// logically equivalent to `*(get() + index)`.
3006 typename add_lvalue_reference<element_type>::type
3007 operator[](ptrdiff_t index) const;
3008
3009 template<class ANY_TYPE>
3010 bool owner_before(const shared_ptr<ANY_TYPE>& other) const
3012
3013 /// Return `true` if the address of the
3014 /// `BloombergLP::bslma::SharedPtrRep` object used by this shared
3015 /// pointer is ordered before the address of the
3016 /// `BloombergLP::bslma::SharedPtrRep` object used by the specified
3017 /// `other` shared pointer under the total ordering defined by
3018 /// `std::less<BloombergLP::bslma::SharedPtrRep *>`, and `false`
3019 /// otherwise.
3020 template<class ANY_TYPE>
3021 bool owner_before(const weak_ptr<ANY_TYPE>& other) const
3023
3024 template<class ANY_TYPE>
3025 bool owner_equal(const shared_ptr<ANY_TYPE>& other) const
3027
3028 /// Return `true` if the address of the
3029 /// `BloombergLP::bslma::SharedPtrRep` object used by this shared
3030 /// pointer is equal to the address of the
3031 /// `BloombergLP::bslma::SharedPtrRep` object used by the specified
3032 /// `other` shared pointer, and `false` otherwise.
3033 template<class ANY_TYPE>
3034 bool owner_equal(const weak_ptr<ANY_TYPE>& other) const
3036
3037 /// Return an unspecified value such that, for any object `x` where
3038 /// `owner_equal(x)` is true, `owner_hash() == x.owner_hash()` is true.
3039 ///
3040 /// \note Note that this is based on the hash of the address of the
3041 /// `BloombergLP::bslma::SharedPtrRep` object used by this object.
3042 /// Note also that for two empty smart pointers `x` and `y`,
3043 /// `x.owner_hash() == y.owner_hash()` is true.
3045
3047 "deprecated_cpp17_standard_library_features",
3048 "do not use")
3049 /// Return `true` if this shared pointer is not empty and does not share
3050 /// ownership of the object it managed with any other shared pointer, and `false` otherwise.
3051 ///
3052 /// \note Note that a shared pointer with a custom
3053 /// deleter can refer to a null pointer without being empty, and so may
3054 /// be `unique`. Also note that the result of this function may not be
3055 /// reliable in a multi-threaded program, where a weak pointer may be
3056 /// locked on another thread.
3057 ///
3058 /// @deprecated This function is deprecated in C++17 because its
3059 /// correctness is not guaranteed since the value returned by the used
3060 /// @ref use_count function is approximate.
3061 bool unique() const BSLS_KEYWORD_NOEXCEPT;
3062
3063 /// Return a "snapshot" of the number of shared pointers (including this
3064 /// one) that share ownership of the object managed by this shared pointer.
3065 ///
3066 /// \note Note that 0 is returned if this shared pointer is empty.
3067 /// Also note that any result other than 0 may be unreliable in a
3068 /// multi-threaded program, where another pointer sharing ownership in a
3069 /// different thread may be copied or destroyed, or a weak pointer may
3070 /// be locked in the case that 1 is returned (that would otherwise
3071 /// indicate unique ownership).
3073
3074 // ADDITIONAL BSL ACCESSORS
3075
3076 /// Return a managed pointer that refers to the same object as this
3077 /// shared pointer. If this shared pointer is not empty, and is not
3078 /// null, then increment the shared count on the shared object, and give
3079 /// the managed pointer a deleter that decrements the reference count for the shared object.
3080 ///
3081 /// \note Note that if this `shared_ptr` is reference-
3082 /// counting a null pointer, the empty `bslma::ManagedPtr` returned will
3083 /// not participate in that shared ownership.
3084 BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE> managedPtr() const;
3085
3086 /// Return the address providing modifiable access to the
3087 /// `BloombergLP::bslma::SharedPtrRep` object used by this shared
3088 /// pointer, or 0 if this shared pointer is empty.
3089 BloombergLP::bslma::SharedPtrRep *rep() const BSLS_KEYWORD_NOEXCEPT;
3090
3091#ifndef BDE_OMIT_INTERNAL_DEPRECATED
3092 // DEPRECATED BDE LEGACY ACCESSORS
3093
3094 /// Return a "snapshot" of the number of shared pointers (including this
3095 /// one) that share ownership of the object managed by this shared pointer.
3096 ///
3097 /// \note Note that the behavior of this function is the same as
3098 /// @ref use_count , and the result may be unreliable in multi-threaded code
3099 /// for the same reasons.
3100 ///
3101 /// @deprecated Use @ref use_count instead.
3103
3104 /// Return the address providing modifiable access to the object
3105 /// referred to by this shared pointer, or 0 if this shared pointer does not refer to an object.
3106 ///
3107 /// \note Note that the behavior of this function is
3108 /// the same as `get`.
3109 ///
3110 /// @deprecated Use @ref get instead.
3112#endif // BDE_OMIT_INTERNAL_DEPRECATED
3113};
3114
3115#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
3116// CLASS TEMPLATE DEDUCTION GUIDES
3117
3118// The obvious deduction guide:
3119// template <class T>
3120// shared_ptr(T*) -> shared_ptr<T>;
3121// is not provided because there's no way to distinguish from T* and T[].
3122
3123/// Deduce the specified type `ELEMENT_TYPE` corresponding template
3124/// parameter of the `bsl::weak_ptr` supplied to the constructor of
3125/// `shared_ptr`.
3126template<class ELEMENT_TYPE>
3128
3129/// Deduce the specified type `ELEMENT_TYPE` corresponding template
3130/// parameter of the `std::unique_ptr` supplied to the constructor of
3131/// `shared_ptr`.
3132template<class ELEMENT_TYPE, class DELETER>
3133shared_ptr(std::unique_ptr<ELEMENT_TYPE, DELETER>)
3135
3136/// Deduce the specified type `ELEMENT_TYPE` corresponding template
3137/// parameter of the `std::unique_ptr` supplied to the constructor of
3138/// `shared_ptr`. This guide does not participate in deduction unless the
3139/// specified `ALLOC` inherits from `bslma::Allocator`.
3140template<class ELEMENT_TYPE,
3141 class DELETER,
3142 class ALLOC,
3143 class = typename bsl::enable_if_t<
3144 bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
3145 >
3146shared_ptr(std::unique_ptr<ELEMENT_TYPE, DELETER>, ALLOC *)
3148
3149// Deduction guides for `auto_ptr` and @ref auto_ptr_ref are deliberately not
3150// provided, since auto_ptr has been removed from C++17.
3151
3152/// Deduce the specified type `ELEMENT_TYPE` corresponding template
3153/// parameter of the `bslma::ManagedPtr` supplied to the constructor of
3154/// `shared_ptr`.
3155template<class ELEMENT_TYPE>
3156shared_ptr(BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>)
3158
3159/// Deduce the specified type `ELEMENT_TYPE` corresponding template
3160/// parameter of the `bslma::ManagedPtr` supplied to the constructor of
3161/// `shared_ptr`. This guide does not participate in deduction unless the
3162/// specified `ALLOC` inherits from `bslma::Allocator`.
3163template<class ELEMENT_TYPE,
3164 class ALLOC,
3165 class = typename bsl::enable_if_t<
3166 bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
3167 >
3168shared_ptr(BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>, ALLOC *)
3170#endif
3171
3172// FREE OPERATORS
3173
3174/// Return `true` if the specified `lhs` shared pointer refers to the same
3175/// object (if any) as that referred to by the specified `rhs` shared
3176/// pointer (if any), and `false` otherwise; a compiler diagnostic will be
3177/// emitted indicating the error unless a (raw) pointer to `LHS_TYPE` can be compared to a (raw) pointer to `RHS_TYPE`.
3178///
3179/// \note Note that two shared
3180/// pointers that compare equal do not necessarily manage the same object
3181/// due to aliasing.
3182template <class LHS_TYPE, class RHS_TYPE>
3183bool operator==(const shared_ptr<LHS_TYPE>& lhs,
3185
3186#ifdef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3187
3188/// Perform a three-way comparison of the specified `lhs` and the specified
3189/// `rhs` pointers by using the comparison operators of `LHS_TYPE *` and
3190/// `RHS_TYPE *`; return the result of that comparison.
3191template<class LHS_TYPE, class RHS_TYPE>
3192strong_ordering operator<=>(const shared_ptr<LHS_TYPE>& lhs,
3195
3196#else
3197
3198/// Return `true` if the specified `lhs` shared pointer does not refer to
3199/// the same object (if any) as that referred to by the specified `rhs`
3200/// shared pointer (if any), and `false` otherwise; a compiler diagnostic
3201/// will be emitted indicating the error unless a (raw) pointer to
3202/// `LHS_TYPE` can be compared to a (raw) pointer to `RHS_TYPE`.
3203///
3204/// \note Note that two shared pointers that do not compare equal may manage the same object
3205/// due to aliasing.
3206template <class LHS_TYPE, class RHS_TYPE>
3207bool operator!=(const shared_ptr<LHS_TYPE>& lhs,
3209
3210/// Return `true` if the address of the object that the specified `lhs`
3211/// shared pointer refers to is ordered before the address of the object
3212/// that the specified `rhs` shared pointer refers to under the total
3213/// ordering supplied by `std::less<T *>`, where `T *` is the composite
3214/// pointer type of `LHS_TYPE *` and `RHS_TYPE *`, and `false` otherwise.
3215template<class LHS_TYPE, class RHS_TYPE>
3216bool operator<(const shared_ptr<LHS_TYPE>& lhs,
3218
3219/// Return `true` if the address of the object that the specified `lhs`
3220/// shared pointer refers to is ordered after the address of the object
3221/// that the specified `rhs` shared pointer refers to under the total
3222/// ordering supplied by `std::less<T *>`, where `T *` is the composite
3223/// pointer type of `LHS_TYPE *` and `RHS_TYPE *`, and `false` otherwise.
3224template<class LHS_TYPE, class RHS_TYPE>
3225bool operator>(const shared_ptr<LHS_TYPE>& lhs,
3227
3228/// Return `true` if the specified `lhs` shared pointer refers to the same
3229/// object as the specified `rhs` shared pointer, or if the address of the
3230/// object referred to by `lhs` (if any) is ordered before the address of
3231/// the object referred to by `rhs` (if any) under the total ordering
3232/// supplied by `std::less<T *>`, where `T *` is the composite pointer type
3233// of `LHS_TYPE *` and `RHS_TYPE *`, and `false` otherwise.
3234template<class LHS_TYPE, class RHS_TYPE>
3235bool operator<=(const shared_ptr<LHS_TYPE>& lhs,
3237
3238/// Return `true` if the specified `lhs` shared pointer refers to the same
3239/// object as the specified `rhs` shared pointer, or if the address of the
3240/// object referred to by `lhs` (if any) is ordered after the address of the
3241/// object referred to by `rhs` (if any) under the total ordering supplied
3242/// by `std::less<T *>`, where `T *` is the composite pointer type of
3243/// `LHS_TYPE *` and `RHS_TYPE *`, and `false` otherwise.
3244template<class LHS_TYPE, class RHS_TYPE>
3245bool operator>=(const shared_ptr<LHS_TYPE>& lhs,
3247
3248#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3249
3250/// Return `true` if the specified `lhs` shared pointer does not refer to an
3251/// object, and `false` otherwise.
3252template <class LHS_TYPE>
3253bool operator==(const shared_ptr<LHS_TYPE>& lhs,
3255
3256#ifdef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3257
3258/// Perform a three-way comparison of the specified `ptr` and null pointer
3259/// by using the comparison operators of `TYPE *`; return the result of that
3260/// comparison.
3261template<class TYPE>
3262strong_ordering operator<=>(const shared_ptr<TYPE>& ptr,
3264
3265#else
3266
3267/// Return `true` if the specified `rhs` shared pointer does not refer to an
3268/// object, and `false` otherwise.
3269template <class RHS_TYPE>
3270bool operator==(nullptr_t,
3272
3273/// Return `true` if the specified `lhs` shared pointer refers to an object,
3274/// and `false` otherwise.
3275template <class LHS_TYPE>
3276bool operator!=(const shared_ptr<LHS_TYPE>& lhs,
3278
3279/// Return `true` if the specified `rhs` shared pointer refers to an object,
3280/// and `false` otherwise.
3281template <class RHS_TYPE>
3282bool operator!=(nullptr_t,
3284
3285/// Return `true` if the address of the object referred to by the specified
3286/// `lhs` shared pointer is ordered before the null-pointer value under the
3287/// total ordering supplied by `std::less<LHS_TYPE *>`, and `false`
3288/// otherwise.
3289template <class LHS_TYPE>
3290bool operator<(const shared_ptr<LHS_TYPE>& lhs, nullptr_t)
3292
3293/// Return `true` if the address of the object referred to by the specified
3294/// `rhs` shared pointer is ordered after the null-pointer value under the
3295/// total ordering supplied by `std::less<RHS_TYPE *>`, and `false`
3296/// otherwise.
3297template <class RHS_TYPE>
3298bool operator<(nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
3300
3301/// Return `true` if the specified `lhs` shared pointer does not refer to an
3302/// object, or if the address of the object referred to by `lhs` is ordered
3303/// before the null-pointer value under the total ordering supplied by
3304/// `std::less<LHS_TYPE *>`, and `false` otherwise.
3305template <class LHS_TYPE>
3306bool operator<=(const shared_ptr<LHS_TYPE>& lhs,
3308
3309/// Return `true` if the specified `rhs` shared pointer does not refer to an
3310/// object, or if the address of the object referred to by `rhs` is ordered
3311/// after the null-pointer value under the total ordering supplied by
3312/// `std::less<RHS_TYPE *>`, and `false` otherwise.
3313template <class RHS_TYPE>
3314bool operator<=(nullptr_t,
3316
3317/// Return `true` if the address of the object referred to by the specified
3318/// `lhs` shared pointer is ordered after the null-pointer value under the
3319/// total ordering supplied by `std::less<LHS_TYPE *>`, and `false`
3320/// otherwise.
3321template <class LHS_TYPE>
3322bool operator>(const shared_ptr<LHS_TYPE>& lhs, nullptr_t)
3324
3325/// Return `true` if the address of the object referred to by the specified
3326/// `rhs` shared pointer is ordered before the null-pointer value under the
3327/// total ordering supplied by `std::less<RHS_TYPE *>`, and `false`
3328/// otherwise.
3329template <class RHS_TYPE>
3330bool operator>(nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
3332
3333/// Return `true` if the specified `lhs` shared pointer does not refer to an
3334/// object, or if the address of the object referred to by `lhs` is ordered
3335/// after the null-pointer value under the total ordering supplied by
3336/// `std::less<LHS_TYPE *>`, and `false` otherwise.
3337template <class LHS_TYPE>
3338bool operator>=(const shared_ptr<LHS_TYPE>& lhs,
3340
3341/// Return `true` if the specified `rhs` shared pointer does not refer to an
3342/// object, or if the address of the object referred to by `rhs` is ordered
3343/// before the null-pointer value under the total ordering supplied by
3344/// `std::less<RHS_TYPE *>`, and `false` otherwise.
3345template <class RHS_TYPE>
3346bool operator>=(nullptr_t,
3348
3349#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3350
3351/// Print to the specified `stream` the address of the shared object
3352/// referred to by the specified `rhs` shared pointer and return a reference
3353/// to the modifiable `stream`.
3354template<class CHAR_TYPE, class CHAR_TRAITS, class ELEMENT_TYPE>
3355std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>&
3356operator<<(std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& stream,
3358
3359// ASPECTS
3360
3361/// Pass the address of the object referred to by the specified `input`
3362/// shared pointer to the specified `hashAlg` hashing algorithm of (template
3363/// parameter) type `HASHALG`.
3364template <class HASHALG, class ELEMENT_TYPE>
3365void hashAppend(HASHALG& hashAlg, const shared_ptr<ELEMENT_TYPE>& input);
3366
3367/// Efficiently exchange the states of the specified `a` and `b` shared
3368/// pointers such that each will refer to the object formerly referred to by
3369/// the other, and each will manage the object formerly managed by the
3370/// other.
3371template <class ELEMENT_TYPE>
3374
3375// STANDARD FREE FUNCTIONS
3376
3377/// Return the address of deleter used by the specified `p` shared pointer
3378/// if the (template parameter) type `DELETER` is the type of the deleter
3379/// installed in `p`, and a null pointer value otherwise.
3380template<class DELETER, class ELEMENT_TYPE>
3382
3383// STANDARD CAST FUNCTIONS
3384
3385/// Return a `shared_ptr<TO_TYPE>` object sharing ownership of the same
3386/// object as the specified `source` shared pointer to the (template
3387/// parameter) `FROM_TYPE`, and referring to `const_cast<TO_TYPE *>(source.get())`.
3388///
3389/// \note Note that if `source` cannot be
3390/// `const`-cast to `TO_TYPE *`, then a compiler diagnostic will be emitted
3391/// indicating the error.
3392template<class TO_TYPE, class FROM_TYPE>
3395
3396/// Return a `shared_ptr<TO_TYPE>` object sharing ownership of the same
3397/// object as the specified `source` shared pointer to the (template
3398/// parameter) `FROM_TYPE`, and referring to
3399/// `dynamic_cast<TO_TYPE*>(source.get())`. If `source` cannot be
3400/// dynamically cast to `TO_TYPE *`, then an empty `shared_ptr<TO_TYPE>`
3401/// object is returned.
3402template<class TO_TYPE, class FROM_TYPE>
3405
3406/// Return a `shared_ptr<TO_TYPE>` object sharing ownership of the same
3407/// object as the specified `source` shared pointer to the (template
3408/// parameter) `FROM_TYPE`, and referring to `static_cast<TO_TYPE *>(source.get())`.
3409///
3410/// \note Note that if `source` cannot be
3411/// statically cast to `TO_TYPE *`, then a compiler diagnostic will be
3412/// emitted indicating the error.
3413template<class TO_TYPE, class FROM_TYPE>
3416
3417/// Return a `shared_ptr<TO_TYPE>` object sharing ownership of the same
3418/// object as the specified `source` shared pointer to the (template
3419/// parameter) `FROM_TYPE`, and referring to `reinterpret_cast<TO_TYPE *>(source.get())`.
3420///
3421/// \note Note that if `source`
3422/// cannot be reinterpret_cast-ed to `TO_TYPE *`, then a compiler diagnostic
3423/// will be emitted indicating the error.
3424template<class TO_TYPE, class FROM_TYPE>
3427
3428
3429// STANDARD FACTORY FUNCTIONS
3430 // ===========================
3431 // allocate_shared(ALLOC, ...)
3432 // ===========================
3433
3434#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
3435
3436/// Return a `shared_ptr` object referring to and managing a new
3437/// `ELEMENT_TYPE` object. The specified `basicAllocator` will be used to
3438/// supply a single contiguous region of memory holding the returned shared
3439/// pointer's internal representation and the new `ELEMENT_TYPE` object,
3440/// which is initialized by calling `allocator_traits<ALLOC>::construct`
3441/// passing `basicAllocator`, an `ELEMENT_TYPE *` pointer to space for the
3442/// new shared object, and the specified arguments
3443/// `std::forward<ARGS>(args)...`.
3444template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
3447allocate_shared(ALLOC basicAllocator, ARGS&&... args);
3448
3449#endif
3450
3451/// Return a `shared_ptr` object referring to and managing a new
3452/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The
3453/// specified `basicAllocator` will be used to supply a single contiguous
3454/// region of memory holding the returned shared pointer's internal
3455/// representation and the new `ARRAY_TYPE` object, and each element in the
3456/// array is default constructed.
3457template<class ARRAY_TYPE, class ALLOC>
3461allocate_shared(ALLOC basicAllocator);
3462
3463/// Return a `shared_ptr` object referring to and managing a new
3464/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The
3465/// specified `basicAllocator` will be used to supply a single contiguous
3466/// region of memory holding the returned shared pointer's internal
3467/// representation and the new `ARRAY_TYPE` object, and each element in the
3468/// array is constructed from the specified `value`.
3469template<class ARRAY_TYPE, class ALLOC>
3473allocate_shared(ALLOC basicAllocator,
3474 const typename remove_extent<ARRAY_TYPE>::type& value);
3475
3476/// Return a `shared_ptr` object referring to and managing a new
3477/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a unbounded array. The
3478/// specified `basicAllocator` will be used to supply a single contiguous
3479/// region of memory holding the returned shared pointer's internal
3480/// representation and the new `ARRAY_TYPE` containing the specified
3481/// `numElements` number of elements, and each element in the array is
3482/// default constructed.
3483template<class ARRAY_TYPE, class ALLOC>
3487allocate_shared(ALLOC basicAllocator, size_t numElements);
3488
3489/// Return a `shared_ptr` object referring to and managing a new
3490/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a unbounded array. The
3491/// specified `basicAllocator` will be used to supply a single contiguous
3492/// region of memory holding the returned shared pointer's internal
3493/// representation and the new `ARRAY_TYPE` containing the specified
3494/// `numElements` number of elements, and each element in the array is
3495/// constructed from the specified `value`.
3496template<class ARRAY_TYPE, class ALLOC>
3500allocate_shared(ALLOC basicAllocator,
3501 size_t numElements,
3502 const typename remove_extent<ARRAY_TYPE>::type& value);
3503
3504 // =========================================
3505 // allocate_shared_for_overwrite(ALLOC, ...)
3506 // =========================================
3507
3508/// Return a `shared_ptr` object referring to and managing a new
3509/// `ELEMENT_TYPE` object. The specified `basicAllocator` will be used to
3510/// supply a single contiguous region of memory holding the returned shared
3511/// pointer's internal representation and the new `ELEMENT_TYPE` object,
3512/// which is default-constructed.
3513template<class ELEMENT_TYPE, class ALLOC>
3516allocate_shared_for_overwrite(ALLOC basicAllocator);
3517
3518/// Return a `shared_ptr` object referring to and managing a new
3519/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The
3520/// specified `basicAllocator` will be used to supply a single contiguous
3521/// region of memory holding the returned shared pointer's internal
3522/// representation and the new `ARRAY_TYPE` object, and the array is
3523/// default-constructed.
3524template<class ARRAY_TYPE, class ALLOC>
3528allocate_shared_for_overwrite(ALLOC basicAllocator);
3529
3530/// Return a `shared_ptr` object referring to and managing a new
3531/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a unbounded array. The
3532/// specified `basicAllocator` will be used to supply a single contiguous
3533/// region of memory holding the returned shared pointer's internal
3534/// representation and the new `ARRAY_TYPE` containing the specified
3535/// `numElements` number of elements, and the array is default-constructed.
3536template<class ARRAY_TYPE, class ALLOC>
3540allocate_shared_for_overwrite(ALLOC basicAllocator, size_t numElements);
3541
3542 // =============================
3543 // allocate_shared(ALLOC *, ...)
3544 // =============================
3545
3546#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
3547
3548/// Return a `shared_ptr` object referring to and managing a new
3549/// `ELEMENT_TYPE` object. The specified `basicAllocator` will be used to
3550/// supply a single contiguous region of memory holding the returned shared
3551/// pointer's internal representation and the new `ELEMENT_TYPE` object,
3552/// which is initialized using the `ELEMENT_TYPE` constructor that takes the
3553/// specified arguments `std::forward<ARGS>(args)...`. If `ELEMENT_TYPE`
3554/// uses `bslma` allocators, then `basicAllocator` is passed as an extra
3555/// argument in the final position. If `basicAllocator` is 0, then the
3556/// default allocator will be used instead, and passed as the allocator,
3557/// when appropriate, to the `ELEMENT_TYPE` constructor.
3558template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
3561allocate_shared(ALLOC *basicAllocator, ARGS&&... args);
3562#endif
3563
3564/// Return a `shared_ptr` object referring to and managing a new
3565/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The
3566/// specified `basicAllocator` will be used to supply a single contiguous
3567/// region of memory holding the returned shared pointer's internal
3568/// representation and the new `ARRAY_TYPE` object, and each element in the
3569/// array is default constructed. If `basicAllocator` is 0, then the
3570/// default allocator will be used instead.
3571template<class ARRAY_TYPE, class ALLOC>
3574allocate_shared(ALLOC *basicAllocator);
3575
3576/// Return a `shared_ptr` object referring to and managing a new
3577/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The
3578/// specified `basicAllocator` will be used to supply a single contiguous
3579/// region of memory holding the returned shared pointer's internal
3580/// representation and the new `ARRAY_TYPE` object, and each element in the
3581/// array is constructed from the specified `value`. If `basicAllocator`
3582/// is 0, then the default allocator will be used instead.
3583template<class ARRAY_TYPE, class ALLOC>
3587 ALLOC *basicAllocator,
3588 const typename remove_extent<ARRAY_TYPE>::type& value);
3589
3590/// Return a `shared_ptr` object referring to and managing a new
3591/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a unbounded array. The
3592/// specified `basicAllocator` will be used to supply a single contiguous
3593/// region of memory holding the returned shared pointer's internal
3594/// representation and the new `ARRAY_TYPE` containing the specified
3595/// `numElements` number of elements, and each element in the array is
3596/// default constructed. If `basicAllocator` is 0, then the default
3597/// allocator will be used instead.
3598template<class ARRAY_TYPE, class ALLOC>
3601allocate_shared(ALLOC *basicAllocator, size_t numElements);
3602
3603/// Return a `shared_ptr` object referring to and managing a new
3604/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a unbounded array. The
3605/// specified `basicAllocator` will be used to supply a single contiguous
3606/// region of memory holding the returned shared pointer's internal
3607/// representation and the new `ARRAY_TYPE` containing the specified
3608/// `numElements` number of elements, and each element in the array is
3609/// constructed from the specified `value`. If `basicAllocator` is 0, then
3610/// the default allocator will be used instead.
3611template<class ARRAY_TYPE, class ALLOC>
3615 ALLOC *basicAllocator,
3616 size_t numElements,
3617 const typename remove_extent<ARRAY_TYPE>::type& value);
3618
3619 // ===========================================
3620 // allocate_shared_for_overwrite(ALLOC *, ...)
3621 // ===========================================
3622
3623/// Return a `shared_ptr` object referring to and managing a new
3624/// `ELEMENT_TYPE` object. The specified `basicAllocator` will be used to
3625/// supply a single contiguous region of memory holding the returned shared
3626/// pointer's internal representation and the new `ELEMENT_TYPE` object,
3627/// which is default-constructed. If `basicAllocator` is 0, then the
3628/// default allocator will be used instead.
3629template<class ELEMENT_TYPE, class ALLOC>
3632allocate_shared_for_overwrite(ALLOC *basicAllocator);
3633
3634/// Return a `shared_ptr` object referring to and managing a new
3635/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The
3636/// specified `basicAllocator` will be used to supply a single contiguous
3637/// region of memory holding the returned shared pointer's internal
3638/// representation and the new `ARRAY_TYPE` object, and the array is
3639/// default-constructed. If `basicAllocator` is 0, then the default
3640/// allocator will be used instead.
3641template<class ARRAY_TYPE, class ALLOC>
3644allocate_shared_for_overwrite(ALLOC *basicAllocator);
3645
3646/// Return a `shared_ptr` object referring to and managing a new
3647/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a unbounded array. The
3648/// specified `basicAllocator` will be used to supply a single contiguous
3649/// region of memory holding the returned shared pointer's internal
3650/// representation and the new `ARRAY_TYPE` containing the specified
3651/// `numElements` number of elements, and the array is default-constructed.
3652/// If `basicAllocator` is 0, then the default allocator will be used
3653/// instead.
3654template<class ARRAY_TYPE, class ALLOC>
3657allocate_shared_for_overwrite(ALLOC *basicAllocator, size_t numElements);
3658
3659 // ================
3660 // make_shared(...)
3661 // ================
3662
3663#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
3664
3665/// Return a `shared_ptr` object referring to and managing a new
3666/// `ELEMENT_TYPE` object. The default allocator will be used to supply a
3667/// single contiguous region of memory holding the returned shared pointer's
3668/// internal representation and the new `ELEMENT_TYPE` object, which is
3669/// initialized using the `ELEMENT_TYPE` constructor that takes the
3670/// specified arguments `std::forward<ARGS>(args)...`. If `ELEMENT_TYPE`
3671/// uses `bslma` allocators, then the default allocator is passed as an
3672/// extra argument in the final position.
3673template<class ELEMENT_TYPE, class... ARGS>
3676make_shared(ARGS&&... args);
3677#endif
3678
3679/// Return a `shared_ptr` object referring to and managing a new
3680/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The default
3681/// allocator will be used to supply a single contiguous region of memory
3682/// holding the returned shared pointer's internal representation and the
3683/// new `ARRAY_TYPE` object, and each element in the array is default
3684/// constructed.
3685template<class ARRAY_TYPE>
3689
3690/// Return a `shared_ptr` object referring to and managing a new
3691/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The default
3692/// allocator will be used to supply a single contiguous region of memory
3693/// holding the returned shared pointer's internal representation and the
3694/// new `ARRAY_TYPE` object, and each element in the array is constructed
3695/// from the specified `value`.
3696template<class ARRAY_TYPE>
3700
3701// unbounded array overloads
3702
3703/// Return a `shared_ptr` object referring to and managing a new `ARRAY_TYPE`
3704/// object, where `ARRAY_TYPE` is a unbounded array. The default allocator
3705/// will be used to supply a single contiguous region of memory holding the
3706/// returned shared pointer's internal representation and the new `ARRAY_TYPE`
3707/// containing the specified `numElements` number of elements, and each element
3708/// in the array is default constructed.
3709template<class ARRAY_TYPE>
3712make_shared(size_t numElements);
3713
3714/// Return a `shared_ptr` object referring to and managing a new `ARRAY_TYPE`
3715/// object, where `ARRAY_TYPE` is a unbounded array. The default allocator
3716/// will be used to supply a single contiguous region of memory holding the
3717/// returned shared pointer's internal representation and the new `ARRAY_TYPE`
3718/// containing the specified `numElements` number of elements, and each element
3719/// in the array is constructed from the specified `value`.
3720template<class ARRAY_TYPE>
3723make_shared(size_t numElements,
3724 const typename remove_extent<ARRAY_TYPE>::type& value);
3725
3726 // ==============================
3727 // make_shared_for_overwrite(...)
3728 // ==============================
3729
3730/// Return a `shared_ptr` object referring to and managing a new
3731/// `ELEMENT_TYPE` object. The default allocator will be used to supply a
3732/// single contiguous region of memory holding the returned shared pointer's
3733/// internal representation and the new `ELEMENT_TYPE` object, which is
3734/// default-constructed.
3735template<class ELEMENT_TYPE>
3739
3740/// Return a `shared_ptr` object referring to and managing a new
3741/// `ARRAY_TYPE` object, where `ARRAY_TYPE` is a bounded array. The default
3742/// allocator will be used to supply a single contiguous region of memory
3743/// holding the returned shared pointer's internal representation and the
3744/// new `ARRAY_TYPE` object, and the array is default-constructed.
3745template<class ARRAY_TYPE>
3749
3750/// Return a `shared_ptr` object referring to and managing a new `ARRAY_TYPE`
3751/// object, where `ARRAY_TYPE` is a unbounded array. The default allocator
3752/// will be used to supply a single contiguous region of memory holding the
3753/// returned shared pointer's internal representation and the new `ARRAY_TYPE`
3754/// containing the specified `numElements` number of elements, and the array is
3755/// default-constructed.
3756template<class ARRAY_TYPE>
3759make_shared_for_overwrite(size_t numElements);
3760
3761 // ==============
3762 // class weak_ptr
3763 // ==============
3764
3765/// This `class` provides a mechanism to create weak references to
3766/// reference-counted shared (`shared_ptr`) objects. A weak reference
3767/// provides conditional access to a shared object managed by a
3768/// `shared_ptr`, but, unlike a shared (or "strong") reference, does not
3769/// affect the shared object's lifetime.
3770///
3771/// See @ref bslstl_sharedptr
3772template <class ELEMENT_TYPE>
3774
3775 // DATA
3776 ELEMENT_TYPE *d_ptr_p; // pointer to the referenced
3777 // object
3778
3779 BloombergLP::bslma::SharedPtrRep *d_rep_p; // pointer to the representation
3780 // object that manages the
3781 // shared object (held, not
3782 // owned)
3783
3784 // PRIVATE MANIPULATORS
3785
3786 /// Release weak ownership of the currently managed shared pointer rep
3787 /// and assign to this weak pointer weak ownership of the specified
3788 /// shared pointer `rep`, aliasing the specified `target` pointer.
3789 void privateAssign(BloombergLP::bslma::SharedPtrRep *rep,
3790 ELEMENT_TYPE *target);
3791
3792 // FRIENDS
3793
3794 /// This `friend` declaration provides access to the internal data
3795 /// members while constructing a weak pointer from a weak pointer of a
3796 /// different type.
3797 template <class COMPATIBLE_TYPE>
3798 friend class weak_ptr;
3799
3801
3802 public:
3803 // TRAITS
3806
3807 // TYPES
3808
3809 /// For weak pointers to non-array types, @ref element_type is an alias to
3810 /// the `ELEMENT_TYPE` template parameter. Otherwise, it is an alias to
3811 /// the type contained in the array.
3813
3814 // CREATORS
3815
3816 /// Create a weak pointer in the empty state and referring to no object,
3817 /// i.e., a weak pointer having no representation.
3820
3821 /// Create a weak pointer that refers to the same object (if any) as the
3822 /// specified `original` weak pointer, and reset `original` to an empty
3823 /// state.
3824 weak_ptr(BloombergLP::bslmf::MovableRef<weak_ptr> original)
3826
3827 /// Create a weak pointer that refers to the same object (if any) as the
3828 /// specified `other` weak pointer, and reset `original` to an empty state.
3829 ///
3830 /// \note Note that this operation does not involve any change to
3831 /// reference counts.
3832#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3833 template <class COMPATIBLE_TYPE
3836#else
3837 template <class COMPATIBLE_TYPE
3839 weak_ptr(BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > other)
3841#endif
3842
3843 /// Create a weak pointer that refers to the same object (if any) as the
3844 /// specified `original` weak pointer, and increment the number of weak
3845 /// references to the object managed by `original` (if any).
3846 ///
3847 /// \note Note that if `original` is in the empty state, this weak pointer will be
3848 /// initialized to the empty state.
3850
3851 /// Create a weak pointer that refers to the same object (if any) as the
3852 /// specified `other` (shared or weak) pointer of the (template
3853 /// parameter) `COMPATIBLE_TYPE`, and increment the number of weak
3854 /// references to the object managed by `other` (if any). If
3855 /// `COMPATIBLE_TYPE *` is not implicitly convertible to
3856 /// `ELEMENT_TYPE *`, then a compiler diagnostic will be emitted.
3857 ///
3858 /// \note Note that if `other` is in the empty state, this weak pointer will be
3859 /// initialized to the empty state.
3860 template <class COMPATIBLE_TYPE
3863 // IMPLICIT
3864 template <class COMPATIBLE_TYPE
3867 // IMPLICIT
3868
3869 /// Destroy this weak pointer object. If this weak pointer manages a
3870 /// (possibly shared) object, release the weak reference to that object.
3872
3873 // MANIPULATORS
3874
3875 /// Make this weak pointer refer to the same object (if any) as the
3876 /// specified `rhs` weak pointer. If `rhs` is not a reference to this
3877 /// weak pointer, decrement the number of weak references to the object
3878 /// this weak pointer managed (if any), and reset `rhs` to an empty
3879 /// state. Return a reference providing modifiable access to this weak pointer.
3880 ///
3881 /// \note Note that if `rhs` is in an empty state, this weak pointer
3882 /// will be set to an empty state.
3883 weak_ptr& operator=(BloombergLP::bslmf::MovableRef<weak_ptr> rhs)
3885
3886 /// Make this weak pointer refer to the same object (if any) as the
3887 /// specified `rhs` weak pointer. Decrement the number of weak
3888 /// references to the object this weak pointer manages (if any), and
3889 /// increment the number of weak references to the object managed by
3890 /// `rhs` (if any). Return a reference providing modifiable access to this weak pointer.
3891 ///
3892 /// \note Note that if `rhs` is in an empty state, this
3893 /// weak pointer will be set to an empty state.
3895
3896 /// Make this weak pointer refer to the same object (if any) as the
3897 /// specified `rhs` weak pointer. Decrement the number of weak
3898 /// references to the object this weak pointer managed (if any), and
3899 /// reset `rhs` to an empty state. Return a reference providing
3900 /// modifiable access to this weak pointer. This function does not
3901 /// exist unless a pointer to (the template parameter) `COMPATIBLE_TYPE`
3902 /// is convertible to a pointer to (the template parameter) `ELEMENT_TYPE`.
3903 ///
3904 /// \note Note that if `rhs` is in an empty state, this weak
3905 /// pointer will be set to an empty state.
3906#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3907 template <class COMPATIBLE_TYPE>
3908 typename enable_if<
3911#else
3912 template <class COMPATIBLE_TYPE>
3913 typename enable_if<
3915 operator=(BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > rhs)
3917#endif
3918
3919 template <class COMPATIBLE_TYPE>
3920 typename enable_if<
3923
3924 /// Make this weak pointer refer to the same object (if any) as the
3925 /// specified `rhs` (shared or weak) pointer to the (template parameter)
3926 /// `COMPATIBLE_TYPE`. Decrement the number of weak references to the
3927 /// object to which this weak pointer currently manages (if any), and
3928 /// increment the number of weak references to the object managed by
3929 /// `rhs` (if any). Return a reference providing modifiable access to
3930 /// this weak pointer. If `COMPATIBLE_TYPE *` is not implicitly
3931 /// convertible to `TYPE *`, then a compiler diagnostic will be emitted.
3932 ///
3933 /// \note Note that if `rhs` is in the empty state, this weak pointer will be
3934 /// set to the empty state.
3935 template <class COMPATIBLE_TYPE>
3936 typename enable_if<
3939
3940 /// Reset this weak pointer to the empty state. If this weak pointer
3941 /// manages a (possibly shared) object, then decrement the number of
3942 /// weak references to that object.
3944
3945 /// Efficiently exchange the states of this weak pointer and the
3946 /// specified `other` weak pointer such that each will refer to the
3947 /// object (if any) and representation (if any) formerly referred to and
3948 /// managed by the other.
3950
3951 // ACCESSORS
3952
3953 /// Return `true` if this weak pointer is in the empty state or the
3954 /// object that it originally referenced has been destroyed, and `false`
3955 /// otherwise.
3957
3958 /// Return a shared pointer to the object referred to by this weak
3959 /// pointer if `false == expired()`, and a shared pointer in the empty
3960 /// state otherwise.
3962
3963 template <class ANY_TYPE>
3964 bool owner_before(const shared_ptr<ANY_TYPE>& other) const
3966
3967 /// Return `true` if the address of the
3968 /// `BloombergLP::bslma::SharedPtrRep` object used by this weak pointer
3969 /// is ordered before the address of the
3970 /// `BloombergLP::bslma::SharedPtrRep` object used by the specified
3971 /// `other` shared pointer under the total ordering defined by
3972 /// `std::less<BloombergLP::bslma::SharedPtrRep *>`, and `false`
3973 /// otherwise.
3974 template <class ANY_TYPE>
3975 bool owner_before(const weak_ptr<ANY_TYPE>& other) const
3977
3978 template<class ANY_TYPE>
3979 bool owner_equal(const shared_ptr<ANY_TYPE>& other) const
3981
3982 /// Return `true` if the address of the
3983 /// `BloombergLP::bslma::SharedPtrRep` object used by this shared
3984 /// pointer is equal to the address of the
3985 /// `BloombergLP::bslma::SharedPtrRep` object used by the specified
3986 /// `other` shared pointer, and `false` otherwise.
3987 template<class ANY_TYPE>
3988 bool owner_equal(const weak_ptr<ANY_TYPE>& other) const
3990
3991 /// Return an unspecified value such that, for any object `x` where
3992 /// `owner_equal(x)` is true, `owner_hash() == x.owner_hash()` is true.
3993 ///
3994 /// \note Note that this is based on the hash of the address of the
3995 /// `BloombergLP::bslma::SharedPtrRep` object used by this object.
3996 /// Note also that for two empty smart pointers `x` and `y`,
3997 /// `x.owner_hash() == y.owner_hash()` is true.
3999
4000 /// Return the address providing modifiable access to the
4001 /// `BloombergLP::bslma::SharedPtrRep` object held by this weak pointer,
4002 /// or 0 if this weak pointer is in the empty state.
4003 BloombergLP::bslma::SharedPtrRep *rep() const BSLS_KEYWORD_NOEXCEPT;
4004
4005 /// Return a "snapshot" of the current number of shared pointers that
4006 /// share ownership of the object referred to by this weak pointer, or 0 if this weak pointer is in the empty state.
4007 ///
4008 /// \note Note that any result
4009 /// other than 0 may be unreliable in a multi-threaded program, where
4010 /// another pointer sharing ownership in a different thread may be
4011 /// copied or destroyed, or another weak pointer may be locked in the
4012 /// case that 1 is returned (that would otherwise indicate unique
4013 /// ownership).
4015
4016#ifndef BDE_OMIT_INTERNAL_DEPRECATED
4017 // DEPRECATED BDE LEGACY ACCESSORS
4018
4019 /// Return a shared pointer to the object referred to by this weak
4020 /// pointer and managing the same object as that managed by this weak
4021 /// pointer (if any) if `false == expired()`, and a shared pointer in the empty state otherwise.
4022 ///
4023 /// \note Note that the behavior of this method is
4024 /// the same as that of `lock`.
4026
4027 /// Return a "snapshot" of the current number of shared pointers that
4028 /// share ownership of the object referred to by this weak pointer, or 0 if this weak pointer is in the empty state.
4029 ///
4030 /// \note Note that the behavior
4031 /// of this method is the same as that of @ref use_count , and the result
4032 /// may be unreliable in multi-threaded code for the same reasons.
4033 ///
4034 /// @deprecated Use @ref use_count instead.
4036#endif // BDE_OMIT_INTERNAL_DEPRECATED
4037};
4038
4039#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
4040// CLASS TEMPLATE DEDUCTION GUIDES
4041
4042/// Deduce the specified type `ELEMENT_TYPE` corresponding template
4043/// parameter of the `bsl::shared_ptr` supplied to the constructor of
4044/// `weak_ptr`.
4045template<class ELEMENT_TYPE>
4047#endif
4048
4049 //==============================
4050 // class enable_shared_from_this
4051 //==============================
4052
4053/// This class allows an object that is currently managed by a `shared_ptr`
4054/// to safely generate a copy of the managing `shared_ptr` object.
4055/// Inheriting from `enable_shared_from_this<ELEMENT_TYPE>` provides the
4056/// (template parameter) `ELEMENT_TYPE` type with a member function
4057/// @ref shared_from_this . If an object of type `ELEMENT_TYPE` is managed by a
4058/// `shared_ptr` then calling @ref shared_from_this will return a
4059/// `shared_ptr<ELEMENT_TYPE>` that shares ownership of that object. It is
4060/// undefined behavior to call @ref shared_from_this on an object unless that
4061/// object is managed by a `shared_ptr`.
4062///
4063/// The intended use of @ref enable_shared_from_this is that the (template
4064/// parameter) type `ELEMENT_TYPE` inherits directly from the
4065/// @ref enable_shared_from_this class template. In the case of multiple
4066/// inheritance, only one of the base classes should inherit from the
4067/// @ref enable_shared_from_this class template. If multiple base classes
4068/// inherit from @ref enable_shared_from_this , then there will be ambiguous
4069/// calls to the @ref shared_from_this function.
4070///
4071/// See @ref bslstl_sharedptr
4072template<class ELEMENT_TYPE>
4074
4075 // FRIENDS
4076
4077 /// Allows `shared_ptr` to initialize `d_weakThis` when it detects an
4078 /// @ref enable_shared_from_this base class.
4080
4081 private:
4082 // DATA
4083 mutable bsl::weak_ptr<ELEMENT_TYPE> d_weakThis;
4084
4085 protected:
4086 // PROTECTED CREATORS
4087
4088 /// Create an @ref enable_shared_from_this object that is not owned by any
4089 /// `shared_ptr` object.
4091
4092 /// Create an @ref enable_shared_from_this object that is not owned by any `shared_ptr` object.
4093 ///
4094 /// \note Note that the specified `unused` argument is
4095 /// not used by this constructor.
4098
4099 /// Destroy this @ref enable_shared_form_this .
4101
4102 // PROTECTED MANIPULATORS
4103
4104 /// Return `*this`. This object is unchanged.
4105 /// \note Note that the specified
4106 /// `rhs` is not used.
4109
4110 public:
4111 // MANIPULATORS
4112
4113 /// Return a `shared_ptr<ELEMENT_TYPE>` that shares ownership with an
4114 /// existing `shared_ptr` object that managed this object, and throw a
4115 /// `std::bad_weak_ptr` exception if there is no `shared_ptr` currently
4116 /// managing this object. If multiple groups of `shared_ptr`s are
4117 /// managing this object, the returned `shared_ptr` will share ownership
4118 /// with the group that first managed this object.
4120
4121 /// Return a `weak_ptr` holding a weak reference to this managed object
4122 /// if this object is currently managed by `shared_ptr`, and return an
4123 /// expired `weak_ptr` otherwise. If multiple groups of `shared_ptr`s
4124 /// are managing this object, the returned `weak_ptr` will hold a weak
4125 /// reference to the group that first managed this object.
4127
4128 // ACCESSORS
4129
4130 /// Return a `shared_ptr<const ELEMENT_TYPE>` that shares ownership with
4131 /// an existing `shared_ptr` object that managed this object, and throw
4132 /// a `std::bad_weak_ptr` exception if there is no `shared_ptr`
4133 /// currently managing this object. If multiple groups of `shared_ptr`s
4134 /// are managing this object, the returned `shared_ptr` will share
4135 /// ownership with the group that first managed this object.
4136 bsl::shared_ptr<const ELEMENT_TYPE> shared_from_this() const;
4137
4138
4139 /// Return a `weak_ptr` holding a weak reference (with only `const`
4140 /// access) to this managed object if this object is currently managed
4141 /// by `shared_ptr`, and return an expired `weak_ptr` otherwise. If
4142 /// multiple groups of `shared_ptr`s are managing this object, the
4143 /// returned `weak_ptr` will hold a weak reference to the group that
4144 /// first managed this object.
4145 bsl::weak_ptr<const ELEMENT_TYPE> weak_from_this() const
4147};
4148
4149// ASPECTS
4150
4151/// Efficiently exchange the states of the specified `a` and `b` weak
4152/// pointers such that each will refer to the object (if any) and
4153/// representation formerly referred to by the other.
4154template <class ELEMENT_TYPE>
4155void swap(weak_ptr<ELEMENT_TYPE>& a, weak_ptr<ELEMENT_TYPE>& b)
4157
4158 // =========================
4159 // class hash specialization
4160 // =========================
4161
4162// A partial specialization of 'bsl::hash' is no longer necessary, as the
4163// primary template has the correct behavior once 'hashAppend' is defined.
4164
4165} // close namespace bsl
4166
4167
4168namespace bslstl {
4169
4170 // ====================
4171 // struct SharedPtrUtil
4172 // ====================
4173
4174/// This `struct` provides a namespace for operations on shared pointers.
4175///
4176/// See @ref bslstl_sharedptr
4178
4179 // CLASS METHODS
4180
4181 /// Return a shared pointer with an in-place representation holding a
4182 /// newly-created uninitialized buffer of the specified `bufferSize` (in
4183 /// bytes). Optionally specify a `basicAllocator` used to supply
4184 /// memory. If `basicAllocator` is 0, the currently installed default allocator is used.
4185 ///
4186 /// \pre The behavior is undefined unless
4187 /// `0 < bufferSize`.
4188 static
4191 bslma::Allocator *basicAllocator = 0);
4192
4193 // CASTING FUNCTIONS
4194
4195 /// Load into the specified `target` an aliased shared pointer sharing
4196 /// ownership of the object managed by the specified `source` shared
4197 /// pointer and referring to `const_cast<TARGET *>(source.get())`. If
4198 /// `*target` is already managing a (possibly shared) object, then
4199 /// release the shared reference to that object, and destroy it using
4200 /// its associated deleter if that shared pointer held the last shared reference to that object.
4201 ///
4202 /// \note Note that a compiler diagnostic will be
4203 /// emitted indicating an error unless
4204 /// `const_cast<TARGET *>(source.get())` is a valid expression.
4205 template <class TARGET, class SOURCE>
4206 static
4207 void constCast(bsl::shared_ptr<TARGET> *target,
4208 const bsl::shared_ptr<SOURCE>& source);
4209
4210 /// Return a `bsl::shared_ptr<TARGET>` object sharing ownership of the
4211 /// same object as the specified `source` shared pointer to the
4212 /// (template parameter) `SOURCE` type, and referring to `const_cast<TARGET *>(source.get())`.
4213 ///
4214 /// \note Note that a compiler
4215 /// diagnostic will be emitted indicating an error unless
4216 /// `const_cast<TARGET *>(source.get())` is a valid expression.
4217 template <class TARGET, class SOURCE>
4218 static
4219 bsl::shared_ptr<TARGET> constCast(const bsl::shared_ptr<SOURCE>& source)
4221
4222 /// Load into the specified `target` an aliased shared pointer sharing
4223 /// ownership of the object managed by the specified `source` shared
4224 /// pointer and referring to `dynamic_cast<TARGET *>(source.get())`. If
4225 /// `*target` is already managing a (possibly shared) object, then
4226 /// release the shared reference to that object, and destroy it using
4227 /// its associated deleter if that shared pointer held the last shared
4228 /// reference to that object. If
4229 /// `0 == dynamic_cast<TARGET*>(source.get())`, then `*target` shall be
4230 /// reset to an empty state that does not refer to an object.
4231 ///
4232 /// \note Note that a compiler diagnostic will be emitted indicating an error unless
4233 /// `dynamic_cast<TARGET *>(source.get())` is a valid expression.
4234 template <class TARGET, class SOURCE>
4235 static
4236 void dynamicCast(bsl::shared_ptr<TARGET> *target,
4237 const bsl::shared_ptr<SOURCE>& source);
4238
4239 /// Return a `bsl::shared_ptr<TARGET>` object sharing ownership of the
4240 /// same object as the specified `source` shared pointer to the
4241 /// (template parameter) `SOURCE` type, and referring to
4242 /// `dynamic_cast<TARGET *>(source.get())`. If that would return a
4243 /// shared pointer referring to nothing (`0 == get()`), then instead return an (empty) default constructed shared pointer.
4244 ///
4245 /// \note Note that a
4246 /// compiler diagnostic will be emitted indicating an error unless
4247 /// `dynamic_cast<TARGET *>(source.get())` is a valid expression..
4248 template <class TARGET, class SOURCE>
4249 static
4250 bsl::shared_ptr<TARGET> dynamicCast(const bsl::shared_ptr<SOURCE>& source)
4252
4253 /// Load into the specified `target` an aliased shared pointer sharing
4254 /// ownership of the object managed by the specified `source` shared
4255 /// pointer and referring to `static_cast<TARGET *>(source.get())`. If
4256 /// `*target` is already managing a (possibly shared) object, then
4257 /// release the shared reference to that object, and destroy it using
4258 /// its associated deleter if that shared pointer held the last shared reference to that object.
4259 ///
4260 /// \note Note that a compiler diagnostic will be
4261 /// emitted indicating an error unless
4262 /// `static_cast<TARGET *>(source.get())` is a valid expression.
4263 template <class TARGET, class SOURCE>
4264 static
4265 void staticCast(bsl::shared_ptr<TARGET> *target,
4266 const bsl::shared_ptr<SOURCE>& source);
4267
4268 /// Return a `bsl::shared_ptr<TARGET>` object sharing ownership of the
4269 /// same object as the specified `source` shared pointer to the
4270 /// (template parameter) `SOURCE` type, and referring to `static_cast<TARGET *>(source.get())`.
4271 ///
4272 /// \note Note that a compiler
4273 /// diagnostic will be emitted indicating an error unless
4274 /// `static_cast<TARGET *>(source.get())` is a valid expression.
4275 template <class TARGET, class SOURCE>
4276 static
4277 bsl::shared_ptr<TARGET> staticCast(const bsl::shared_ptr<SOURCE>& source)
4279};
4280
4281 // ==========================
4282 // struct SharedPtrNilDeleter
4283 // ==========================
4284
4285/// This `struct` provides a function-like shared pointer deleter that does
4286/// nothing when invoked.
4287///
4288/// See @ref bslstl_sharedptr
4290
4291 // ACCESSORS
4292
4293 /// No-Op.
4294 void operator()(const volatile void *) const BSLS_KEYWORD_NOEXCEPT;
4295};
4296
4297 // ===============================
4298 // struct SharedPtr_DefaultDeleter
4299 // ===============================
4300
4301/// This `struct` provides a function-like shared pointer deleter that
4302/// invokes `delete` with the passed pointer. If the template parameter is
4303/// `true`, then the pointer is deleted using `operator delete []`.
4304/// Otherwise, it is deleted using `operator delete`.
4305///
4306/// See @ref bslstl_sharedptr
4307template <bool>
4309
4310 // ACCESSORS
4311
4312 /// Call `delete` with the specified `ptr`.
4313 template <class ANY_TYPE>
4314 void operator()(ANY_TYPE *ptr) const BSLS_KEYWORD_NOEXCEPT;
4315};
4316
4317 //=========================
4318 // struct SharedPtr_ImpUtil
4319 //=========================
4320
4321/// This `struct` should be used by only `shared_ptr` constructors. Its
4322/// purpose is to enable `shared_ptr` constructors to determine if the
4323/// (template parameter) types `COMPATIBLE_TYPE` or `ELEMENT_TYPE` have a
4324/// specialization of @ref enable_shared_from_this as an unambiguous, publicly
4325/// accessible, base class.
4326///
4327/// See @ref bslstl_sharedptr
4329
4330 // PUBLIC TYPES
4331#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
4332 template <class TYPE, unsigned DIM = 0>
4333 struct Extent : std::extent<TYPE, DIM> {};
4334#else
4335 template <class TYPE, unsigned DIM = 0>
4336 struct Extent : public bsl::integral_constant<size_t, 0> {};
4337
4338 template <class TYPE>
4339 struct Extent<TYPE[], 0> : public bsl::integral_constant<size_t, 0> {};
4340
4341 template <class TYPE, unsigned DIM>
4342 struct Extent<TYPE[], DIM>
4343 : public bsl::integral_constant<size_t, Extent<TYPE, DIM-1>::value> {};
4344
4345 template <class TYPE, size_t SIZE>
4346 struct Extent<TYPE[SIZE], 0>
4347 : public bsl::integral_constant<size_t, SIZE> {};
4348
4349 template <class TYPE, size_t SIZE, unsigned DIM>
4350 struct Extent<TYPE[SIZE], DIM>
4351 : public bsl::integral_constant<size_t, Extent<TYPE, DIM-1>::value> {};
4352#endif
4353
4354 // CLASS METHODS
4355
4356 /// Load the specified `result` with the control block (i.e.,
4357 /// `SharedPtrRep`) from the specified `sharedPtr` if (and only if)
4358 /// `result` is not 0 and `result` does not already refer to a
4359 /// non-expired shared-pointer control block. If `result` is 0, or if
4360 /// `result->d_weakThis` has not expired, this operation has no effect.
4361 /// This operation is used to initialize data members from a type that
4362 /// inherits from @ref enable_shared_from_this when constructing an
4363 /// out-of-place shared pointer representation. This function shall be
4364 /// called only by `shared_ptr` constructors creating shared pointers
4365 /// for classes that derive publicly and unambiguously from a specialization of `enabled_shared_from_this`.
4366 ///
4367 /// \note Note that overload
4368 /// resolution will select the overload below if a supplied type does
4369 /// not derive from a specialization of @ref enable_shared_from_this .
4370 template<class SHARED_TYPE, class ENABLE_TYPE>
4371 static void loadEnableSharedFromThis(
4373 bsl::shared_ptr<SHARED_TYPE> *sharedPtr);
4374
4375 /// Do nothing. This overload is selected, rather than the immediately
4376 /// preceding template, when the `SHARED_TYPE` template type parameter
4377 /// of `shared_ptr<SHARED_TYPE>` does not derive from a specialization
4378 /// of @ref enable_shared_from_this .
4379 static void loadEnableSharedFromThis(const volatile void *, const void *)
4381
4382 /// Throw a `bsl::bad_weak_ptr` exception.
4383 static void throwBadWeakPtr();
4384};
4385
4386 // ==========================
4387 // class SharedPtr_RepProctor
4388 // ==========================
4389
4390/// This `class` implements a proctor that, unless its `release` method has
4391/// previously been invoked, automatically releases a reference held by the
4392/// `bslma::SharedPtrRep` object that is supplied at construction.
4393///
4394/// See @ref bslstl_sharedptr
4396
4397 private:
4398 // DATA
4399 bslma::SharedPtrRep *d_rep_p; // Address of representation being managed
4400
4401 private:
4402 // NOT IMPLEMENTED
4404 SharedPtr_RepProctor& operator=(const SharedPtr_RepProctor&);
4405
4406 public:
4407 // CREATORS
4408
4409 /// Create a `SharedPtr_RepProctor` that conditionally manages the
4410 /// specified `rep` (if non-zero).
4413
4414 /// Destroy this `SharedPtr_RepProctor`, and dispose of (deallocate) the
4415 /// `bslma::SharedPtrRep` it manages (if any). If no such object is currently being managed, this method has no effect.
4416 ///
4417 /// \note Note that the
4418 /// destructor of the `bslma::SharedPtrRep` will not be called as the
4419 /// reference count will not be decremented.
4421
4422 // MANIPULATORS
4423
4424 /// Release from management the object currently managed by this
4425 /// proctor. If no object is currently being managed, this method has
4426 /// no effect.
4427 void release() BSLS_KEYWORD_NOEXCEPT;
4428};
4429
4430} // close package namespace
4431
4432
4433// ============================================================================
4434// INLINE DEFINITIONS
4435// ============================================================================
4436
4437#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
4438
4439namespace bslstl {
4440
4441#if defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE) && \
4442 defined(BSLS_PLATFORM_CMP_MSVC) && \
4443 BSLS_PLATFORM_CMP_VERSION >= 1936 && BSLS_PLATFORM_CMP_VERSION <= 1937
4444// Microsoft needs a workaround to correctly handle calling `sizeof` on an
4445// unevaluated expression. This compiler bug was introduced in Visual Studio
4446// 2022 version 17.6 (cl 19.36, released May 2022). The report to Microsoft is
4447// https://developercommunity.visualstudio.com/t/C-templates:-new-compiler-error-in-MSV/10381900
4448
4449# define BSLSTL_SHAREDPTR_MSVC_DECLTYPE_WORKAROUND(...) decltype(__VA_ARGS__)
4450#else
4451# define BSLSTL_SHAREDPTR_MSVC_DECLTYPE_WORKAROUND(...) (__VA_ARGS__)
4452#endif
4453
4454template <class FUNCTOR>
4455struct SharedPtr_TestIsCallable {
4456 private:
4457 // PRIVATE TYPES
4458 typedef BloombergLP::bslmf::Util Util;
4459
4460 struct TrueType {
4461 char d_padding;
4462 };
4463 struct FalseType {
4464 char d_padding[17];
4465 };
4466
4467 // The two structs `TrueType` and `FalseType` are guaranteed to have
4468 // distinct sizes, so that a `sizeof(expression)` query, where `expression`
4469 // returns one of these two types, will give different answers depending on
4470 // which type is returned.
4471
4472 public:
4473 // CLASS METHODS
4474
4475 /// This function is never defined. It provides a property-checker that
4476 /// an entity of (template parameter) type `FACTORY` can be called like
4477 /// a function with a single argument, which is a pointer to an object
4478 /// of (template parameter) type `ARG`. The `sizeof()` expression
4479 /// provides an unevaluated context to check the validity of the
4480 /// enclosed expression, and the `, 0` ensures that the `sizeof` check
4481 /// remains valid, even if the expression returns `void`. Similarly,
4482 /// the cast to `void` ensures that there are no surprises with types that overload the comma operator.
4483 ///
4484 /// \note Note that the cast to `void` is
4485 /// elided for Clang compilers using versions of LLVM prior to
4486 /// 12, which fail to evaluate the trait properly.
4487 ///
4488 /// \note Note that `sizeof(decltype())` is required for MSVC due to a compiler bug in
4489 /// MSVC 17.6 and later (at least including 17.7.0 Preview 2.0).
4490 template <class ARG>
4491 static FalseType test(...);
4492 template <class ARG>
4493 static TrueType
4494 test(typename bsl::enable_if<
4495 static_cast<bool>(
4496 sizeof(BSLSTL_SHAREDPTR_MSVC_DECLTYPE_WORKAROUND(
4497 BSLSTL_SHAREDPTR_SFINAE_DISCARD(
4498 Util::declval<FUNCTOR>()(Util::declval<ARG>())),
4499 0)))>::type *);
4500};
4501
4502#if defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1920
4503// Microsoft needs a workaround to correctly handle calling through function
4504// pointers with incompatible types in Visual Studio 2017. In Visual Studio
4505// 2019 the workaround isn't needed and crashes the compiler if enabled!
4506// (Visual Studio versions prior to 2017 appear to not need the workaround,
4507// based on further testing, but it's being left in place so as not to alter
4508// this code for people using older compiler versions.)
4509
4510template <class RESULT, class PARAM>
4511struct SharedPtr_TestIsCallable<RESULT(PARAM)> {
4512 private:
4513 // PRIVATE TYPES
4514 typedef BloombergLP::bslmf::Util Util;
4515
4516 struct TrueType { char d_padding; };
4517 struct FalseType { char d_padding[17]; };
4518
4519 // PRIVATE CLASS METHODS
4520 static RESULT callMe(PARAM);
4521
4522 public:
4523 // CLASS METHODS
4524
4525 // This function is never defined. It provides a property-checker that
4526 // an entity of (template parameter) type `FACTORY` can be called like
4527 // a function with a single argument, which is a pointer to an object
4528 // of (template parameter) type `ARG`. The `sizeof` expression
4529 // provides an unevaluated context to check the validity of the
4530 // enclosed expression, and the `, 0` ensures that the `sizeof` check
4531 // remains valid, even if the expression returns `void`. Similarly,
4532 // the cast to `void` ensures that there are no surprises with types
4533 // that overload the comma operator.
4534 template <class ARG>
4535 static FalseType test(...);
4536 template <class ARG>
4537 static TrueType test(typename bsl::enable_if<(bool)sizeof(
4538 ((void)callMe(Util::declval<ARG>())), 0
4539 )>::type *);
4540};
4541
4542template <class RESULT, class PARAM>
4543struct SharedPtr_TestIsCallable<RESULT(*)(PARAM)>
4544 : SharedPtr_TestIsCallable<RESULT(PARAM)> {
4545};
4546
4547template <class RESULT, class PARAM>
4548struct SharedPtr_TestIsCallable<RESULT(&)(PARAM)>
4549 : SharedPtr_TestIsCallable<RESULT(PARAM)> {
4550};
4551
4552#if BSLS_PLATFORM_CMP_VERSION >= 1910
4553// MSVC 2017 expression-SFINAE has a regression that is failing in two
4554// additional cases:
4555// 1) for pointers to object types
4556// 2) where `0` is used for a null pointer literal, deducing as `int`.
4557// We resolve those issues with a couple more specializations below.
4558
4559template <class TYPE>
4560struct SharedPtr_TestIsCallable<TYPE *> {
4561 struct TrueType { char d_padding; };
4562 struct FalseType { char d_padding[17]; };
4563
4564 template <class ARG>
4565 static FalseType test(...);
4566};
4567
4568template <>
4569struct SharedPtr_TestIsCallable<int> {
4570 struct TrueType { char d_padding; };
4571 struct FalseType { char d_padding[17]; };
4572
4573 template <class ARG>
4574 static FalseType test(...);
4575};
4576#endif // MSVC 2017
4577
4578#endif // BSLS_PLATFORM_CMP_MSVC
4579
4580template <class FUNCTOR, class ARG>
4581struct SharedPtr_IsCallable {
4582 enum { k_VALUE =
4583 sizeof(SharedPtr_TestIsCallable<FUNCTOR>::template test<ARG>(0)) == 1
4584 };
4585};
4586
4587
4588struct SharedPtr_IsFactoryFor_Impl {
4589 private:
4590 // PRIVATE TYPES
4591 struct TrueType {
4592 char d_padding;
4593 };
4594 struct FalseType {
4595 char d_padding[17];
4596 };
4597
4598 public:
4599 // CLASS METHODS
4600
4601 /// This function is never defined. It provides a property-checker that
4602 /// an object of (template parameter) type `FACTORY` has a
4603 /// member-function called `deleteObject` that can be called with a
4604 /// single argument, which is a pointer to an object of (template
4605 /// parameter) type `ARG`. The `sizeof` expression provides an
4606 /// unevaluated context to check the validity of the enclosed
4607 /// expression, and the `, 0` ensures that the `sizeof` check remains
4608 /// valid, even if the expression returns `void`. Similarly, the cast
4609 /// to `void` ensures that there are no surprises with types that overload the comma operator.
4610 ///
4611 /// \note Note that the cast to `void` is elided
4612 /// for Clang compilers using versions of LLVM prior to 12, which fail
4613 /// to evaluate the trait properly.
4614 template <class FACTORY, class ARG>
4615 static FalseType test(...);
4616 template <class FACTORY, class ARG>
4617 static TrueType test(typename bsl::enable_if<static_cast<bool>(sizeof(
4618 BSLSTL_SHAREDPTR_SFINAE_DISCARD(
4619 (*(FACTORY *)0)->deleteObject((ARG *)0)),
4620 0))>::type *);
4621};
4622
4623template <class FACTORY, class ARG>
4624struct SharedPtr_IsFactoryFor {
4625 enum { k_VALUE =
4626 sizeof(SharedPtr_IsFactoryFor_Impl::test<FACTORY, ARG>(0)) == 1
4627 };
4628};
4629
4630
4631struct SharedPtr_IsNullableFactory_Impl {
4632 private:
4633 // PRIVATE TYPES
4634 struct TrueType {
4635 char d_padding;
4636 };
4637 struct FalseType {
4638 char d_padding[17];
4639 };
4640
4641 public:
4642 // CLASS METHODS
4643
4644 /// This function is never defined. It provides a property-checker that
4645 /// an object of (template parameter) type `FACTORY` has a
4646 /// member-function called `deleteObject` that can be called with a
4647 /// single argument, which is a pointer to an object of (template
4648 /// parameter) type `ARG`. The `sizeof` expression provides an
4649 /// unevaluated context to check the validity of the enclosed
4650 /// expression, and the `, 0` ensures that the `sizeof` check remains
4651 /// valid, even if the expression returns `void`. Similarly, the cast
4652 /// to `void` ensures that there are no surprises with types that overload the comma operator.
4653 ///
4654 /// \note Note that the cast to `void` is elided
4655 /// for Clang compilers using versions of LLVM prior to 12, which fail
4656 /// to evaluate the trait properly.
4657 template <class FACTORY>
4658 static FalseType test(...);
4659 template <class FACTORY>
4660 static TrueType test(typename bsl::enable_if<static_cast<bool>(sizeof(
4661 BSLSTL_SHAREDPTR_SFINAE_DISCARD(
4662 (*(FACTORY *)0)->deleteObject(nullptr)),
4663 0))>::type *);
4664};
4665
4666template <class FACTORY>
4667struct SharedPtr_IsNullableFactory {
4668 enum { k_VALUE =
4669 sizeof(SharedPtr_IsNullableFactory_Impl::test<FACTORY>(0)) == 1
4670 };
4671};
4672
4673
4674template <class SOURCE_TYPE, class DEST_TYPE>
4675struct SharedPtr_IsPointerConvertible_Impl
4676: bsl::is_convertible<SOURCE_TYPE *, DEST_TYPE *>::type {};
4677
4678template <class SOURCE_TYPE, class DEST_TYPE>
4679struct SharedPtr_IsPointerConvertible_Impl<SOURCE_TYPE, DEST_TYPE[]>
4680: bsl::is_convertible<SOURCE_TYPE (*)[], DEST_TYPE (*)[]>::type {};
4681
4682template <class SOURCE_TYPE, class DEST_TYPE, size_t DEST_SIZE>
4683struct SharedPtr_IsPointerConvertible_Impl<SOURCE_TYPE, DEST_TYPE[DEST_SIZE]>
4684: bsl::is_convertible<SOURCE_TYPE (*)[DEST_SIZE],
4685 DEST_TYPE (*)[DEST_SIZE]>::type {};
4686
4687
4688template <class SOURCE_TYPE, class DEST_TYPE>
4689struct SharedPtr_IsPointerConvertible
4690: SharedPtr_IsPointerConvertible_Impl<SOURCE_TYPE, DEST_TYPE>::type {};
4691
4692
4693template <class SOURCE_TYPE, class DEST_TYPE>
4694struct SharedPtr_IsPointerCompatible_Impl
4695 : bsl::is_convertible<SOURCE_TYPE *, DEST_TYPE *>::type {};
4696
4697template <class TYPE, size_t SIZE>
4698struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], TYPE[]>
4699 : bsl::true_type {};
4700
4701template <class TYPE, size_t SIZE>
4702struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], const TYPE[]>
4703 : bsl::true_type {};
4704
4705template <class TYPE, size_t SIZE>
4706struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], volatile TYPE[]>
4707 : bsl::true_type {};
4708
4709template <class TYPE, size_t SIZE>
4710struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], const volatile TYPE[]>
4711 : bsl::true_type {};
4712
4713
4714template <class SOURCE_TYPE, class DEST_TYPE>
4715struct SharedPtr_IsPointerCompatible
4716: SharedPtr_IsPointerCompatible_Impl<SOURCE_TYPE, DEST_TYPE>::type {};
4717
4718} // close package namespace
4719
4720#endif // BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS
4721
4722
4723namespace bsl {
4724 //------------------------------
4725 // class enable_shared_from_this
4726 //------------------------------
4727// CREATORS
4728template<class ELEMENT_TYPE>
4729inline // constexpr
4735
4736template<class ELEMENT_TYPE>
4737inline
4744
4745template<class ELEMENT_TYPE>
4746inline
4750
4751// MANIPULATORS
4752template<class ELEMENT_TYPE>
4753inline
4761
4762template<class ELEMENT_TYPE>
4763inline
4769
4770template<class ELEMENT_TYPE>
4771inline
4777
4778template<class ELEMENT_TYPE>
4779inline
4785
4786template<class ELEMENT_TYPE>
4787inline
4794
4795 // ----------------
4796 // class shared_ptr
4797 // ----------------
4798
4799// PRIVATE CLASS METHODS
4800template <class ELEMENT_TYPE>
4801template <class INPLACE_REP>
4802inline
4803BloombergLP::bslma::SharedPtrRep *
4805 ELEMENT_TYPE *,
4806 INPLACE_REP *,
4807 BloombergLP::bslma::SharedPtrRep *rep)
4808{
4809 return rep;
4810}
4811
4812template <class ELEMENT_TYPE>
4813template <class COMPATIBLE_TYPE, class ALLOCATOR>
4814inline
4815BloombergLP::bslma::SharedPtrRep *
4816shared_ptr<ELEMENT_TYPE>::makeInternalRep(
4817 COMPATIBLE_TYPE *ptr,
4818 ALLOCATOR *,
4819 BloombergLP::bslma::Allocator *allocator)
4820{
4821 typedef BloombergLP::bslma::SharedPtrOutofplaceRep<
4822 COMPATIBLE_TYPE,
4823 BloombergLP::bslma::Allocator *>
4824 RepMaker;
4825
4826 return RepMaker::makeOutofplaceRep(ptr, allocator, allocator);
4827}
4828
4829template <class ELEMENT_TYPE>
4830template <class COMPATIBLE_TYPE, class DELETER>
4831inline
4832BloombergLP::bslma::SharedPtrRep *
4833shared_ptr<ELEMENT_TYPE>::makeInternalRep(COMPATIBLE_TYPE *ptr,
4834 DELETER *deleter,
4835 ...)
4836{
4837 typedef BloombergLP::bslma::SharedPtrOutofplaceRep<COMPATIBLE_TYPE,
4838 DELETER *> RepMaker;
4839
4840 return RepMaker::makeOutofplaceRep(ptr, deleter, 0);
4841}
4842
4843// CREATORS
4844template <class ELEMENT_TYPE>
4845inline
4848: d_ptr_p(0)
4849, d_rep_p(0)
4850{
4851}
4852
4853template <class ELEMENT_TYPE>
4854inline
4861
4862template <class ELEMENT_TYPE>
4863template <class CONVERTIBLE_TYPE
4865inline
4867: d_ptr_p(ptr)
4868{
4869 typedef BloombergLP::bslstl::SharedPtr_DefaultDeleter<
4871 typedef BloombergLP::bslma::SharedPtrOutofplaceRep<CONVERTIBLE_TYPE,
4872 Deleter> RepMaker;
4873
4874 d_rep_p = RepMaker::makeOutofplaceRep(ptr, Deleter(), 0);
4876 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
4877 this);
4878 }
4879}
4880
4881template <class ELEMENT_TYPE>
4882template <class CONVERTIBLE_TYPE
4884inline
4886 CONVERTIBLE_TYPE *ptr,
4887 BloombergLP::bslma::Allocator *basicAllocator)
4888: d_ptr_p(ptr)
4889{
4890 typedef BloombergLP::bslma::SharedPtrOutofplaceRep<
4891 CONVERTIBLE_TYPE,
4892 BloombergLP::bslma::Allocator *>
4893 RepMaker;
4894
4895 d_rep_p = RepMaker::makeOutofplaceRep(ptr, basicAllocator, basicAllocator);
4897 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
4898 this);
4899 }
4900}
4901
4902template <class ELEMENT_TYPE>
4903inline
4906 BloombergLP::bslma::SharedPtrRep *rep)
4907: d_ptr_p(ptr)
4908, d_rep_p(rep)
4909{
4910 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
4911 this);
4912}
4913
4914template <class ELEMENT_TYPE>
4915inline
4917 ELEMENT_TYPE *ptr,
4918 BloombergLP::bslma::SharedPtrRep *rep,
4919 BloombergLP::bslstl::SharedPtr_RepFromExistingSharedPtr)
4920: d_ptr_p(ptr)
4921, d_rep_p(rep)
4922{
4923}
4924
4925template <class ELEMENT_TYPE>
4926template <class CONVERTIBLE_TYPE,
4927 class DISPATCH
4929 BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(DISPATCH *, CONVERTIBLE_TYPE)>
4930inline
4932 DISPATCH *dispatch)
4933: d_ptr_p(ptr)
4934, d_rep_p(makeInternalRep(ptr, dispatch, dispatch))
4935{
4937 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
4938 this);
4939 }
4940}
4941
4942template <class ELEMENT_TYPE>
4943template <class CONVERTIBLE_TYPE,
4944 class DELETER
4946 BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
4947inline
4949 CONVERTIBLE_TYPE *ptr,
4950 DELETER deleter,
4951 BloombergLP::bslma::Allocator *basicAllocator)
4952: d_ptr_p(ptr)
4953{
4954 typedef BloombergLP::bslma::SharedPtrOutofplaceRep<CONVERTIBLE_TYPE,
4955 DELETER> RepMaker;
4956
4957 d_rep_p = RepMaker::makeOutofplaceRep(ptr, deleter, basicAllocator);
4959 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
4960 this);
4961 }
4962}
4963
4964template <class ELEMENT_TYPE>
4965template <class CONVERTIBLE_TYPE,
4966 class DELETER,
4967 class ALLOCATOR
4969 BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
4970inline
4972 DELETER deleter,
4973 ALLOCATOR basicAllocator,
4974 typename ALLOCATOR::value_type *)
4975: d_ptr_p(ptr)
4976{
4977#ifdef BSLS_PLATFORM_CMP_MSVC
4978 // This is not quite C++11 'decay' as we do not need to worry about array
4979 // types, and do not want to remove reference or cv-qualification from
4980 // DELETER otherwise. This works around a Microsoft bug turning function
4981 // pointers into function references.
4982
4985 DELETER>::type DeleterType;
4986#else
4987 typedef DELETER DeleterType;
4988#endif
4989
4990 typedef
4991 BloombergLP::bslstl::SharedPtrAllocateOutofplaceRep<CONVERTIBLE_TYPE,
4992 DeleterType,
4993 ALLOCATOR> RepMaker;
4994
4995 d_rep_p = RepMaker::makeOutofplaceRep(ptr, deleter, basicAllocator);
4997 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
4998 this);
4999 }
5000}
5001
5002template <class ELEMENT_TYPE>
5003inline
5005 BloombergLP::bslma::Allocator *)
5006: d_ptr_p(0)
5007, d_rep_p(0)
5008{
5009}
5010
5011template <class ELEMENT_TYPE>
5012template <class DELETER
5014inline
5016 nullptr_t,
5017 DELETER deleter,
5018 BloombergLP::bslma::Allocator *basicAllocator)
5019: d_ptr_p(0)
5020{
5021 typedef BloombergLP::bslma::SharedPtrOutofplaceRep<ELEMENT_TYPE,
5022 DELETER> RepMaker;
5023
5026 d_rep_p = 0;
5027 }
5028 else {
5029 d_rep_p = RepMaker::makeOutofplaceRep((ELEMENT_TYPE *)0,
5030 deleter,
5031 basicAllocator);
5032 }
5033}
5034
5035template <class ELEMENT_TYPE>
5036template <class DELETER, class ALLOCATOR
5038inline
5040 nullptr_t,
5041 DELETER deleter,
5042 ALLOCATOR basicAllocator,
5043 typename ALLOCATOR::value_type *)
5044: d_ptr_p(0)
5045{
5046#ifdef BSLS_PLATFORM_CMP_MSVC
5047 // This is not quite C++11 'decay' as we do not need to worry about array
5048 // types, and do not want to remove reference or cv-qualification from
5049 // DELETER otherwise. This works around a Microsoft bug turning function
5050 // pointers into function references.
5051
5054 DELETER>::type DeleterType;
5055#else
5056 typedef DELETER DeleterType;
5057#endif
5058
5059 typedef
5060 BloombergLP::bslstl::SharedPtrAllocateOutofplaceRep<ELEMENT_TYPE,
5061 DeleterType,
5062 ALLOCATOR> RepMaker;
5063
5064 d_rep_p = RepMaker::makeOutofplaceRep((ELEMENT_TYPE *)0,
5065 deleter,
5066 basicAllocator);
5067}
5068
5069template <class ELEMENT_TYPE>
5070template <class CONVERTIBLE_TYPE
5073 BloombergLP::bslma::ManagedPtr<CONVERTIBLE_TYPE> managedPtr,
5074 BloombergLP::bslma::Allocator *basicAllocator)
5075: d_ptr_p(managedPtr.ptr())
5076, d_rep_p(0)
5077{
5078 typedef BloombergLP::bslma::SharedPtrInplaceRep<
5079 BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE> > Rep;
5080
5081 if (d_ptr_p) {
5082 ELEMENT_TYPE *pPotentiallyShared = static_cast<ELEMENT_TYPE *>(
5083 managedPtr.deleter().object());
5084
5085 if (&BloombergLP::bslma::SharedPtrRep::managedPtrDeleter ==
5086 managedPtr.deleter().deleter()) {
5087 d_rep_p = static_cast<BloombergLP::bslma::SharedPtrRep *>
5088 (managedPtr.release().second.factory());
5089 }
5090 else if (&BloombergLP::bslma::SharedPtrRep::managedPtrEmptyDeleter ==
5091 managedPtr.deleter().deleter()) {
5092 d_rep_p = 0;
5093 managedPtr.release();
5094 }
5095 else {
5096 basicAllocator =
5097 BloombergLP::bslma::Default::allocator(basicAllocator);
5098 Rep *rep = new (*basicAllocator) Rep(basicAllocator);
5099 (*rep->ptr()) = managedPtr;
5100 d_rep_p = rep;
5101 }
5102
5103 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
5104 pPotentiallyShared,
5105 this);
5106 }
5107}
5108
5109#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
5110template <class ELEMENT_TYPE>
5111template <class CONVERTIBLE_TYPE
5114 std::auto_ptr<CONVERTIBLE_TYPE>& autoPtr,
5115 BloombergLP::bslma::Allocator *basicAllocator)
5116: d_ptr_p(autoPtr.get())
5117, d_rep_p(0)
5118{
5119 typedef BloombergLP::bslma::SharedPtrInplaceRep<
5120 std::auto_ptr<CONVERTIBLE_TYPE> > Rep;
5121
5122 if (d_ptr_p) {
5123 basicAllocator =
5124 BloombergLP::bslma::Default::allocator(basicAllocator);
5125 Rep *rep = new (*basicAllocator) Rep(basicAllocator);
5126 (*rep->ptr()) = autoPtr;
5127 d_rep_p = rep;
5128 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
5129 d_ptr_p,
5130 this);
5131 }
5132}
5133
5134template <class ELEMENT_TYPE>
5136 std::auto_ptr_ref<ELEMENT_TYPE> autoRef,
5137 BloombergLP::bslma::Allocator *basicAllocator)
5138: d_ptr_p(0)
5139, d_rep_p(0)
5140{
5141 typedef BloombergLP::bslma::SharedPtrInplaceRep<
5142 std::auto_ptr<ELEMENT_TYPE> > Rep;
5143
5144 std::auto_ptr<ELEMENT_TYPE> autoPtr(autoRef);
5145 if (autoPtr.get()) {
5146 basicAllocator =
5147 BloombergLP::bslma::Default::allocator(basicAllocator);
5148 Rep *rep = new (*basicAllocator) Rep(basicAllocator);
5149 d_ptr_p = autoPtr.get();
5150 (*rep->ptr()) = autoPtr;
5151 d_rep_p = rep;
5152 }
5153}
5154#endif
5155
5156#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
5157# if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
5158template <class ELEMENT_TYPE>
5159template <class COMPATIBLE_TYPE,
5160 class UNIQUE_DELETER,
5161 typename enable_if<is_convertible<
5162 typename std::unique_ptr<COMPATIBLE_TYPE,
5163 UNIQUE_DELETER>::pointer,
5164 ELEMENT_TYPE *>::value>::type *>
5166 std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>&& adoptee,
5167 BloombergLP::bslma::Allocator *basicAllocator)
5168: d_ptr_p(adoptee.get())
5169, d_rep_p(0)
5170{
5171 typedef BloombergLP::bslma::SharedPtrInplaceRep<
5172 std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER> > Rep;
5173
5174 if (d_ptr_p) {
5175 basicAllocator =
5176 BloombergLP::bslma::Default::allocator(basicAllocator);
5177 Rep *rep = new (*basicAllocator) Rep(basicAllocator,
5178 BloombergLP::bslmf::MovableRefUtil::move(adoptee));
5179 d_rep_p = rep;
5180 BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
5181 d_ptr_p,
5182 this);
5183 }
5184}
5185# endif
5186#endif
5187
5188template <class ELEMENT_TYPE>
5189template <class ANY_TYPE>
5191 ELEMENT_TYPE *object)
5193: d_ptr_p(object)
5194, d_rep_p(source.d_rep_p)
5195{
5196 if (d_rep_p) {
5197 d_rep_p->acquireRef();
5198 }
5199}
5200
5201template <class ELEMENT_TYPE>
5202template <class COMPATIBLE_TYPE
5206: d_ptr_p(other.d_ptr_p)
5207, d_rep_p(other.d_rep_p)
5208{
5209 if (d_rep_p) {
5210 d_rep_p->acquireRef();
5211 }
5212}
5213
5214template <class ELEMENT_TYPE>
5217: d_ptr_p(original.d_ptr_p)
5218, d_rep_p(original.d_rep_p)
5219{
5220 if (d_rep_p) {
5221 d_rep_p->acquireRef();
5222 }
5223}
5224
5225template <class ELEMENT_TYPE>
5227 (BloombergLP::bslmf::MovableRef<shared_ptr> original)
5229: d_ptr_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_ptr_p)
5230, d_rep_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p)
5231{
5232 BloombergLP::bslmf::MovableRefUtil::access(original).d_ptr_p = 0;
5233 BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p = 0;
5234}
5235
5236#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5237template <class ELEMENT_TYPE>
5238template <class COMPATIBLE_TYPE
5242: d_ptr_p(other.d_ptr_p)
5243, d_rep_p(other.d_rep_p)
5244{
5245 other.d_ptr_p = 0;
5246 other.d_rep_p = 0;
5247}
5248#else
5249template <class ELEMENT_TYPE>
5250template <class COMPATIBLE_TYPE
5253shared_ptr(BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > other)
5255: d_ptr_p(BloombergLP::bslmf::MovableRefUtil::access(other).d_ptr_p)
5256, d_rep_p(BloombergLP::bslmf::MovableRefUtil::access(other).d_rep_p)
5257{
5258 BloombergLP::bslmf::MovableRefUtil::access(other).d_ptr_p = 0;
5259 BloombergLP::bslmf::MovableRefUtil::access(other).d_rep_p = 0;
5260}
5261#endif
5262
5263template <class ELEMENT_TYPE>
5264template <class COMPATIBLE_TYPE
5267: d_ptr_p(0)
5268, d_rep_p(0)
5269{
5270 // This implementation handles two awkward cases:
5271 //
5272 // i) a ref-counted null pointer, means we cannot simply test 'if (!value)'
5273 // ii) a null pointer aliasing a non-null pointer is still expired, and so
5274 // should throw.
5275
5276 SelfType value = other.lock();
5277 if (other.expired()) {
5278 // Test after lock to avoid a race between testing 'expired' and
5279 // claiming the lock.
5280
5281 BloombergLP::bslstl::SharedPtr_ImpUtil::throwBadWeakPtr();
5282 }
5283
5284 swap(value);
5285}
5286
5287#if !defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5288template <class ELEMENT_TYPE>
5289template <class COMPATIBLE_TYPE
5292 BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > ptr)
5293: d_ptr_p(0)
5294, d_rep_p(0)
5295{
5296 // This implementation handles two awkward cases:
5297 //
5298 // i) a ref-counted null pointer, means we cannot simply test 'if (!value)'
5299 // ii) a null pointer aliasing a non-null pointer is still expired, and so
5300 // should throw.
5301
5303
5304 SelfType value = other.lock();
5305 if (other.expired()) {
5306 // Test after lock to avoid a race between testing 'expired' and
5307 // claiming the lock.
5308
5309 BloombergLP::bslstl::SharedPtr_ImpUtil::throwBadWeakPtr();
5310 }
5311
5312 swap(value);
5313}
5314#endif
5315
5316template <class ELEMENT_TYPE>
5318{
5319 if (d_rep_p) {
5320 d_rep_p->releaseRef();
5321 }
5322}
5323
5324// MANIPULATORS
5325template <class ELEMENT_TYPE>
5329{
5330 // Instead of testing '&rhs == this', which happens infrequently, optimize
5331 // for when reps are the same.
5332
5333 if (rhs.d_rep_p == d_rep_p) {
5334 d_ptr_p = rhs.d_ptr_p;
5335 }
5336 else {
5337 SelfType(rhs).swap(*this);
5338 }
5339
5340 return *this;
5341}
5342
5343template <class ELEMENT_TYPE>
5346 BloombergLP::bslmf::MovableRef<shared_ptr> rhs)
5348{
5349 // No self-assignment to optimize, postcondition demands 'rhs' is left
5350 // empty, unless it is the exact same object, not just the same 'rep'.
5351
5352 shared_ptr(BloombergLP::bslmf::MovableRefUtil::move(rhs)).swap(*this);
5353
5354 return *this;
5355}
5356
5357template <class ELEMENT_TYPE>
5358template <class COMPATIBLE_TYPE>
5359typename enable_if<
5364{
5365 // Instead of testing '&rhs == this', which happens infrequently, optimize
5366 // for when reps are the same.
5367
5368 if (rhs.d_rep_p == d_rep_p) {
5369 d_ptr_p = rhs.d_ptr_p;
5370 }
5371 else {
5372 SelfType(rhs).swap(*this);
5373 }
5374
5375 return *this;
5376}
5377
5378#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5379template <class ELEMENT_TYPE>
5380template <class COMPATIBLE_TYPE>
5385#else
5386template <class ELEMENT_TYPE>
5387template <class COMPATIBLE_TYPE>
5391 BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > rhs)
5393#endif
5394{
5395 // No self-assignment to optimize, postcondition demands 'rhs' is left
5396 // empty, unless it is the exact same object, not just the same 'rep'.
5397
5398 shared_ptr(BloombergLP::bslmf::MovableRefUtil::move(rhs)).swap(*this);
5399
5400 return *this;
5401}
5402
5403template <class ELEMENT_TYPE>
5404template <class COMPATIBLE_TYPE>
5405inline
5406typename enable_if<
5410 BloombergLP::bslma::ManagedPtr<COMPATIBLE_TYPE> rhs)
5411{
5412 SelfType(rhs).swap(*this);
5413 return *this;
5414}
5415
5416#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
5417template <class ELEMENT_TYPE>
5418template <class COMPATIBLE_TYPE>
5419inline
5420typename enable_if<
5423shared_ptr<ELEMENT_TYPE>::operator=(std::auto_ptr<COMPATIBLE_TYPE> rhs)
5424{
5425 SelfType(rhs).swap(*this);
5426 return *this;
5427}
5428#endif
5429
5430#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
5431template <class ELEMENT_TYPE>
5432template <class COMPATIBLE_TYPE, class UNIQUE_DELETER>
5433inline
5434typename enable_if<
5435 is_convertible<
5436 typename std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>::pointer,
5437 ELEMENT_TYPE *>::value,
5438 shared_ptr<ELEMENT_TYPE>&>::type
5440 std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>&& rhs)
5441{
5442 SelfType(BloombergLP::bslmf::MovableRefUtil::move(rhs)).swap(*this);
5443 return *this;
5444}
5445#endif
5446
5447template <class ELEMENT_TYPE>
5448inline
5450{
5451 BloombergLP::bslma::SharedPtrRep *rep = d_rep_p;
5452
5453 // Clear 'd_rep_p' first so that a self-referencing shared pointer's
5454 // destructor does not try to call 'releaseRef' again.
5455
5456 d_rep_p = 0;
5457 d_ptr_p = 0;
5458
5459 if (rep) {
5460 rep->releaseRef();
5461 }
5462}
5463
5464template <class ELEMENT_TYPE>
5465template <class COMPATIBLE_TYPE>
5466inline
5467typename
5470{
5471 SelfType(ptr).swap(*this);
5472}
5473
5474template <class ELEMENT_TYPE>
5475template <class COMPATIBLE_TYPE, class DELETER>
5476inline
5477typename
5480 DELETER deleter)
5481{
5482 SelfType(ptr, deleter).swap(*this);
5483}
5484
5485template <class ELEMENT_TYPE>
5486template <class COMPATIBLE_TYPE, class DELETER, class ALLOCATOR>
5487inline
5488typename
5491 DELETER deleter,
5492 ALLOCATOR basicAllocator)
5493{
5494 SelfType(ptr, deleter, basicAllocator).swap(*this);
5495}
5496
5497template <class ELEMENT_TYPE>
5498template <class ANY_TYPE>
5499inline
5501 ELEMENT_TYPE *ptr)
5502{
5503 // Optimize for the (expected) common case where aliases are managing the
5504 // same data structure.
5505
5506 if (source.d_rep_p == d_rep_p && ptr) {
5507 d_ptr_p = ptr;
5508 }
5509 else {
5510 SelfType(source, ptr).swap(*this);
5511 }
5512}
5513
5514template <class ELEMENT_TYPE>
5515inline
5517{
5518 // We directly implement swapping of two pointers, rather than simply
5519 // calling 'bsl::swap' or using 'bslalg::SwapUtil', to avoid (indirectly)
5520 // including the platform <algorithm> header, which may transitively
5521 // include other standard headers. This reduces the risk of
5522 // platform-specific cycles, which have been observed to cause problems.
5523
5524 // Also, as 'shared_ptr' is bitwise-moveable, we could simplify this to
5525 // 'memcpy'-ing through an (aligned?) array of sufficient 'char'.
5526
5527 element_type *tempPtr_p = d_ptr_p;
5528 d_ptr_p = other.d_ptr_p;
5529 other.d_ptr_p = tempPtr_p;
5530
5531 BloombergLP::bslma::SharedPtrRep *tempRep_p = d_rep_p;
5532 d_rep_p = other.d_rep_p;
5533 other.d_rep_p = tempRep_p;
5534}
5535
5536// ADDITIONAL BSL MANIPULATORS
5537template<class ELEMENT_TYPE>
5538void
5540{
5541 typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;
5542
5543 BloombergLP::bslma::Allocator *basicAllocator =
5544 BloombergLP::bslma::Default::allocator();
5545
5546 Rep *rep = new (*basicAllocator) Rep(basicAllocator);
5547 SelfType(rep->ptr(), rep).swap(*this);
5548}
5549
5550#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
5551template <class ELEMENT_TYPE>
5552template <class... ARGS>
5553void
5555 BloombergLP::bslma::Allocator *basicAllocator,
5556 ARGS&&... args)
5557{
5558 typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;
5559
5560 basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
5561 Rep *rep = new (*basicAllocator) Rep(basicAllocator,
5562 BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);
5563 SelfType(rep->ptr(), rep).swap(*this);
5564}
5565#endif
5566
5567template <class ELEMENT_TYPE>
5568template <class ANY_TYPE>
5569void
5571 ELEMENT_TYPE *object)
5572{
5573 if (source.d_rep_p == d_rep_p && object) {
5574 d_ptr_p = object;
5575 }
5576 else {
5577 SelfType(source, object).swap(*this);
5578 }
5579}
5580
5581template <class ELEMENT_TYPE>
5582pair<typename shared_ptr<ELEMENT_TYPE>::element_type *, BloombergLP::bslma::SharedPtrRep *>
5584{
5586 d_rep_p);
5587 d_ptr_p = 0;
5588 d_rep_p = 0;
5589 return ret;
5590}
5591
5592#ifndef BDE_OMIT_INTERNAL_DEPRECATED
5593// DEPRECATED BDE LEGACY MANIPULATORS
5594template <class ELEMENT_TYPE>
5595inline
5600
5601template <class ELEMENT_TYPE>
5602template <class COMPATIBLE_TYPE>
5603inline
5604void shared_ptr<ELEMENT_TYPE>::load(COMPATIBLE_TYPE *ptr)
5605{
5606 SelfType(ptr).swap(*this);
5607}
5608
5609template <class ELEMENT_TYPE>
5610template <class COMPATIBLE_TYPE>
5611inline
5612void
5614 BloombergLP::bslma::Allocator *basicAllocator)
5615{
5616 SelfType(ptr, basicAllocator).swap(*this);
5617}
5618
5619template <class ELEMENT_TYPE>
5620template <class COMPATIBLE_TYPE, class DELETER>
5621inline
5622void
5624 const DELETER& deleter,
5625 BloombergLP::bslma::Allocator *basicAllocator)
5626{
5627 SelfType(ptr, deleter, basicAllocator).swap(*this);
5628}
5629#endif // BDE_OMIT_INTERNAL_DEPRECATED
5630
5631// ACCESSORS
5632template <class ELEMENT_TYPE>
5633inline
5634#if defined(BSLS_PLATFORM_CMP_IBM) // Last tested with xlC 12.1
5635shared_ptr<ELEMENT_TYPE>::operator typename shared_ptr::BoolType() const
5637#else
5639#endif
5640{
5641 return BloombergLP::bsls::UnspecifiedBool<shared_ptr>::makeValue(d_ptr_p);
5642}
5643
5644template <class ELEMENT_TYPE>
5645inline
5648{
5649 BSLS_ASSERT_SAFE(d_ptr_p);
5650
5651 return *d_ptr_p;
5652}
5653
5654template <class ELEMENT_TYPE>
5655inline
5658{
5659 return d_ptr_p;
5660}
5661
5662template <class ELEMENT_TYPE>
5663inline
5666{
5667 return d_ptr_p;
5668}
5669
5670template <class ELEMENT_TYPE>
5671inline typename
5674{
5675 BSLS_ASSERT_SAFE(d_ptr_p);
5676
5677 return *(d_ptr_p + index);
5678}
5679
5680template <class ELEMENT_TYPE>
5681template<class ANY_TYPE>
5682inline
5685{
5686 return std::less<BloombergLP::bslma::SharedPtrRep *>()(rep(), other.rep());
5687}
5688
5689template <class ELEMENT_TYPE>
5690template<class ANY_TYPE>
5691inline
5692bool
5695{
5696 return std::less<BloombergLP::bslma::SharedPtrRep *>()(rep(), other.rep());
5697}
5698
5699template <class ELEMENT_TYPE>
5700template<class ANY_TYPE>
5701inline
5704{
5705 return rep() == other.rep();
5706}
5707
5708template <class ELEMENT_TYPE>
5709template<class ANY_TYPE>
5710inline
5711bool
5714{
5715 return rep() == other.rep();
5716}
5717
5718template <class ELEMENT_TYPE>
5719inline
5720size_t
5725
5726template <class ELEMENT_TYPE>
5727inline
5729{
5730 return 1 == use_count();
5731}
5732
5733template <class ELEMENT_TYPE>
5734inline
5736{
5737 return d_rep_p ? d_rep_p->numReferences() : 0;
5738}
5739
5740// ADDITIONAL BSL ACCESSORS
5741template <class ELEMENT_TYPE>
5742BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>
5744{
5745 if (d_rep_p && d_ptr_p) {
5746 d_rep_p->acquireRef();
5747 return BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>(d_ptr_p,
5748 d_rep_p,
5749 &BloombergLP::bslma::SharedPtrRep::managedPtrDeleter);
5750 // RETURN
5751 }
5752
5753 return BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>(
5754 d_ptr_p,
5755 (BloombergLP::bslma::SharedPtrRep *)0,
5756 &BloombergLP::bslma::SharedPtrRep::managedPtrEmptyDeleter);
5757}
5758
5759template <class ELEMENT_TYPE>
5760inline
5761BloombergLP::bslma::SharedPtrRep *shared_ptr<ELEMENT_TYPE>::rep() const
5763{
5764 return d_rep_p;
5765}
5766
5767#ifndef BDE_OMIT_INTERNAL_DEPRECATED
5768// DEPRECATED BDE LEGACY ACCESSORS
5769template <class ELEMENT_TYPE>
5770inline
5772{
5773 return d_rep_p ? d_rep_p->numReferences() : 0;
5774}
5775
5776template <class ELEMENT_TYPE>
5777inline
5780{
5781 return d_ptr_p;
5782}
5783#endif // BDE_OMIT_INTERNAL_DEPRECATED
5784
5785 // --------------
5786 // class weak_ptr
5787 // --------------
5788
5789// CREATORS
5790template <class ELEMENT_TYPE>
5791inline
5794: d_ptr_p(0)
5795, d_rep_p(0)
5796{
5797}
5798
5799template <class ELEMENT_TYPE>
5801 BloombergLP::bslmf::MovableRef<weak_ptr> original)
5803: d_ptr_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_ptr_p)
5804, d_rep_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p)
5805{
5806 BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p = 0;
5807// original.d_ptr_p = 0; // this seems overkill for a /weak/ pointer
5808}
5809
5810#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5811template <class ELEMENT_TYPE>
5812template <class COMPATIBLE_TYPE
5816: d_ptr_p(original.d_ptr_p)
5817, d_rep_p(original.d_rep_p)
5818{
5819 original.d_rep_p = 0;
5820// original.d_ptr_p = 0; // this seems overkill for a /weak/ pointer
5821}
5822#else
5823template <class ELEMENT_TYPE>
5824template <class CONVERTIBLE_TYPE
5827 BloombergLP::bslmf::MovableRef<weak_ptr<CONVERTIBLE_TYPE> > original)
5829: d_ptr_p(original.d_ptr_p)
5830, d_rep_p(original.d_rep_p)
5831{
5832 original.d_rep_p = 0;
5833// original.d_ptr_p = 0; // this seems overkill for a /weak/ pointer
5834}
5835#endif
5836
5837template <class ELEMENT_TYPE>
5840: d_ptr_p(original.d_ptr_p)
5841, d_rep_p(original.d_rep_p)
5842{
5843 if (d_rep_p) {
5844 d_rep_p->acquireWeakRef();
5845 }
5846}
5847
5848template <class ELEMENT_TYPE>
5849template <class COMPATIBLE_TYPE
5853: d_ptr_p(other.get())
5854, d_rep_p(other.rep())
5855{
5856 if (d_rep_p) {
5857 d_rep_p->acquireWeakRef();
5858 }
5859}
5860
5861template <class ELEMENT_TYPE>
5862template <class COMPATIBLE_TYPE
5866: d_ptr_p(other.d_ptr_p)
5867, d_rep_p(other.d_rep_p)
5868{
5869 if (d_rep_p) {
5870 d_rep_p->acquireWeakRef();
5871 }
5872}
5873
5874template <class ELEMENT_TYPE>
5875inline
5877{
5878 if (d_rep_p) {
5879 d_rep_p->releaseWeakRef();
5880 }
5881}
5882
5883// PRIVATE MANIPULATORS
5884template <class ELEMENT_TYPE>
5885inline
5887 BloombergLP::bslma::SharedPtrRep *rep,
5888 ELEMENT_TYPE *target)
5889{
5890 if (d_rep_p) {
5891 d_rep_p->releaseWeakRef();
5892 }
5893
5894 d_ptr_p = target;
5895 d_rep_p = rep;
5896 d_rep_p->acquireWeakRef();
5897}
5898
5899// MANIPULATORS
5900template <class ELEMENT_TYPE>
5902 BloombergLP::bslmf::MovableRef<weak_ptr> rhs)
5904{
5905 weak_ptr tmp(BloombergLP::bslmf::MovableRefUtil::move(rhs));
5906 tmp.swap(*this);
5907 return *this;
5908}
5909
5910#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5911template <class ELEMENT_TYPE>
5912template <class COMPATIBLE_TYPE>
5913typename enable_if<
5918{
5919 weak_ptr tmp(BloombergLP::bslmf::MovableRefUtil::move(rhs));
5920 tmp.swap(*this);
5921 return *this;
5922}
5923#else
5924template <class ELEMENT_TYPE>
5925template <class COMPATIBLE_TYPE>
5926typename enable_if<
5927 is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
5928 weak_ptr<ELEMENT_TYPE>&>::type
5930 BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > rhs)
5932{
5933 weak_ptr tmp(BloombergLP::bslmf::MovableRefUtil::move(rhs));
5934 tmp.swap(*this);
5935 return *this;
5936}
5937#endif
5938
5939template <class ELEMENT_TYPE>
5943{
5944#if 1
5945 weak_ptr tmp(rhs);
5946 tmp.swap(*this);
5947#else
5948 // needs friendship, or use the cheating util class.
5949 privateAssign(rhs.d_rep_p, rhs.d_ptr_p);
5950#endif
5951 return *this;
5952}
5953
5954template <class ELEMENT_TYPE>
5955template <class COMPATIBLE_TYPE>
5956typename enable_if<
5961{
5962#if 1
5963 weak_ptr tmp(rhs);
5964 tmp.swap(*this);
5965#else
5966 // needs friendship, or use the cheating util class.
5967 privateAssign(rhs.d_rep_p, rhs.d_ptr_p);
5968#endif
5969 return *this;
5970}
5971
5972template <class ELEMENT_TYPE>
5973template <class COMPATIBLE_TYPE>
5974typename enable_if<
5979{
5980#if 1
5981 weak_ptr tmp(rhs);
5982 tmp.swap(*this);
5983#else
5984 // needs friendship, or use the cheating util class.
5985 privateAssign(rhs.d_rep_p, rhs.d_ptr_p);
5986#endif
5987 return *this;
5988}
5989
5990template <class ELEMENT_TYPE>
5991inline
5993{
5994 if (d_rep_p) {
5995 d_rep_p->releaseWeakRef();
5996 }
5997
5998 d_ptr_p = 0;
5999 d_rep_p = 0;
6000}
6001
6002template <class ELEMENT_TYPE>
6003inline
6006{
6007 // We directly implement swapping of two pointers, rather than simply
6008 // calling 'bsl::swap' or using 'bslalg::SwapUtil', to avoid (indirectly)
6009 // including the platform <algorithm> header, which may transitively
6010 // include other standard headers. This reduces the risk of
6011 // platform-specific cycles, which have been observed to cause problems.
6012
6013 ELEMENT_TYPE *tempPtr_p = d_ptr_p;
6014 d_ptr_p = other.d_ptr_p;
6015 other.d_ptr_p = tempPtr_p;
6016
6017 BloombergLP::bslma::SharedPtrRep *tempRep_p = d_rep_p;
6018 d_rep_p = other.d_rep_p;
6019 other.d_rep_p = tempRep_p;
6020}
6021
6022// ACCESSORS
6023template <class ELEMENT_TYPE>
6024inline
6026{
6027 return !(d_rep_p && d_rep_p->numReferences());
6028}
6029
6030template <class ELEMENT_TYPE>
6033{
6034 if (d_rep_p && d_rep_p->tryAcquireRef()) {
6036 d_ptr_p,
6037 d_rep_p,
6038 BloombergLP::bslstl::SharedPtr_RepFromExistingSharedPtr());
6039 // RETURN
6040 }
6041 return shared_ptr<ELEMENT_TYPE>();
6042}
6043
6044template <class ELEMENT_TYPE>
6045template <class ANY_TYPE>
6046inline
6047bool
6050{
6051 return std::less<BloombergLP::bslma::SharedPtrRep *>()(d_rep_p,
6052 other.rep());
6053}
6054
6055template <class ELEMENT_TYPE>
6056template <class ANY_TYPE>
6057inline
6058bool
6061{
6062 return std::less<BloombergLP::bslma::SharedPtrRep *>()(d_rep_p,
6063 other.d_rep_p);
6064}
6065
6066template <class ELEMENT_TYPE>
6067template<class ANY_TYPE>
6068inline
6069bool
6072{
6073 return rep() == other.rep();
6074}
6075
6076template <class ELEMENT_TYPE>
6077template<class ANY_TYPE>
6078inline
6079bool
6082{
6083 return rep() == other.rep();
6084}
6085
6086template <class ELEMENT_TYPE>
6087inline
6088size_t
6093
6094template <class ELEMENT_TYPE>
6095inline
6096BloombergLP::bslma::SharedPtrRep *weak_ptr<ELEMENT_TYPE>::rep() const
6098{
6099 return d_rep_p;
6100}
6101
6102template <class ELEMENT_TYPE>
6103inline
6105{
6106 return d_rep_p ? d_rep_p->numReferences() : 0;
6107}
6108
6109#ifndef BDE_OMIT_INTERNAL_DEPRECATED
6110// DEPRECATED BDE LEGACY ACCESSORS
6111template <class ELEMENT_TYPE>
6112inline
6118
6119template <class ELEMENT_TYPE>
6120inline
6122{
6123 return d_rep_p ? d_rep_p->numReferences() : 0;
6124}
6125#endif // BDE_OMIT_INTERNAL_DEPRECATED
6126
6127} // close namespace bsl
6128
6129
6130namespace bslstl {
6131
6132 // -----------------
6133 // SharedPtr_ImpUtil
6134 // -----------------
6135
6136template <class SHARED_TYPE, class ENABLE_TYPE>
6137inline
6141{
6142 BSLS_ASSERT(0 != sharedPtr);
6143
6144 if (0 != result && result->d_weakThis.expired()) {
6145 result->d_weakThis.privateAssign(
6146 sharedPtr->d_rep_p,
6147 const_cast <ENABLE_TYPE *>(
6148 static_cast<ENABLE_TYPE const*>(sharedPtr->d_ptr_p)));
6149 }
6150}
6151
6152inline
6154 const void *)
6156{
6157}
6158
6159 // --------------------
6160 // struct SharedPtrUtil
6161 // --------------------
6162
6163// CLASS METHODS
6164template <class TARGET, class SOURCE>
6165inline
6167 const bsl::shared_ptr<SOURCE>& source)
6168{
6169 BSLS_ASSERT(0 != target);
6170
6171 target->reset(source, const_cast<TARGET *>(source.get()));
6172}
6173
6174template <class TARGET, class SOURCE>
6175inline
6179{
6180 return bsl::shared_ptr<TARGET>(source,
6181 const_cast<TARGET *>(source.get()));
6182}
6183
6184template <class TARGET, class SOURCE>
6185inline
6187 const bsl::shared_ptr<SOURCE>& source)
6188{
6189 BSLS_ASSERT(0 != target);
6190
6191 if (TARGET *castPtr = dynamic_cast<TARGET *>(source.get())) {
6192 target->reset(source, castPtr);
6193 }
6194 else {
6195 target->reset();
6196 }
6197}
6198
6199template <class TARGET, class SOURCE>
6200inline
6204{
6205 if (TARGET *castPtr = dynamic_cast<TARGET *>(source.get())) {
6206 return bsl::shared_ptr<TARGET>(source, castPtr); // RETURN
6207 }
6208
6209 return bsl::shared_ptr<TARGET>();
6210}
6211
6212template <class TARGET, class SOURCE>
6213inline
6215 const bsl::shared_ptr<SOURCE>& source)
6216{
6217 BSLS_ASSERT(0 != target);
6218
6219 target->reset(source, static_cast<TARGET *>(source.get()));
6220}
6221
6222template <class TARGET, class SOURCE>
6223inline
6227{
6228 return bsl::shared_ptr<TARGET>(source,
6229 static_cast<TARGET *>(source.get()));
6230}
6231
6232 // --------------------------
6233 // struct SharedPtrNilDeleter
6234 // --------------------------
6235
6236// ACCESSORS
6237inline
6238void SharedPtrNilDeleter::operator()(const volatile void *) const
6240{
6241}
6242
6243 // -------------------------------
6244 // struct SharedPtr_DefaultDeleter
6245 // -------------------------------
6246
6247// ACCESSORS
6248template <>
6249template <class ANY_TYPE>
6250inline
6253{
6254 delete [] ptr;
6255}
6256
6257template <>
6258template <class ANY_TYPE>
6259inline
6262{
6263 delete ptr;
6264}
6265
6266 // --------------------------
6267 // class SharedPtr_RepProctor
6268 // --------------------------
6269
6270// CREATORS
6271inline
6272SharedPtr_RepProctor::SharedPtr_RepProctor(bslma::SharedPtrRep *rep)
6274: d_rep_p(rep)
6275{
6276}
6277
6278inline
6280{
6281 if (d_rep_p) {
6282 d_rep_p->disposeRep();
6283 }
6284}
6285
6286// MANIPULATORS
6287inline
6289{
6290 d_rep_p = 0;
6291}
6292
6293} // close package namespace
6294
6295
6296// FREE OPERATORS
6297template <class LHS_TYPE, class RHS_TYPE>
6298inline
6299bool bsl::operator==(const shared_ptr<LHS_TYPE>& lhs,
6300 const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
6301{
6302 return lhs.get() == rhs.get();
6303}
6304
6305#ifdef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
6306
6307template<class LHS_TYPE, class RHS_TYPE>
6308inline
6309bsl::strong_ordering bsl::operator<=>(const shared_ptr<LHS_TYPE>& lhs,
6310 const shared_ptr<RHS_TYPE>& rhs)
6312{
6313 const void *p1 = lhs.get(),
6314 *p2 = rhs.get();
6315 return p1 <=> p2;
6316}
6317
6318#else
6319
6320template <class LHS_TYPE, class RHS_TYPE>
6321inline
6322bool bsl::operator!=(const shared_ptr<LHS_TYPE>& lhs,
6323 const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
6324{
6325 return !(lhs == rhs);
6326}
6327
6328template <class LHS_TYPE, class RHS_TYPE>
6329inline
6330bool bsl::operator<(const shared_ptr<LHS_TYPE>& lhs,
6331 const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
6332{
6333 return std::less<const void *>()(lhs.get(), rhs.get());
6334}
6335
6336template <class LHS_TYPE, class RHS_TYPE>
6337inline
6338bool bsl::operator>(const shared_ptr<LHS_TYPE>& lhs,
6339 const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
6340{
6341 return rhs < lhs;
6342}
6343
6344template <class LHS_TYPE, class RHS_TYPE>
6345inline
6346bool bsl::operator<=(const shared_ptr<LHS_TYPE>& lhs,
6347 const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
6348{
6349 return !(rhs < lhs);
6350}
6351
6352template <class LHS_TYPE, class RHS_TYPE>
6353inline
6354bool bsl::operator>=(const shared_ptr<LHS_TYPE>& lhs,
6355 const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
6356{
6357 return !(lhs < rhs);
6358}
6359
6360#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
6361
6362template <class LHS_TYPE>
6363inline
6364bool bsl::operator==(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
6366{
6367 return !lhs;
6368}
6369
6370#ifdef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
6371
6372template<class TYPE>
6373inline
6374bsl::strong_ordering bsl::operator<=>(const shared_ptr<TYPE>& ptr,
6375 nullptr_t) BSLS_KEYWORD_NOEXCEPT
6376{
6377 const typename shared_ptr<TYPE>::element_type *null = nullptr;
6378 return ptr.get() <=> null;
6379}
6380
6381#else
6382
6383template <class RHS_TYPE>
6384inline
6385bool bsl::operator==(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
6387{
6388 return !rhs;
6389}
6390
6391template <class LHS_TYPE>
6392inline
6393bool bsl::operator!=(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
6395{
6396 return static_cast<bool>(lhs);
6397}
6398
6399template <class RHS_TYPE>
6400inline
6401bool bsl::operator!=(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
6403{
6404 return static_cast<bool>(rhs);
6405}
6406
6407template <class LHS_TYPE>
6408inline
6409bool bsl::operator<(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
6411{
6412 return std::less<LHS_TYPE *>()(lhs.get(), 0);
6413}
6414
6415template <class RHS_TYPE>
6416inline
6417bool bsl::operator<(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
6419{
6420 return std::less<RHS_TYPE *>()(0, rhs.get());
6421}
6422
6423template <class LHS_TYPE>
6424inline
6425bool bsl::operator<=(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
6427{
6428 return !std::less<LHS_TYPE *>()(0, lhs.get());
6429}
6430
6431template <class RHS_TYPE>
6432inline
6433bool bsl::operator<=(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
6435{
6436 return !std::less<RHS_TYPE *>()(rhs.get(), 0);
6437}
6438
6439template <class LHS_TYPE>
6440inline
6441bool bsl::operator>(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
6443{
6444 return std::less<LHS_TYPE *>()(0, lhs.get());
6445}
6446
6447template <class RHS_TYPE>
6448inline
6449bool bsl::operator>(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
6451{
6452 return std::less<RHS_TYPE *>()(rhs.get(), 0);
6453}
6454
6455template <class LHS_TYPE>
6456inline
6457bool bsl::operator>=(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
6459{
6460 return !std::less<LHS_TYPE *>()(lhs.get(), 0);
6461}
6462
6463template <class RHS_TYPE>
6464inline
6465bool bsl::operator>=(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
6467{
6468 return !std::less<RHS_TYPE *>()(0, rhs.get());
6469}
6470
6471#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
6472
6473template <class CHAR_TYPE, class CHAR_TRAITS, class ELEMENT_TYPE>
6474inline
6475std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>&
6476bsl::operator<<(std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& stream,
6477 const shared_ptr<ELEMENT_TYPE>& rhs)
6478{
6479 return stream << rhs.get();
6480}
6481
6482// ASPECTS
6483template <class HASHALG, class ELEMENT_TYPE>
6484inline
6485void bsl::hashAppend(HASHALG& hashAlg, const shared_ptr<ELEMENT_TYPE>& input)
6486{
6487 hashAppend(hashAlg, input.get());
6488}
6489
6490template <class ELEMENT_TYPE>
6491inline
6492void bsl::swap(shared_ptr<ELEMENT_TYPE>& a, shared_ptr<ELEMENT_TYPE>& b)
6494{
6495 a.swap(b);
6496}
6497
6498template <class ELEMENT_TYPE>
6499inline
6500void bsl::swap(weak_ptr<ELEMENT_TYPE>& a, weak_ptr<ELEMENT_TYPE>& b)
6502{
6503 a.swap(b);
6504}
6505
6506// STANDARD FREE FUNCTIONS
6507template<class DELETER, class ELEMENT_TYPE>
6508inline
6509DELETER *bsl::get_deleter(const shared_ptr<ELEMENT_TYPE>& p)
6511{
6512 BloombergLP::bslma::SharedPtrRep *rep = p.rep();
6513 return rep ? static_cast<DELETER *>(rep->getDeleter(typeid(DELETER))) : 0;
6514}
6515
6516// STANDARD CAST FUNCTIONS
6517template<class TO_TYPE, class FROM_TYPE>
6518inline
6520bsl::const_pointer_cast(const shared_ptr<FROM_TYPE>& source)
6522{
6523 return shared_ptr<TO_TYPE>(source, const_cast<TO_TYPE *>(source.get()));
6524}
6525
6526template<class TO_TYPE, class FROM_TYPE>
6527inline
6529bsl::dynamic_pointer_cast(const shared_ptr<FROM_TYPE>& source)
6531{
6532 if (TO_TYPE *castPtr = dynamic_cast<TO_TYPE *>(source.get())) {
6533 return shared_ptr<TO_TYPE>(source, castPtr); // RETURN
6534 }
6535
6536 return shared_ptr<TO_TYPE>();
6537}
6538
6539template<class TO_TYPE, class FROM_TYPE>
6540inline
6542bsl::static_pointer_cast(const shared_ptr<FROM_TYPE>& source)
6544{
6545 return shared_ptr<TO_TYPE>(source, static_cast<TO_TYPE *>(source.get()));
6546}
6547
6548template<class TO_TYPE, class FROM_TYPE>
6549inline
6551bsl::reinterpret_pointer_cast(const shared_ptr<FROM_TYPE>& source)
6553{
6554 return shared_ptr<TO_TYPE>(source,
6555 reinterpret_cast<TO_TYPE *>(source.get()));
6556}
6557
6558// STANDARD FACTORY FUNCTIONS
6559
6560 // ===========================
6561 // allocate_shared(ALLOC, ...)
6562 // ===========================
6563
6564#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
6565// C++11, PERFECT FORWARDING THROUGH A VARIADIC TEMPLATE
6566
6567template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
6571bsl::allocate_shared(ALLOC basicAllocator, ARGS&&... args)
6572{
6573 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6574
6575 typedef BloombergLP::bslstl::
6576 SharedPtrAllocateInplaceRep<ELEMENT_TYPE, ALLOC> Rep;
6577 Rep *rep_p = Rep::makeRep(basicAllocator);
6578
6579 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6581 basicAllocator,
6582 PtrUtil::unqualify(rep_p->ptr()),
6583 BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);
6584 proctor.release();
6585 return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
6586}
6587#endif
6588
6589template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[N]
6590inline
6594bsl::allocate_shared(ALLOC basicAllocator)
6595{
6596 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
6597 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6599 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
6600 typedef BloombergLP::bslstl::
6601 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, ALLOC> Rep;
6602
6603 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
6604 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
6605
6606 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6607 BloombergLP::bslalg::ArrayPrimitives::defaultConstruct(
6608 static_cast<Element_type *> (rep_p->ptr()),
6609 numElements,
6610 ElementAllocatorType(basicAllocator));
6611 proctor.release();
6612
6613 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6614 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6615}
6616
6617template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[N]
6618inline
6623 ALLOC basicAllocator,
6624 const typename bsl::remove_extent<ARRAY_TYPE>::type& value)
6625{
6626 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
6627 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6629 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
6630 typedef BloombergLP::bslstl::
6631 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, ALLOC> Rep;
6632
6633 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
6634 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
6635
6636 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6637 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
6638 static_cast<Element_type *> (rep_p->ptr()),
6639 numElements,
6640 value,
6641 ElementAllocatorType(basicAllocator));
6642 proctor.release();
6643
6644 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6645 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6646}
6647
6648template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[]
6649inline
6653bsl::allocate_shared(ALLOC basicAllocator, size_t numElements)
6654{
6655 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6657 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
6658 typedef BloombergLP::bslstl::
6659 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, ALLOC> Rep;
6660
6661 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
6662
6663 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6664 BloombergLP::bslalg::ArrayPrimitives::defaultConstruct(
6665 static_cast<Element_type *> (rep_p->ptr()),
6666 numElements,
6667 ElementAllocatorType(basicAllocator));
6668 proctor.release();
6669
6670 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6671 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6672}
6673
6674template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[]
6675inline
6680 ALLOC basicAllocator,
6681 size_t numElements,
6682 const typename bsl::remove_extent<ARRAY_TYPE>::type& value)
6683{
6684 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6686 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
6687 typedef BloombergLP::bslstl::
6688 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, ALLOC> Rep;
6689
6690 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
6691
6692 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6693 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
6694 static_cast<Element_type *> (rep_p->ptr()),
6695 numElements,
6696 value,
6697 ElementAllocatorType(basicAllocator));
6698 proctor.release();
6699
6700 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6701 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6702}
6703
6704 // =========================================
6705 // allocate_shared_for_overwrite(ALLOC, ...)
6706 // =========================================
6707
6708template<class ELEMENT_TYPE, class ALLOC>
6709inline
6713bsl::allocate_shared_for_overwrite(ALLOC basicAllocator)
6714{
6715 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6716
6717 typedef BloombergLP::bslstl::
6718 SharedPtrAllocateInplaceRep<ELEMENT_TYPE, ALLOC> Rep;
6719 Rep *rep_p = Rep::makeRep(basicAllocator);
6720
6721 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6722 ::new (PtrUtil::voidify(rep_p->ptr())) ELEMENT_TYPE;
6723 proctor.release();
6724
6725 return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
6726}
6727
6728template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[N]
6729inline
6730typename bsl::enable_if<bsl::is_bounded_array<ARRAY_TYPE>::value &&
6731 !bsl::is_pointer<ALLOC>::value,
6732 bsl::shared_ptr<ARRAY_TYPE> >::type
6733bsl::allocate_shared_for_overwrite(ALLOC basicAllocator)
6734{
6735 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
6736 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6737
6738 typedef BloombergLP::bslstl::
6739 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, ALLOC> Rep;
6740
6741 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
6742 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
6743
6744 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6745 ::new (PtrUtil::voidify(rep_p->ptr())) ARRAY_TYPE;
6746 proctor.release();
6747
6748 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6749 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6750}
6751
6752template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[]
6753inline
6754typename bsl::enable_if<bsl::is_unbounded_array<ARRAY_TYPE>::value &&
6755 !bsl::is_pointer<ALLOC>::value,
6756 bsl::shared_ptr<ARRAY_TYPE> >::type
6757bsl::allocate_shared_for_overwrite(ALLOC basicAllocator, size_t numElements)
6758{
6759 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6760 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6761
6762 typedef BloombergLP::bslstl::
6763 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, ALLOC> Rep;
6764
6765 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
6766
6767 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6768 ::new (PtrUtil::voidify(rep_p->ptr())) Element_type[numElements];
6769 proctor.release();
6770
6771 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6772 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6773}
6774
6775 // =============================
6776 // allocate_shared(ALLOC *, ...)
6777 // =============================
6778
6779#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
6780template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
6781inline
6784bsl::allocate_shared(ALLOC *basicAllocator,
6785 ARGS&&... args)
6786{
6787 typedef bsl::allocator<char> AllocatorType;
6788 typedef bsl::allocator_traits<AllocatorType> AllocatorTraits;
6789 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6790
6791 typedef BloombergLP::bslstl::
6792 SharedPtrAllocateInplaceRep<ELEMENT_TYPE, AllocatorType> Rep;
6793 AllocatorType alloc(basicAllocator);
6794 Rep *rep_p = Rep::makeRep(alloc);
6795
6796 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6797 AllocatorTraits::construct(alloc,
6798 PtrUtil::unqualify(rep_p->ptr()),
6799 BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);
6800 proctor.release();
6801 return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
6802}
6803#endif
6804
6805template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[N]
6806inline
6809bsl::allocate_shared(ALLOC *basicAllocator)
6810{
6811 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
6812 typedef bsl::allocator<char> AllocatorType;
6813 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
6814 ARRAY_TYPE,
6815 AllocatorType> Rep;
6816
6817 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
6818 AllocatorType alloc(basicAllocator);
6819 Rep *rep_p = Rep::makeRep(alloc, numElements);
6820
6821 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6822 BloombergLP::bslalg::ArrayPrimitives::defaultConstruct(rep_p->ptr(),
6823 numElements,
6824 basicAllocator);
6825 proctor.release();
6826
6827 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6828 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6829}
6830
6831template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[N]
6832inline
6836 ALLOC *basicAllocator,
6837 const typename bsl::remove_extent<ARRAY_TYPE>::type& value)
6838{
6839 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
6840 typedef bsl::allocator<char> AllocatorType;
6841 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6842 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
6843 ARRAY_TYPE,
6844 AllocatorType> Rep;
6845
6846 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
6847 AllocatorType alloc(basicAllocator);
6848 Rep *rep_p = Rep::makeRep(alloc, numElements);
6849
6850 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6851 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
6852 static_cast<Element_type *> (rep_p->ptr()),
6853 numElements,
6854 value,
6855 basicAllocator);
6856 proctor.release();
6857
6858 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6859 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6860}
6861
6862template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[]
6863inline
6866bsl::allocate_shared(ALLOC *basicAllocator, size_t numElements)
6867{
6868 typedef bsl::allocator<char> AllocatorType;
6869 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
6870 ARRAY_TYPE,
6871 AllocatorType> Rep;
6872 AllocatorType alloc(basicAllocator);
6873 Rep *rep_p = Rep::makeRep(alloc, numElements);
6874
6875 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6876 BloombergLP::bslalg::ArrayPrimitives::defaultConstruct(rep_p->ptr(),
6877 numElements,
6878 basicAllocator);
6879 proctor.release();
6880
6881 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6882 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6883}
6884
6885template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[]
6886inline
6890 ALLOC *basicAllocator,
6891 size_t numElements,
6892 const typename bsl::remove_extent<ARRAY_TYPE>::type& value)
6893{
6894 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6895 typedef bsl::allocator<char> AllocatorType;
6896 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
6897 ARRAY_TYPE,
6898 AllocatorType> Rep;
6899 AllocatorType alloc(basicAllocator);
6900 Rep *rep_p = Rep::makeRep(alloc, numElements);
6901
6902 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6903 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
6904 static_cast<Element_type *> (rep_p->ptr()),
6905 numElements,
6906 value,
6907 basicAllocator);
6908 proctor.release();
6909
6910 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6911 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6912}
6913
6914 // ===========================================
6915 // allocate_shared_for_overwrite(ALLOC *, ...)
6916 // ===========================================
6917
6918template<class ELEMENT_TYPE, class ALLOC>
6919inline
6922bsl::allocate_shared_for_overwrite(ALLOC *basicAllocator)
6923{
6924 typedef bsl::allocator<char> AllocatorType;
6925 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6926
6927 typedef BloombergLP::bslstl::
6928 SharedPtrAllocateInplaceRep<ELEMENT_TYPE, AllocatorType> Rep;
6929 AllocatorType alloc(basicAllocator);
6930 Rep *rep_p = Rep::makeRep(alloc);
6931
6932 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6933 ::new (PtrUtil::voidify(rep_p->ptr())) ELEMENT_TYPE;
6934 proctor.release();
6935
6936 return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
6937}
6938
6939
6940template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[N]
6941inline
6942typename bsl::enable_if<bsl::is_bounded_array<ARRAY_TYPE>::value,
6943 bsl::shared_ptr<ARRAY_TYPE> >::type
6944bsl::allocate_shared_for_overwrite(ALLOC *basicAllocator)
6945{
6946 typedef bsl::allocator<char> AllocatorType;
6947 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
6948 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6949
6950 typedef BloombergLP::bslstl::
6951 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, AllocatorType> Rep;
6952
6953 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
6954 AllocatorType alloc(basicAllocator);
6955 Rep *rep_p = Rep::makeRep(alloc, numElements);
6956
6957 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6958 ::new (PtrUtil::voidify(rep_p->ptr())) ARRAY_TYPE;
6959 proctor.release();
6960
6961 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6962 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6963}
6964
6965template<class ARRAY_TYPE, class ALLOC> // ARRAY_TYPE is T[]
6966inline
6967typename bsl::enable_if<bsl::is_unbounded_array<ARRAY_TYPE>::value,
6968 bsl::shared_ptr<ARRAY_TYPE> >::type
6969bsl::allocate_shared_for_overwrite(ALLOC *basicAllocator, size_t numElements)
6970{
6971 typedef bsl::allocator<char> AllocatorType;
6972 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
6973 typedef BloombergLP::bslma::PointerUtil PtrUtil;
6974
6975 typedef BloombergLP::bslstl::
6976 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, AllocatorType> Rep;
6977 AllocatorType alloc(basicAllocator);
6978 Rep *rep_p = Rep::makeRep(alloc, numElements);
6979
6980 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
6981 ::new (PtrUtil::voidify(rep_p->ptr())) Element_type[numElements];
6982 proctor.release();
6983
6984 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
6985 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
6986}
6987
6988 // ================
6989 // make_shared(...)
6990 // ================
6991
6992#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
6993// @ref make_shared using the default allocator
6994
6995template<class ELEMENT_TYPE, class... ARGS>
6996inline
6999bsl::make_shared(ARGS&&... args)
7000{
7001 typedef bsl::allocator<char> AllocatorType;
7002 typedef BloombergLP::bslma::PointerUtil PtrUtil;
7003
7004 typedef BloombergLP::bslstl::
7005 SharedPtrAllocateInplaceRep<ELEMENT_TYPE, AllocatorType> Rep;
7006
7007 AllocatorType basicAllocator;
7008 Rep *rep_p = Rep::makeRep(basicAllocator);
7009
7010 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7011 ::new (PtrUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
7012 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
7013 proctor.release();
7014
7015 return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
7016}
7017#endif
7018
7019template<class ARRAY_TYPE> // ARRAY_TYPE is T[N]
7020inline
7024{
7025 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
7026 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
7027 typedef bsl::allocator<char> AllocatorType;
7029 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
7030 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
7031 ARRAY_TYPE,
7032 AllocatorType> Rep;
7033
7034 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
7035 AllocatorType basicAllocator;
7036 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
7037
7038 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7039 BloombergLP::bslalg::ArrayPrimitives::defaultConstruct(
7040 rep_p->ptr(),
7041 numElements,
7042 ElementAllocatorType(basicAllocator));
7043 proctor.release();
7044
7045 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
7046 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
7047}
7048
7049template<class ARRAY_TYPE> // ARRAY_TYPE is T[N]
7050inline
7054{
7055 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
7056 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
7057 typedef bsl::allocator<char> AllocatorType;
7059 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
7060 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
7061 ARRAY_TYPE,
7062 AllocatorType> Rep;
7063
7064 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
7065 AllocatorType basicAllocator;
7066 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
7067
7068 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7069 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
7070 rep_p->ptr(),
7071 numElements,
7072 value,
7073 ElementAllocatorType(basicAllocator));
7074 proctor.release();
7075
7076 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
7077 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
7078}
7079
7080template<class ARRAY_TYPE> // ARRAY_TYPE is T[]
7081inline
7084bsl::make_shared(size_t numElements)
7085{
7086 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
7087 typedef bsl::allocator<char> AllocatorType;
7089 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
7090 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
7091 ARRAY_TYPE,
7092 AllocatorType> Rep;
7093
7094 AllocatorType basicAllocator;
7095 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
7096
7097 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7098 BloombergLP::bslalg::ArrayPrimitives::defaultConstruct(
7099 rep_p->ptr(),
7100 numElements,
7101 ElementAllocatorType(basicAllocator));
7102 proctor.release();
7103
7104 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
7105 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
7106}
7107
7108template<class ARRAY_TYPE> // ARRAY_TYPE is T[]
7109inline
7113 size_t numElements,
7114 const typename bsl::remove_extent<ARRAY_TYPE>::type& value)
7115{
7116 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
7117 typedef bsl::allocator<char> AllocatorType;
7119 rebind_traits<Element_type>::allocator_type ElementAllocatorType;
7120 typedef BloombergLP::bslstl::SharedPtrArrayAllocateInplaceRep<
7121 ARRAY_TYPE,
7122 AllocatorType> Rep;
7123
7124 AllocatorType basicAllocator;
7125 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
7126
7127 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7128 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
7129 rep_p->ptr(),
7130 numElements,
7131 value,
7132 ElementAllocatorType(basicAllocator));
7133 proctor.release();
7134
7135 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
7136 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
7137}
7138
7139 // ==============================
7140 // make_shared_for_overwrite(...)
7141 // ==============================
7142
7143template<class ELEMENT_TYPE>
7144inline
7148{
7149 typedef bsl::allocator<char> AllocatorType;
7150 typedef BloombergLP::bslma::PointerUtil PtrUtil;
7151
7152 typedef BloombergLP::bslstl::
7153 SharedPtrAllocateInplaceRep<ELEMENT_TYPE, AllocatorType> Rep;
7154
7155 AllocatorType basicAllocator;
7156 Rep *rep_p = Rep::makeRep(basicAllocator);
7157
7158 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7159 ::new (PtrUtil::voidify(rep_p->ptr())) ELEMENT_TYPE;
7160 proctor.release();
7161
7162 return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
7163}
7164
7165template<class ARRAY_TYPE> // ARRAY_TYPE is T[N]
7166inline
7167typename bsl::enable_if<bsl::is_bounded_array<ARRAY_TYPE>::value,
7168 bsl::shared_ptr<ARRAY_TYPE> >::type
7169bsl::make_shared_for_overwrite()
7170{
7171 typedef bsl::allocator<char> AllocatorType;
7172 typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
7173 typedef BloombergLP::bslma::PointerUtil PtrUtil;
7174
7175 typedef BloombergLP::bslstl::
7176 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, AllocatorType> Rep;
7177
7178 const size_t numElements = ImpUtil::Extent<ARRAY_TYPE>::value;
7179 AllocatorType basicAllocator;
7180 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
7181
7182 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7183 ::new (PtrUtil::voidify(rep_p->ptr())) ARRAY_TYPE;
7184
7185 proctor.release();
7186
7187 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
7188 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
7189}
7190
7191template<class ARRAY_TYPE> // ARRAY_TYPE is T[]
7192inline
7193typename bsl::enable_if<bsl::is_unbounded_array<ARRAY_TYPE>::value,
7194 bsl::shared_ptr<ARRAY_TYPE> >::type
7195bsl::make_shared_for_overwrite(size_t numElements)
7196{
7197 typedef bsl::allocator<char> AllocatorType;
7198 typedef typename bsl::remove_extent<ARRAY_TYPE>::type Element_type;
7199 typedef BloombergLP::bslma::PointerUtil PtrUtil;
7200
7201 typedef BloombergLP::bslstl::
7202 SharedPtrArrayAllocateInplaceRep<ARRAY_TYPE, AllocatorType> Rep;
7203
7204 AllocatorType basicAllocator;
7205 Rep *rep_p = Rep::makeRep(basicAllocator, numElements);
7206
7207 BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
7208 ::new (PtrUtil::voidify(rep_p->ptr())) Element_type[numElements];
7209
7210 proctor.release();
7211
7212 BloombergLP::bslma::SharedPtrRep *upcastRep = rep_p;
7213 return shared_ptr<ARRAY_TYPE>(rep_p->ptr(), upcastRep);
7214}
7215
7216// ============================================================================
7217// TYPE TRAITS
7218// ============================================================================
7219
7220// Type traits for smart pointers:
7221//: o 'shared_ptr' has pointer semantics, but 'weak_ptr' does not.
7222//:
7223//: o Although 'shared_ptr' constructs with an allocator, it does not 'use' an
7224//: allocator in the manner of the 'UsesBslmaAllocator' trait, and should be
7225//: explicitly specialized as a clear sign to code inspection tools.
7226//:
7227//: o Smart pointers are bitwise-movable as long as there is no opportunity for
7228//: holding a pointer to internal state in the immediate object itself. As
7229//: 'd_ptr_p' is never exposed by reference, it is not possible to create an
7230//: internal pointer, so the trait should be 'true'.
7231
7232
7233
7234namespace bslma {
7235
7236template <class ELEMENT_TYPE>
7237struct UsesBslmaAllocator< ::bsl::shared_ptr<ELEMENT_TYPE> >
7239{};
7240
7241} // close namespace bslma
7242
7243namespace bslmf {
7244
7245template <class ELEMENT_TYPE>
7246struct HasPointerSemantics< ::bsl::shared_ptr<ELEMENT_TYPE> >
7248{};
7249
7250template <class ELEMENT_TYPE>
7251struct IsBitwiseMoveable< ::bsl::shared_ptr<ELEMENT_TYPE> >
7253{};
7254
7255template <class ELEMENT_TYPE>
7256struct IsBitwiseMoveable< ::bsl::weak_ptr<ELEMENT_TYPE> >
7258{};
7259
7260} // close namespace bslmf
7261
7262
7263
7264#if defined(BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC)
7265# pragma GCC diagnostic pop
7266#endif
7267
7268#undef BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
7269#undef BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE
7270
7271#undef BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE
7272#undef BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE
7273
7274#undef BSLSTL_SHAREDPTR_DECLARE_IF_DELETER
7275#undef BSLSTL_SHAREDPTR_DEFINE_IF_DELETER
7276
7277#undef BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER
7278#undef BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER
7279
7280#undef BSLSTL_SHAREDPTR_MSVC_DECLTYPE_WORKAROUND
7281
7282#undef BSLSTL_SHAREDPTR_SFINAE_DISCARD
7283
7284#endif // End C++11 code
7285
7286#endif
7287
7288// ----------------------------------------------------------------------------
7289// Copyright 2023 Bloomberg Finance L.P.
7290//
7291// Licensed under the Apache License, Version 2.0 (the "License");
7292// you may not use this file except in compliance with the License.
7293// You may obtain a copy of the License at
7294//
7295// http://www.apache.org/licenses/LICENSE-2.0
7296//
7297// Unless required by applicable law or agreed to in writing, software
7298// distributed under the License is distributed on an "AS IS" BASIS,
7299// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7300// See the License for the specific language governing permissions and
7301// limitations under the License.
7302// ----------------------------- END-OF-FILE ----------------------------------
7303
7304/** @} */
7305/** @} */
7306/** @} */
Definition bslma_bslallocator.h:588
Definition bslstl_sharedptr.h:4073
bsl::weak_ptr< ELEMENT_TYPE > weak_from_this() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:4781
bsl::shared_ptr< ELEMENT_TYPE > shared_from_this()
Definition bslstl_sharedptr.h:4765
enable_shared_from_this() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:4730
friend struct BloombergLP::bslstl::SharedPtr_ImpUtil
Definition bslstl_sharedptr.h:4079
Definition bslstl_pair.h:1280
Definition bslstl_sharedptr.h:1838
void swap(shared_ptr &other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5516
shared_ptr(const shared_ptr &original) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5215
shared_ptr(BloombergLP::bslmf::MovableRef< weak_ptr< COMPATIBLE_TYPE > > ptr)
Definition bslstl_sharedptr.h:5291
BloombergLP::bslma::SharedPtrRep * rep() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5761
shared_ptr(BloombergLP::bslmf::MovableRef< shared_ptr< COMPATIBLE_TYPE > > other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5253
element_type * ptr() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5779
shared_ptr & operator=(const shared_ptr &rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5327
shared_ptr(BloombergLP::bslmf::MovableRef< shared_ptr > original) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5227
BSLMF_NESTED_TRAIT_DECLARATION(shared_ptr< ELEMENT_TYPE >, bsl::is_nothrow_move_constructible)
enable_if< is_convertible< COMPATIBLE_TYPE *, ELEMENT_TYPE * >::value, shared_ptr & >::type operator=(BloombergLP::bslma::ManagedPtr< COMPATIBLE_TYPE > rhs)
Definition bslstl_sharedptr.h:5409
void reset() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5449
size_t owner_hash() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5721
long use_count() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5735
weak_ptr< ELEMENT_TYPE > weak_type
Definition bslstl_sharedptr.h:1854
bool owner_equal(const shared_ptr< ANY_TYPE > &other) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5702
shared_ptr(const shared_ptr< COMPATIBLE_TYPE > &other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5205
pair< element_type *, BloombergLP::bslma::SharedPtrRep * > release() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5583
shared_ptr(const shared_ptr< ANY_TYPE > &source, ELEMENT_TYPE *object) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5190
enable_if< is_convertible< COMPATIBLE_TYPE *, ELEMENT_TYPE * >::value, shared_ptr & >::type operator=(BloombergLP::bslmf::MovableRef< shared_ptr< COMPATIBLE_TYPE > > rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5390
void load(COMPATIBLE_TYPE *ptr)
Definition bslstl_sharedptr.h:5604
void createInplace(BloombergLP::bslma::Allocator *basicAllocator, ARGS &&... args)
Definition bslstl_sharedptr.h:5554
BSLS_KEYWORD_CONSTEXPR shared_ptr() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:4847
ELEMENT_TYPE * operator->() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5656
friend class shared_ptr
Definition bslstl_sharedptr.h:1875
friend struct BloombergLP::bslstl::SharedPtr_ImpUtil
Definition bslstl_sharedptr.h:1877
enable_if< is_convertible< COMPATIBLE_TYPE *, ELEMENT_TYPE * >::value, shared_ptr & >::type operator=(const shared_ptr< COMPATIBLE_TYPE > &rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5362
add_lvalue_reference< ELEMENT_TYPE >::type operator*() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5647
element_type * get() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5665
bsl::remove_extent< ELEMENT_TYPE >::type element_type
Definition bslstl_sharedptr.h:1850
add_lvalue_reference< element_type >::type operator[](ptrdiff_t index) const
Definition bslstl_sharedptr.h:5673
BloombergLP::bslma::ManagedPtr< ELEMENT_TYPE > managedPtr() const
Definition bslstl_sharedptr.h:5743
shared_ptr(const weak_ptr< COMPATIBLE_TYPE > &ptr)
Definition bslstl_sharedptr.h:5266
void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5596
void loadAlias(const shared_ptr< ANY_TYPE > &source, ELEMENT_TYPE *object)
Definition bslstl_sharedptr.h:5570
shared_ptr & operator=(BloombergLP::bslmf::MovableRef< shared_ptr > rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5345
~shared_ptr()
Definition bslstl_sharedptr.h:5317
int numReferences() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5771
void createInplace()
Definition bslstl_sharedptr.h:5539
bool owner_before(const shared_ptr< ANY_TYPE > &other) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5683
Definition bslstl_sharedptr.h:3773
enable_if< is_convertible< COMPATIBLE_TYPE *, ELEMENT_TYPE * >::value, weak_ptr & >::type operator=(const shared_ptr< COMPATIBLE_TYPE > &rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5959
shared_ptr< ELEMENT_TYPE > lock() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6031
friend class weak_ptr
Definition bslstl_sharedptr.h:3798
~weak_ptr()
Definition bslstl_sharedptr.h:5876
size_t owner_hash() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6089
void swap(weak_ptr &other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6004
void reset() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5992
bool owner_before(const shared_ptr< ANY_TYPE > &other) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6048
BSLMF_NESTED_TRAIT_DECLARATION(weak_ptr< ELEMENT_TYPE >, bsl::is_nothrow_move_constructible)
enable_if< is_convertible< COMPATIBLE_TYPE *, ELEMENT_TYPE * >::value, weak_ptr & >::type operator=(BloombergLP::bslmf::MovableRef< weak_ptr< COMPATIBLE_TYPE > > rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5929
long use_count() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6104
BloombergLP::bslma::SharedPtrRep * rep() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6096
weak_ptr(const weak_ptr &original) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5838
shared_ptr< ELEMENT_TYPE > acquireSharedPtr() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6113
bsl::remove_extent< ELEMENT_TYPE >::type element_type
Definition bslstl_sharedptr.h:3812
weak_ptr(const shared_ptr< COMPATIBLE_TYPE > &other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5851
weak_ptr & operator=(const weak_ptr &rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5940
friend struct BloombergLP::bslstl::SharedPtr_ImpUtil
Definition bslstl_sharedptr.h:3800
weak_ptr(BloombergLP::bslmf::MovableRef< weak_ptr< COMPATIBLE_TYPE > > other) BSLS_KEYWORD_NOEXCEPT
BSLS_KEYWORD_CONSTEXPR weak_ptr() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5793
enable_if< is_convertible< COMPATIBLE_TYPE *, ELEMENT_TYPE * >::value, weak_ptr & >::type operator=(const weak_ptr< COMPATIBLE_TYPE > &rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5977
weak_ptr(const weak_ptr< COMPATIBLE_TYPE > &other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5864
bool owner_equal(const shared_ptr< ANY_TYPE > &other) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6070
int numReferences() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6121
weak_ptr & operator=(BloombergLP::bslmf::MovableRef< weak_ptr > rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5901
bool expired() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6025
Definition bslma_allocator.h:545
Definition bslma_sharedptrrep.h:338
Definition bslstl_sharedptr.h:4395
void release() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:6288
~SharedPtr_RepProctor()
Definition bslstl_sharedptr.h:6279
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:387
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(FUNCTOR, ARGUMENT)
Definition bslstl_sharedptr.h:1714
#define BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(FUNCTOR)
Definition bslstl_sharedptr.h:1716
#define BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(FUNCTOR)
Definition bslstl_sharedptr.h:1717
#define BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE
Definition bslstl_sharedptr.h:1711
#define BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE
Definition bslstl_sharedptr.h:1708
#define BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
Definition bslstl_sharedptr.h:1707
#define BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(FUNCTOR, ARGUMENT)
Definition bslstl_sharedptr.h:1713
#define BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE
Definition bslstl_sharedptr.h:1710
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
Definition bdlat_valuetypefunctions.h:939
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:283
enable_if< is_bounded_array< ARRAY_TYPE >::value, shared_ptr< ARRAY_TYPE > >::type make_shared()
shared_ptr< TO_TYPE > const_pointer_cast(const shared_ptr< FROM_TYPE > &source) BSLS_KEYWORD_NOEXCEPT
shared_ptr< TO_TYPE > dynamic_pointer_cast(const shared_ptr< FROM_TYPE > &source) BSLS_KEYWORD_NOEXCEPT
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:959
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
BSLS_KEYWORD_CONSTEXPR_CPP14 TYPE & get(array< TYPE, SIZE > &a) BSLS_KEYWORD_NOEXCEPT
DELETER * get_deleter(const shared_ptr< ELEMENT_TYPE > &p) BSLS_KEYWORD_NOEXCEPT
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
shared_ptr< TO_TYPE > reinterpret_pointer_cast(const shared_ptr< FROM_TYPE > &source) BSLS_KEYWORD_NOEXCEPT
shared_ptr< TO_TYPE > static_pointer_cast(const shared_ptr< FROM_TYPE > &source) BSLS_KEYWORD_NOEXCEPT
enable_if<!is_array< ELEMENT_TYPE >::value &&!is_pointer< ALLOC >::value, shared_ptr< ELEMENT_TYPE > >::type allocate_shared(ALLOC basicAllocator, ARGS &&... args)
bool operator==(const memory_resource &a, const memory_resource &b)
std::basic_ostream< CHAR_TYPE, TRAITS > & operator<<(std::basic_ostream< CHAR_TYPE, TRAITS > &os, const bitset< N > &x)
Definition bslstl_bitset.h:1417
enable_if<!is_array< ELEMENT_TYPE >::value, shared_ptr< ELEMENT_TYPE > >::type make_shared_for_overwrite()
ALLOCATOR & lhs
Definition bslstl_string.h:3917
bool operator!=(const memory_resource &a, const memory_resource &b)
enable_if<!is_array< ELEMENT_TYPE >::value &&!is_pointer< ALLOC >::value, shared_ptr< ELEMENT_TYPE > >::type allocate_shared_for_overwrite(ALLOC basicAllocator)
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bslstl_algorithm.h:84
Definition bslmf_addlvaluereference.h:128
t_TYPE & type
This typedef defines the return type of this meta function.
Definition bslmf_addlvaluereference.h:131
BloombergLP::bslmf::AddPointer_Impl< t_TYPE >::type type
Definition bslmf_addpointer.h:181
Definition bslma_allocatortraits.h:1089
static void construct(ALLOCATOR_TYPE &basicAllocator, ELEMENT_TYPE *elementAddr, Args &&... arguments)
Definition bslma_allocatortraits.h:1527
Definition bslmf_conditional.h:123
Definition bslmf_enableif.h:530
Definition bslstl_hash.h:495
Definition bslmf_integralconstant.h:261
Definition bslmf_isarray.h:168
Definition bslmf_isconvertible.h:875
Definition bslmf_isnothrowmoveconstructible.h:361
Definition bslmf_ispointer.h:138
Definition bslstl_ownerequal.h:124
Definition bslstl_ownerhash.h:174
t_TYPE type
Definition bslmf_removeextent.h:134
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_haspointersemantics.h:83
Definition bslmf_isbitwisemoveable.h:718
Definition bslstl_sharedptr.h:4289
void operator()(const volatile void *) const BSLS_KEYWORD_NOEXCEPT
No-Op.
Definition bslstl_sharedptr.h:6238
Definition bslstl_sharedptr.h:4177
static void staticCast(bsl::shared_ptr< TARGET > *target, const bsl::shared_ptr< SOURCE > &source)
Definition bslstl_sharedptr.h:6214
static bsl::shared_ptr< char > createInplaceUninitializedBuffer(size_t bufferSize, bslma::Allocator *basicAllocator=0)
static void constCast(bsl::shared_ptr< TARGET > *target, const bsl::shared_ptr< SOURCE > &source)
Definition bslstl_sharedptr.h:6166
static void dynamicCast(bsl::shared_ptr< TARGET > *target, const bsl::shared_ptr< SOURCE > &source)
Definition bslstl_sharedptr.h:6186
Definition bslstl_sharedptr.h:4308
void operator()(ANY_TYPE *ptr) const BSLS_KEYWORD_NOEXCEPT
Call delete with the specified ptr.
Definition bslstl_sharedptr.h:4336
Definition bslstl_sharedptr.h:4328
static void throwBadWeakPtr()
Throw a bsl::bad_weak_ptr exception.
static void loadEnableSharedFromThis(const bsl::enable_shared_from_this< ENABLE_TYPE > *result, bsl::shared_ptr< SHARED_TYPE > *sharedPtr)
Definition bslstl_sharedptr.h:6138
Definition bslstl_sharedptr.h:1752