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