// bslstl_sharedptr_cpp03.h                                           -*-C++-*-

// Automatically generated file.  **DO NOT EDIT**

#ifndef INCLUDED_BSLSTL_SHAREDPTR_CPP03
#define INCLUDED_BSLSTL_SHAREDPTR_CPP03

//@PURPOSE: Provide C++03 implementation for bslstl_sharedptr.h
//
//@CLASSES: See bslstl_sharedptr.h for list of classes
//
//@SEE_ALSO: bslstl_sharedptr
//
//@DESCRIPTION:  This component is the C++03 translation of a C++11 component,
// generated by the 'sim_cpp11_features.pl' program.  If the original header
// contains any specially delimited regions of C++11 code, then this generated
// file contains the C++03 equivalent, i.e., with variadic templates expanded
// and rvalue-references replaced by 'bslmf::MovableRef' objects.  The header
// code in this file is designed to be '#include'd into the original header
// when compiling with a C++03 compiler.  If there are no specially delimited
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Wed Feb 15 08:05:34 2023
// Command line: sim_cpp11_features.pl bslstl_sharedptr.h

#ifdef COMPILING_BSLSTL_SHAREDPTR_H

#if defined(BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC)
        // Here and throughout the file wherever 'auto_ptr' is used, suspend
        // GCC reporting of deprecated declarations since the use of 'auto_ptr'
        // in this standard interface is required.
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif

#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS) \
 && (!defined(BSLS_PLATFORM_CMP_MSVC) || BSLS_PLATFORM_CMP_VERSION >= 1900)
# define BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS 1

#if BSLS_PLATFORM_CMP_VERSION >= 1910 &&                                      \
    BSLS_PLATFORM_CMP_VERSION <  1920 &&                                      \
    BSLS_COMPILERFEATURES_CPLUSPLUS >= 201703L
// Visual Studio 2017 in C++17 mode crashes with an internal compiler error on
// the shared pointer SFINAE code.  See {DRQS 148281696}.
# undef BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS
#endif

// If the macro 'BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS' is defined, then a
// conforming C++11 compiler will define the constructors in this component in
// such a way that they will not be selected during overload resolution unless
// they would instantiate correctly.  This means that code depending on the
// result of 'is_constructible' and similar traits will have the expected
// behavior.  There is no attempt to support this feature in C++03.
//
// Support for SFINAE-queries on the constructability of a 'shared_ptr' depend
// on a variety of C++11 language features, including "expression-SFINAE".
// However, the main language feature that enables SFINAE elimination of a
// constructor is the ability to use default template arguments in a function
// template.  It is significantly preferred to use the template parameter list,
// rather than add additional default arguments to the constructor signatures,
// as there are so many constructor overloads in this component that there is a
// real risk of introducing ambiguities that would need to be worked around.
// Therefore, the 'BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS' macro
// serves as our proxy for whether SFINAE-constructors are enabled in this
// component.  Note that the MSVC 2015 compiler almost supported
// "expression-SFINAE", to the extent that it works for this component, unlike
// earlier versions of that compiler.  We therefore make a special version-test
// on Microsoft in addition to the feature testing.
#endif

# if defined(BSLS_PLATFORM_CMP_GNU)
# define BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER 1
// If the macro 'BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER' is
// defined, we recognize that some compilers need an extra hint to disambiguate
// overload resolution when passed a 'bslma::Allocator *' pointer, that might
// also deduce (incorrectly) as a C++11-style allocator.  Gcc is known to have
// this problem, and was tested as recently as gcc 9. This compiler has a
// problem partially ordering function templates that differ only by the first
// argument deducing as any object type ('T'), or deducing as the a pointer to
// something ('T*').  The rules for partial ordering should make the second
// overload a stronger match when passed a pointer; however, this compiler
// complains about ambiguities when additional parameters are involved.  This
// appears to be fixed in gcc 10.
#endif

#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
// Note the intentional comma in the first line of the definition of each
// macro, which allows these macros to be applied incrementally, even when the
// alternate definition is empty.  This avoids the problem of introducing new
// template parameters along with the macros in the non-SFINAE-supporting case
// below.
# define BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE ,                            \
    typename enable_if<                                                       \
        BloombergLP::bslstl::SharedPtr_IsPointerConvertible<                  \
                            CONVERTIBLE_TYPE,                                 \
                            ELEMENT_TYPE>::value>::type *                     \
                                                                = nullptr

# define BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE ,                             \
    typename enable_if<                                                       \
        BloombergLP::bslstl::SharedPtr_IsPointerConvertible<                  \
                            CONVERTIBLE_TYPE,                                 \
                            ELEMENT_TYPE>::value>::type *


# define BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE ,                             \
    typename enable_if<                                                       \
        BloombergLP::bslstl::SharedPtr_IsPointerCompatible<                   \
                            COMPATIBLE_TYPE,                                  \
                            ELEMENT_TYPE>::value>::type *                     \
                                                                = nullptr

# define BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE ,                              \
    typename enable_if<                                                       \
        BloombergLP::bslstl::SharedPtr_IsPointerCompatible<                   \
                            COMPATIBLE_TYPE,                                  \
                            ELEMENT_TYPE>::value>::type *


# define BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(FUNCTOR, ARGUMENT) ,             \
    typename enable_if<                                                       \
      BloombergLP::bslstl::SharedPtr_IsCallable  <FUNCTOR,                    \
                                                  ARGUMENT *>::k_VALUE ||     \
      BloombergLP::bslstl::SharedPtr_IsFactoryFor<FUNCTOR,                    \
                                                  ARGUMENT>::k_VALUE>::type * \
                                                                      = nullptr

# define BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(FUNCTOR, ARGUMENT) ,              \
    typename enable_if<                                                       \
      BloombergLP::bslstl::SharedPtr_IsCallable  <FUNCTOR,                    \
                                                  ARGUMENT *>::k_VALUE ||     \
      BloombergLP::bslstl::SharedPtr_IsFactoryFor<FUNCTOR,                    \
                                                  ARGUMENT  >::k_VALUE>::type *


# define BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(FUNCTOR) ,               \
    typename enable_if<                                                       \
      BloombergLP::bslstl::SharedPtr_IsCallable  <FUNCTOR,                    \
                                                  nullptr_t>::k_VALUE ||      \
      BloombergLP::bslstl::SharedPtr_IsNullableFactory<                       \
                                           FUNCTOR>::k_VALUE>::type * = nullptr

# define BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(FUNCTOR) ,                \
    typename enable_if<                                                       \
      BloombergLP::bslstl::SharedPtr_IsCallable  <FUNCTOR,                    \
                                                  nullptr_t>::k_VALUE ||      \
      BloombergLP::bslstl::SharedPtr_IsNullableFactory<                       \
                                                     FUNCTOR>::k_VALUE>::type *
#else
// Do not attempt to support SFINAE in constructors in a C++03 compiler
# define BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
# define BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE

# define BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE
# define BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE

# define BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(FUNCTOR, ARGUMENT)
# define BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(FUNCTOR, ARGUMENT)

# define BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(FUNCTOR)
# define BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(FUNCTOR)
#endif  // BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS

// Some SFINAE checks, when enabled, make use of discarded-value expressions
// (as the left-hand side of a comma operator). Clang compilers based on
// versions of LLVM earlier than 12 contain a bug in which substitution
// failures are not caught in discarded-value expressions when used in SFINAE
// contexts (this includes Clang 11 and earlier, and Apple Clang 13 and
// earlier).  In order to ensure that these compilers catch substitution
// failures in such expressions, this component does not discard them.  Note
// that this is dangerous, because not discarding the expression allows the
// possibility that the comma operator will be overloaded on the type of the
// expression, and so it is preferable to discard the expression where
// possible.
#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
# if !defined(BSLS_PLATFORM_CMP_CLANG)                             \
  || !defined(__APPLE_CC__) && BSLS_PLATFORM_CMP_VERSION >= 120000 \
  ||  defined(__APPLE_CC__) && BSLS_PLATFORM_CMP_VERSION >  130000
#  define BSLSTL_SHAREDPTR_SFINAE_DISCARD(EXPRESSION) \
     static_cast<void>(EXPRESSION)
# else
#  define BSLSTL_SHAREDPTR_SFINAE_DISCARD(EXPRESSION) \
     (EXPRESSION)
# endif
#endif

namespace BloombergLP {
namespace bslstl {

struct SharedPtr_RepFromExistingSharedPtr {
    // This 'struct' is for internal use only, providing a tag for 'shared_ptr'
    // constructors to recognize that a passed 'SharedPtrRep' was obtained from
    // an existing 'shared_ptr' object.
};

struct SharedPtr_ImpUtil;
    // Forward declaration of 'SharedPtr_ImpUtil'. This is needed because this
    // struct is a friend of 'enable_shared_from_this' in the 'bsl' namespace.

#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
template <class FUNCTOR, class ARG>
struct SharedPtr_IsCallable;
    // Forward declaration of component-private type trait to indicate whether
    // an object of (template parameter) type 'FUNCTOR' can be called as a
    // function with an argument of (template parameter) type 'ARG'

template <class FACTORY, class ARG>
struct SharedPtr_IsFactoryFor;
    // Forward declaration of component-private type trait to indicate whether
    // a pointer to a 'FACTORY' has a 'deleteObject' member that can be called
    // as 'factory->deleteObject((ARG *)p)'.

template <class FACTORY>
struct SharedPtr_IsNullableFactory;
    // Forward declaration of component-private type trait to indicate whether
    // a pointer to a 'FACTORY' has a 'deleteObject' member that can be called
    // as 'factory->deleteObject((ARG *)p)'.

template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerConvertible;
    // Forward declaration of component-private type trait to indicate whether
    // a pointer to a 'SOURCE_TYPE' can be converted to a pointer to a
    // 'DEST_TYPE'.  [util.smartptr.shared.const]/8 says "either DEST_TYPE is
    // U[N] and SOURCE_TYPE(*)[N] is convertible to DEST_TYPE*, or DEST_TYPE is
    // U[] and SOURCE_TYPE(*)[] is convertible to DEST_TYPE*".

template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerCompatible;
    // Forward declaration of component-private type trait to indicate whether
    // a pointer to a 'SOURCE_TYPE' is compatible with a pointer to
    // 'DEST_TYPE'.  [util.smartptr.shared]/5 says: "for the purposes of ...,
    // a pointer type SOURCE_TYPE* is said to be compatible with a pointer type
    // DEST_TYPE* when either SOURCE_TYPE* is convertible to DEST_TYPE* or
    // SOURCE_TYPE is U[N] and DEST_TYPE is cv U[]."

#endif

}  // close package namespace
}  // close enterprise namespace

namespace bsl {

template<class ELEMENT_TYPE>
class enable_shared_from_this;

template <class ELEMENT_TYPE>
class shared_ptr;

template <class ELEMENT_TYPE>
class weak_ptr;

                        // ================
                        // class shared_ptr
                        // ================

template <class ELEMENT_TYPE>
class shared_ptr {
    // This class provides a thread-safe reference-counted "smart pointer" to
    // support "shared ownership" of objects: a shared pointer ensures that the
    // shared object is destroyed, using the appropriate deletion method, only
    // when there are no shared references to it.  The object (of template
    // parameter type 'ELEMENT_TYPE') referred to by a shared pointer may be
    // accessed directly using the '->' operator, or the dereference operator
    // (operator '*') can be used to obtain a reference to that object.
    //
    // Note that the object referred to by a shared pointer representation is
    // usually the same as the object referred to by that shared pointer (of
    // the same 'ELEMENT_TYPE'), but this need not always be true in the
    // presence of conversions or "aliasing": the object referred to (of
    // template parameter type 'ELEMENT_TYPE') by the shared pointer may differ
    // from the object of type 'COMPATIBLE_TYPE' (see the "Aliasing" section in
    // the component-level documentation) referred to by the shared pointer
    // representation.
    //
    // More generally, this class supports a complete set of *in*-*core*
    // pointer semantic operations.

  public:
    // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(shared_ptr<ELEMENT_TYPE>,
                                   bsl::is_nothrow_move_constructible);

    // TYPES
    typedef typename bsl::remove_extent<ELEMENT_TYPE>::type element_type;
        // For shared pointers to non-array types, 'element_type' is an alias
        // to the 'ELEMENT_TYPE' template parameter.  Otherwise, it is an alias
        // to the type contained in the array.

    typedef weak_ptr<ELEMENT_TYPE> weak_type;
        // 'weak_type' is an alias to a weak pointer with the same element type
        // as this 'shared_ptr'.

  private:
    // DATA
    element_type                     *d_ptr_p; // pointer to the shared object

    BloombergLP::bslma::SharedPtrRep *d_rep_p; // pointer to the representation
                                               // object that manages the
                                               // shared object

    // PRIVATE TYPES
    typedef shared_ptr<ELEMENT_TYPE> SelfType;
        // 'SelfType' is an alias to this 'class', for compilers that do not
        // recognize plain 'shared_ptr'.

    typedef typename BloombergLP::bsls::UnspecifiedBool<shared_ptr>::BoolType
                                                                      BoolType;

    // FRIENDS
    template <class COMPATIBLE_TYPE>
    friend class shared_ptr;

    friend struct BloombergLP::bslstl::SharedPtr_ImpUtil;

  private:
    // PRIVATE CLASS METHODS
    template <class INPLACE_REP>
    static BloombergLP::bslma::SharedPtrRep *makeInternalRep(
                                        ELEMENT_TYPE                     *,
                                        INPLACE_REP                      *,
                                        BloombergLP::bslma::SharedPtrRep *rep);
        // Return the specified 'rep'.

    template <class COMPATIBLE_TYPE, class ALLOCATOR>
    static BloombergLP::bslma::SharedPtrRep *makeInternalRep(
                                     COMPATIBLE_TYPE               *ptr,
                                     ALLOCATOR                     *,
                                     BloombergLP::bslma::Allocator *allocator);
        // Return the address of a new out-of-place representation for a shared
        // pointer that manages the specified 'ptr' and uses the specified
        // 'allocator' to destroy the object pointed to by 'ptr'.  Use
        // 'allocator' to supply memory.

    template <class COMPATIBLE_TYPE, class DELETER>
    static BloombergLP::bslma::SharedPtrRep *makeInternalRep(
                                                      COMPATIBLE_TYPE *ptr,
                                                      DELETER         *deleter,
                                                      ...);
        // Return the address of a new out-of-place representation for a shared
        // pointer that manages the specified 'ptr' and uses the specified
        // 'deleter' to destroy the object pointed to by 'ptr'.  Use the
        // currently installed default allocator to supply memory.

  public:
    // CREATORS
    BSLS_KEYWORD_CONSTEXPR
    shared_ptr() BSLS_KEYWORD_NOEXCEPT;
        // Create an empty shared pointer, i.e., a shared pointer with no
        // representation that does not refer to any object and has no
        // deleter.

    BSLS_KEYWORD_CONSTEXPR
    shared_ptr(bsl::nullptr_t) BSLS_KEYWORD_NOEXCEPT;               // IMPLICIT
        // Create an empty shared pointer, i.e., a shared pointer with no
        // representation that does not refer to any object and has no
        // deleter.

    template <class CONVERTIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE>
    explicit shared_ptr(CONVERTIBLE_TYPE *ptr);
        // Create a shared pointer that manages a modifiable object of
        // (template parameter) type 'CONVERTIBLE_TYPE' and refers to the
        // specified '(ELEMENT_TYPE *)ptr'.  The currently installed default
        // allocator is used to allocate and deallocate the internal
        // representation of the shared pointer.  When all references have been
        // released, the object pointed to by the managed pointer will be
        // destroyed by a call to 'delete ptr'.  If 'CONVERTIBLE_TYPE *' is not
        // implicitly convertible to 'ELEMENT_TYPE *', then a compiler
        // diagnostic will be emitted indicating the error.  If 'ptr' is 0,
        // then this shared pointer will still allocate an internal
        // representation to share ownership of that empty state, which will be
        // reclaimed when the last reference is destroyed.  If an exception is
        // thrown allocating storage for the representation, then 'delete ptr'
        // will be called.  Note that if 'ptr' is a null-pointer constant, the
        // compiler will actually select the 'shared_ptr(bsl::nullptr_t)'
        // constructor, resulting in an empty shared pointer.

    template <class CONVERTIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE>
    shared_ptr(CONVERTIBLE_TYPE              *ptr,
               BloombergLP::bslma::Allocator *basicAllocator);
        // Create a shared pointer that manages a modifiable object of
        // (template parameter) type 'CONVERTIBLE_TYPE' and refers to the
        // specified 'ptr' cast to a pointer to the (template parameter) type
        // 'ELEMENT_TYPE'.  If the specified 'basicAllocator' is not 0, then
        // 'basicAllocator' is used to allocate and deallocate the internal
        // representation of the shared pointer and to destroy the shared
        // object when all references have been released; otherwise, the
        // currently installed default allocator is used.  If
        // 'CONVERTIBLE_TYPE *' is not implicitly convertible to
        // 'ELEMENT_TYPE *', then a compiler diagnostic will be emitted
        // indicating the error.  If 'ptr' is 0, then this shared pointer will
        // still allocate an internal representation to share ownership of that
        // empty state, which will be reclaimed when the last reference is
        // destroyed.  Note that if 'ptr' is a null-pointer constant, the
        // compiler will actually select the
        // 'shared_ptr(bsl::nullptr_t, BloombergLP::bslma::Allocator *)'
        // constructor, resulting in an empty shared pointer.  Note that if
        // 'basicAllocator' is a pointer to a class derived from
        // 'bslma::Allocator', the compiler will actually select the following
        // (more general) constructor that has the same behavior:
        //..
        //  template <class CONVERTIBLE_TYPE, class DELETER>
        //  shared_ptr(CONVERTIBLE_TYPE *ptr, DELETER * deleter);
        //..

    shared_ptr(ELEMENT_TYPE *ptr, BloombergLP::bslma::SharedPtrRep *rep);
        // Create a shared pointer that takes ownership of the specified 'rep'
        // and refers to the modifiable object at the specified 'ptr' address.
        // The number of references to 'rep' is *NOT* incremented.  Note that
        // if 'rep' is a pointer to a class derived from
        // 'BloombergLP::bslma::SharedPtrRep', the compiler will actually
        // select the following (more general) constructor that has the same
        // behavior:
        //..
        //  template <class COMPATIBLE_TYPE, class DELETER>
        //  shared_ptr(COMPATIBLE_TYPE *ptr, DELETER * deleter);
        //..

    shared_ptr(ELEMENT_TYPE                     *ptr,
               BloombergLP::bslma::SharedPtrRep *rep,
               BloombergLP::bslstl::SharedPtr_RepFromExistingSharedPtr);
        // Create a shared pointer that takes ownership of the specified 'rep'
        // and refers to the modifiable object at the specified 'ptr' address.
        // The number of references to 'rep' is *NOT* incremented.  The
        // behavior is undefined unless 'rep' was previously obtained from an
        // existing 'shared_ptr', 'rep->disposeObject' has not been called, and
        // 'rep->numReferences() > 0'.  Note that this constructor is intended
        // for use by 'weak_ptr::lock', and it would be surprising to find
        // another client.  This solves an obscure problem that arises from
        // unusual use of classes derived from 'enable_shared_from_this'.
        // Further note that the caller is responsible for incrementing the
        // 'numReferences' count prior to calling this constructor, in order to
        // maintain a consistent reference count when this 'shared_ptr' object
        // releases the shared object from its management.

    template <class CONVERTIBLE_TYPE,
              class DELETER
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
              BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(DELETER *, CONVERTIBLE_TYPE)>
    shared_ptr(CONVERTIBLE_TYPE *ptr, DELETER *deleter);
        // Create a shared pointer that manages a modifiable object of
        // (template parameter) type 'CONVERTIBLE_TYPE', refers to the
        // specified 'ptr' cast to a pointer to the (template parameter) type
        // 'ELEMENT_TYPE', and uses the specified 'deleter' to delete the
        // shared object when all references have been released.  Use the
        // currently installed default allocator to allocate and deallocate the
        // internal representation of the shared pointer, unless 'DELETER' is a
        // class derived from either 'bslma::Allocator' or
        // 'bslma::SharedPtrRep'; if 'DELETER' is a class derived from
        // 'bslma::allocator', create a shared pointer as if calling the
        // constructor:
        //..
        //  template <class CONVERTIBLE_TYPE>
        //  shared_ptr(CONVERTIBLE_TYPE               *ptr,
        //             BloombergLP::bslma::Allocator *basicAllocator);
        //..
        // If 'DELETER' is a class derived from 'bslma::SharedPtrRep', create a
        // shared pointer as if calling the constructor:
        //..
        //  shared_ptr(ELEMENT_TYPE                     *ptr,
        //             BloombergLP::bslma::SharedPtrRep *rep);
        //..
        // If 'DELETER' does not derive from either 'bslma::Allocator' or
        // 'BloombergLP::bslma::SharedPtrRep', then 'deleter' shall be a
        // pointer to a factory object that exposes a member function that can
        // be invoked as 'deleteObject(ptr)' that will be called to destroy the
        // object at the 'ptr' address (i.e., 'deleter->deleteObject(ptr)' will
        // be called to delete the shared object).  (See the "Deleters" section
        // in the component-level documentation.)  If 'CONVERTIBLE_TYPE *' is
        // not implicitly convertible to 'ELEMENT_TYPE *', then a compiler
        // diagnostic will be emitted indicating the error.  If 'ptr' is 0,
        // then the null pointer will be reference counted, and the deleter
        // will be called when the last reference is destroyed.  If an
        // exception is thrown when allocating storage for the internal
        // representation, then 'deleter(ptr)' will be called.  Note that this
        // method is a BDE extension and not part of the C++ standard
        // interface.

    template <class CONVERTIBLE_TYPE,
              class DELETER
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
              BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
    shared_ptr(CONVERTIBLE_TYPE              *ptr,
               DELETER                        deleter,
               BloombergLP::bslma::Allocator *basicAllocator = 0);
        // Create a shared pointer that manages a modifiable object of
        // (template parameter) type 'CONVERTIBLE_TYPE', refers to the
        // specified '(ELEMENT_TYPE *)ptr', and uses the specified 'deleter' to
        // delete the shared object when all references have been released.
        // Optionally specify a 'basicAllocator' to allocate and deallocate the
        // internal representation of the shared pointer (including a copy of
        // 'deleter').  If 'basicAllocator' is 0, the currently installed
        // default allocator is used.  'DELETER' shall be either a function
        // pointer or a "factory" deleter that may be invoked to destroy the
        // object referred to by a single argument of type 'CONVERTIBLE_TYPE *'
        // (i.e., 'deleter(ptr)' or 'deleter->deleteObject(ptr)' will be called
        // to destroy the shared object).  (See the "Deleters" section in the
        // component-level documentation.)  If 'CONVERTIBLE_TYPE *' is not
        // implicitly convertible to 'ELEMENT_TYPE *', then this constructor
        // will not be selected by overload resolution.  If 'ptr' is 0, then
        // the null pointer will be reference counted, and 'deleter(ptr)' will
        // be called when the last reference is destroyed.  If an exception is
        // thrown when allocating storage for the internal representation, then
        // 'deleter(ptr)' will be called.  The behavior is undefined unless the
        // constructor making a copy of 'deleter' does not throw an exception.

    template <class CONVERTIBLE_TYPE,
              class DELETER,
              class ALLOCATOR
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
              BSLSTL_SHAREDPTR_DECLARE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
    shared_ptr(CONVERTIBLE_TYPE               *ptr,
               DELETER                         deleter,
               ALLOCATOR                       basicAllocator,
               typename ALLOCATOR::value_type * = 0);
        // Create a shared pointer that manages a modifiable object of
        // (template parameter) type 'CONVERTIBLE_TYPE', refers to the
        // specified 'ptr' cast to a pointer to the (template parameter) type
        // 'ELEMENT_TYPE', and uses the specified 'deleter' to delete the
        // shared object when all references have been released.  Use the
        // specified 'basicAllocator' to allocate and deallocate the internal
        // representation of the shared pointer (including a copy of the
        // 'deleter').  The (template parameter) type 'DELETER' shall be either
        // a function pointer or a function-like deleter that may be invoked to
        // destroy the object referred to by a single argument of type
        // 'CONVERTIBLE_TYPE *' (i.e., 'deleter(ptr)' will be called to destroy
        // the shared object).  (See the "Deleters" section in the component-
        // level documentation.)  The (template parameter) type 'ALLOCATOR'
        // shall satisfy the Allocator requirements of the C++ standard (C++11
        // 17.6.3.5, [allocator.requirements]).  If 'CONVERTIBLE_TYPE *' is not
        // implicitly convertible to 'ELEMENT_TYPE *', then a compiler
        // diagnostic will be emitted indicating the error.  If 'ptr' is 0,
        // then the null pointer will be reference counted, and 'deleter(ptr)'
        // will be called when the last reference is destroyed.  If an
        // exception is thrown when allocating storage for the internal
        // representation, then 'deleter(ptr)' will be called.  The behavior is
        // undefined unless the constructor making a copy of 'deleter' does not
        // throw an exception.  Note that the final dummy parameter is a simple
        // SFINAE check that the (template parameter) 'ALLOCATOR' type probably
        // satisfies the standard allocator requirements; in particular, it
        // will not match pointer types, so any pointers to 'bslma::Allocator'
        // derived classes will dispatch to the constructor above this, and not
        // be greedily matched to a generic type parameter.

    shared_ptr(nullptr_t                      nullPointerLiteral,
               BloombergLP::bslma::Allocator *basicAllocator);
        // Create an empty shared pointer.  The specified 'nullPointerLiteral'
        // and 'basicAllocator' are not used.  Note that use of this
        // constructor is equivalent to calling the default constructor.

    template <class DELETER
              BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(DELETER)>
    shared_ptr(nullptr_t                      nullPointerLiteral,
               DELETER                        deleter,
               BloombergLP::bslma::Allocator *basicAllocator = 0);
        // Create a shared pointer that reference-counts the null pointer, and
        // calls the specified 'deleter' with a null pointer (i.e., invokes
        // 'deleter((ELEMENT_TYPE *)0)') when the last shared reference is
        // destroyed.  The specified 'nullPointerLiteral' is not used.
        // Optionally specify a 'basicAllocator' to allocate and deallocate the
        // internal representation of the shared pointer (including a copy of
        // 'deleter').  If 'basicAllocator' is 0, the currently installed
        // default allocator is used.  If an exception is thrown when
        // allocating storage for the internal representation, then
        // 'deleter((ELEMENT_TYPE *)0)' will be called.  The behavior is
        // undefined unless 'deleter' can be called with a null pointer, and
        // unless the constructor making a copy of 'deleter' does not throw an
        // exception.

    template <class DELETER, class ALLOCATOR
              BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER(DELETER)>
    shared_ptr(nullptr_t                       nullPointerLiteral,
               DELETER                         deleter,
               ALLOCATOR                       basicAllocator,
               typename ALLOCATOR::value_type * = 0);
        // Create a shared pointer that reference-counts the null pointer,
        // calls the specified 'deleter' with a null pointer (i.e., invokes
        // 'deleter((ELEMENT_TYPE *)0)') when the last shared reference is
        // destroyed, and uses the specified 'basicAllocator' to allocate and
        // deallocate the internal representation of the shared pointer
        // (including a copy of the 'deleter').  The (template parameter) type
        // 'DELETER' shall be either a function pointer or a function-like
        // deleter (See the "Deleters" section in the component- level
        // documentation).  The (template parameter) type 'ALLOCATOR' shall
        // satisfy the Allocator requirements of the C++ standard (C++11
        // 17.6.3.5, [allocator.requirements]).  The specified
        // 'nullPointerLiteral' is not used.  If an exception is thrown when
        // allocating storage for the internal representation, then
        // 'deleter((ELEMENT_TYPE *)0)' will be called.  The behavior is
        // undefined unless 'deleter' can be called with a null pointer, and
        // unless the constructor making a copy of 'deleter' does not throw an
        // exception.  Note that the final dummy parameter is a simple SFINAE
        // check that the 'ALLOCATOR' type probably satisfies the standard
        // allocator requirements; in particular, it will not match pointer
        // types, so any pointers to 'bslma::Allocator' derived classes will
        // dispatch to the constructor above this, and not be greedily matched
        // to a generic type parameter.

    template <class CONVERTIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE>
    shared_ptr(
         BloombergLP::bslma::ManagedPtr<CONVERTIBLE_TYPE>  managedPtr,
         BloombergLP::bslma::Allocator                    *basicAllocator = 0);
                                                                    // IMPLICIT
        // Create a shared pointer that takes over the management of the
        // modifiable object (if any) previously managed by the specified
        // 'managedPtr' to the (template parameter) type 'CONVERTIBLE_TYPE',
        // and that refers to '(ELEMENT_TYPE *)managedPtr.ptr()'.  The deleter
        // used in the 'managedPtr' will be used to destroy the shared object
        // when all references have been released.  Optionally specify a
        // 'basicAllocator' used to allocate and deallocate the internal
        // representation of the shared pointer.  If 'basicAllocator' is 0, the
        // currently installed default allocator is used.  If
        // 'CONVERTIBLE_TYPE *' is not implicitly convertible to
        // 'ELEMENT_TYPE *', then a compiler diagnostic will be emitted
        // indicating the error.  Note that if 'managedPtr' is empty, then an
        // empty shared pointer is created and 'basicAllocator' is ignored.
        // Also note that if 'managedPtr' owns a reference to another shared
        // object (due to a previous call to 'shared_ptr<T>::managedPtr') then
        // no memory will be allocated, and this 'shared_ptr' will adopt the
        // 'ManagedPtr's ownership of that shared object.

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
    template <class CONVERTIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE>
    explicit shared_ptr(std::auto_ptr<CONVERTIBLE_TYPE>&  autoPtr,
                        BloombergLP::bslma::Allocator    *basicAllocator = 0);
        // Create a shared pointer that takes over the management of the
        // modifiable object previously managed by the specified 'autoPtr' to
        // the (template parameter) type 'CONVERTIBLE_TYPE', and that refers to
        // '(ELEMENT_TYPE *)autoPtr.get()'.  'delete(autoPtr.release())' will
        // be called to destroy the shared object when all references have been
        // released.  Optionally specify a 'basicAllocator' used to allocate
        // and deallocate the internal representation of the shared pointer.
        // If 'basicAllocator' is 0, the currently installed default allocator
        // is used.  If 'CONVERTIBLE_TYPE *' is not implicitly convertible to
        // 'ELEMENT_TYPE *', then a compiler diagnostic will be emitted
        // indicating the error.

    explicit shared_ptr(std::auto_ptr_ref<ELEMENT_TYPE>  autoRef,
                        BloombergLP::bslma::Allocator   *basicAllocator = 0);
        // Create a shared pointer that takes over the management of the
        // modifiable object of (template parameter) type 'COMPATIBLE_TYPE'
        // previously managed by the auto pointer object that the specified
        // 'autoRef' refers to; this shared pointer refers to the same object
        // that it manages, and 'delete(get())' will be called to destroy the
        // shared object when all references have been released.  Optionally
        // specify a 'basicAllocator' used to allocate and deallocate the
        // internal representation of the shared pointer.  If 'basicAllocator'
        // is 0, the currently installed default allocator is used.  This
        // function does not exist unless 'COMPATIBLE_TYPE *' is convertible to
        // 'ELEMENT_TYPE *'.
#endif

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
# if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
    template <class COMPATIBLE_TYPE,
              class UNIQUE_DELETER,
              typename enable_if<is_convertible<
                      typename std::unique_ptr<COMPATIBLE_TYPE,
                                               UNIQUE_DELETER>::pointer,
                      ELEMENT_TYPE *>::value>::type * = nullptr>
     shared_ptr(std::unique_ptr<COMPATIBLE_TYPE,
                                UNIQUE_DELETER>&&  adoptee,
                BloombergLP::bslma::Allocator     *basicAllocator = 0);
                                                                    // IMPLICIT
        // Create a shared pointer that takes over the management of the
        // modifiable object previously managed by the specified 'adoptee' to
        // the (template parameter) type 'COMPATIBLE_TYPE', and that refers to
        // '(ELEMENT_TYPE *)autoPtr.get()'.  'delete(autoPtr.release())' will
        // be called to destroy the shared object when all references have been
        // released.  Optionally specify a 'basicAllocator' used to allocate
        // and deallocate the internal representation of the shared pointer.
        // If 'basicAllocator' is 0, the currently installed default allocator
        // is used.  This function does not exist unless
        // 'unique_ptr<COMPATIBLE_TYPE, DELETER>::pointer' is convertible to
        // 'ELEMENT_TYPE *'.  Note that this function creates a 'shared_ptr'
        // with an unspecified deleter type that has satisfies this contract,
        // which might not be the deleter of 'rhs', which is specified by the
        // C++ standard.
# else
    template <class COMPATIBLE_TYPE, class UNIQUE_DELETER>
    shared_ptr(std::unique_ptr<COMPATIBLE_TYPE,
                                UNIQUE_DELETER>&&  adoptee,
               BloombergLP::bslma::Allocator      *basicAllocator = 0,
               typename enable_if<is_convertible<
                      typename std::unique_ptr<COMPATIBLE_TYPE,
                                               UNIQUE_DELETER>::pointer,
                      ELEMENT_TYPE *>::value,
                      BloombergLP::bslstl::SharedPtr_ImpUtil>::type =
                                      BloombergLP::bslstl::SharedPtr_ImpUtil())
                                                                    // IMPLICIT
        // Create a shared pointer that takes over the management of the
        // modifiable object previously managed by the specified 'adoptee' to
        // the (template parameter) type 'COMPATIBLE_TYPE', and that refers to
        // '(ELEMENT_TYPE *)autoPtr.get()'.  'delete(autoPtr.release())' will
        // be called to destroy the shared object when all references have been
        // released.  Optionally specify a 'basicAllocator' used to allocate
        // and deallocate the internal representation of the shared pointer.
        // If 'basicAllocator' is 0, the currently installed default allocator
        // is used.  This function does not exist unless
        // 'unique_ptr<COMPATIBLE_TYPE, DELETER>::pointer' is convertible to
        // 'ELEMENT_TYPE *'.  Note that this function creates a 'shared_ptr'
        // with an unspecified deleter type that has satisfies this contract,
        // which might not be the deleter of 'rhs', which is specified by the
        // C++ standard.
    : d_ptr_p(adoptee.get())
    , d_rep_p(0)
    {
        // This constructor template must be defined inline inside the class
        // definition, as Microsoft Visual C++ does not recognize the
        // definition as matching this signature when placed out-of-line.

        typedef BloombergLP::bslma::SharedPtrInplaceRep<
                        std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER> > Rep;

        if (d_ptr_p) {
            basicAllocator =
                        BloombergLP::bslma::Default::allocator(basicAllocator);
            Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                            BloombergLP::bslmf::MovableRefUtil::move(adoptee));
            d_rep_p = rep;
            BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
                                                                       d_ptr_p,
                                                                       this);
        }
    }
# endif // BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS
#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR

    template <class ANY_TYPE>
    shared_ptr(const shared_ptr<ANY_TYPE>&  source,
               ELEMENT_TYPE                *object) BSLS_KEYWORD_NOEXCEPT;
        // Create a shared pointer that manages the same modifiable object (if
        // any) as the specified 'source' shared pointer to the (template
        // parameter) type 'ANY_TYPE', and that refers to the modifiable object
        // at the specified 'object' address.  The resulting shared pointer is
        // known as an "alias" of 'source'.  Note that typically the objects
        // referred to by 'source' and 'object' have identical lifetimes (e.g.,
        // one might be a part of the other), so that the deleter for 'source'
        // will destroy them both, but they do not necessarily have the same
        // type.  Also note that if 'source' is empty, then an empty shared
        // pointer is created, even if 'object' is not null (in which case this
        // empty shared pointer will refer to the same object as 'object').
        // Also note that if 'object' is null and 'source' is not empty, then a
        // reference-counted null pointer alias will be created.

    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    shared_ptr(const shared_ptr<COMPATIBLE_TYPE>& other) BSLS_KEYWORD_NOEXCEPT;
        // Create a shared pointer that manages the same modifiable object (if
        // any) as the specified 'other' shared pointer to the (template
        // parameter) type 'COMPATIBLE_TYPE', uses the same deleter as 'other'
        // to destroy the shared object, and refers to
        // '(ELEMENT_TYPE*)other.get()'.  If 'COMPATIBLE_TYPE *' is not
        // implicitly convertible to 'ELEMENT_TYPE *', then a compiler
        // diagnostic will be emitted indicating the error.  Note that if
        // 'other' is empty, then an empty shared pointer is created, which may
        // still point to an un-managed object if 'other' were constructed
        // through an aliasing constructor.

    shared_ptr(const shared_ptr& original) BSLS_KEYWORD_NOEXCEPT;
        // Create a shared pointer that refers to and manages the same object
        // (if any) as the specified 'original' shared pointer, and uses the
        // same deleter as 'original' to destroy the shared object.  Note that
        // if 'original' is empty, then an empty shared pointer is created,
        // which may still point to an un-managed object if 'original' were
        // constructed through an aliasing constructor.

    shared_ptr(BloombergLP::bslmf::MovableRef<shared_ptr> original)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Create a shared pointer that refers to and assumes management of the
        // same object (if any) as the specified 'original' shared pointer,
        // using the same deleter as 'original' to destroy the shared object,
        // and reset 'original' to an empty state, not pointing to any object.
        // Note that if 'original' is empty, then an empty shared pointer is
        // created, which may still point to an un-managed object if 'original'
        // were constructed through an aliasing constructor.

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    shared_ptr(shared_ptr<COMPATIBLE_TYPE>&& other) BSLS_KEYWORD_NOEXCEPT;
        // Create a shared pointer that refers to and assumes management of the
        // same object (if any) as the specified 'other' shared pointer to the
        // (template parameter) type 'COMPATIBLE_TYPE', using the same deleter
        // as 'other' to destroy the shared object, and refers to
        // '(ELEMENT_TYPE*)other.get()'.  If 'COMPATIBLE_TYPE *' is not
        // implicitly convertible to 'ELEMENT_TYPE *', then a compiler
        // diagnostic will be emitted indicating the error.  Note that if
        // 'other' is empty, then an empty shared pointer is created, which may
        // still point to an un-managed object if 'other' were constructed
        // through an aliasing constructor.
#else
    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    shared_ptr(
           BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > other)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Create a shared pointer that refers to and assumes management of the
        // same object (if any) as the specified 'other' shared pointer to the
        // (template parameter) type 'COMPATIBLE_TYPE', using the same deleter
        // as 'other' to destroy the shared object, and refers to
        // '(ELEMENT_TYPE*)other.get()'.  If 'COMPATIBLE_TYPE *' is not
        // implicitly convertible to 'ELEMENT_TYPE *', then a compiler
        // diagnostic will be emitted indicating the error.  Note that if
        // 'other' is empty, then an empty shared pointer is created, which may
        // still point to an un-managed object if 'other' were constructed
        // through an aliasing constructor.
#endif

    template<class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    explicit shared_ptr(const weak_ptr<COMPATIBLE_TYPE>& ptr);
        // Create a shared pointer that refers to and manages the same object
        // as the specified 'ptr' if 'ptr.expired()' is 'false'; otherwise,
        // create a shared pointer in the empty state.  Note that the
        // referenced and managed objects may be different if 'ptr' was created
        // from a 'shared_ptr' in an aliasing state.

#if !defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
    template<class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    explicit shared_ptr(
              BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > ptr);
        // Create a shared pointer that refers to and manages the same object
        // as the specified 'ptr' if  'ptr.expired()' is 'false'; otherwise,
        // create a shared pointer in the empty state.  Note that the
        // referenced and managed objects may be different if 'ptr' was created
        // from a 'shared_ptr' in an aliasing state.  Also note that this
        // overloaded constructor is necessary only for C++03 compilers that
        // rely on the BDE move-emulation type, 'bslmf::MovableRef'; a C++11
        // compiler will pass rvalues directly to the constructor taking a
        // 'const weak_ptr&', rendering this constructor redundant.
#endif

    ~shared_ptr();
        // Destroy this shared pointer.  If this shared pointer refers to a
        // (possibly shared) object, then release the reference to that object,
        // and destroy the shared object using its associated deleter if this
        // shared pointer is the last reference to that object.

    // MANIPULATORS
    shared_ptr& operator=(const shared_ptr& rhs) BSLS_KEYWORD_NOEXCEPT;
        // Make this shared pointer manage the same modifiable object as the
        // specified 'rhs' shared pointer to the (template parameter) type
        // 'COMPATIBLE_TYPE', use the same deleter as 'rhs', and refer to
        // '(ELEMENT_TYPE *)rhs.get()'; return a reference providing modifiable
        // access to this shared pointer.  Note that if 'rhs' is empty, then
        // this shared pointer will also be empty after the assignment.  Also
        // note that if '*this' is the same object as 'rhs', then this method
        // has no effect.

    shared_ptr& operator=(BloombergLP::bslmf::MovableRef<shared_ptr> rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Make this shared pointer manage the same modifiable object as the
        // specified 'rhs' shared pointer to the (template parameter) type
        // 'COMPATIBLE_TYPE', use the same deleter as 'rhs', and refer to
        // 'rhs.get()'; return a reference providing modifiable access to this
        // shared pointer.  Reset 'rhs' to an empty state, not pointing to any
        // object, unless '*this' is the same object as 'rhs'.  Note that if
        // 'rhs' is empty, then this shared pointer will also be empty after
        // the assignment.

    template <class COMPATIBLE_TYPE>
    typename enable_if<
        is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
        shared_ptr&>::type
    operator=(const shared_ptr<COMPATIBLE_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
        // Make this shared pointer refer to and manage the same modifiable
        // object as the specified 'rhs' shared pointer to the (template
        // parameter) type 'COMPATIBLE_TYPE', using the same deleter as 'rhs'
        // and referring to '(ELEMENT_TYPE *)rhs.get()', and return a reference
        // to this modifiable shared pointer.  If this shared pointer is
        // already managing a (possibly shared) object, then release the shared
        // reference to that object, and destroy it using its associated
        // deleter if this shared pointer held the last shared reference to
        // that object.  Note that if 'rhs' is empty, then this shared pointer
        // will also be empty after the assignment.

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
    template <class COMPATIBLE_TYPE>
    typename
            enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
                      shared_ptr&>::type
    operator=(shared_ptr<COMPATIBLE_TYPE>&& rhs) BSLS_KEYWORD_NOEXCEPT;
        // Make this shared pointer refer to and manage the same modifiable
        // object as the specified 'rhs' shared pointer to the (template
        // parameter) type 'COMPATIBLE_TYPE', using the same deleter as 'rhs'
        // and referring to '(ELEMENT_TYPE *)rhs.get()', and return a reference
        // to this modifiable shared pointer.  If this shared pointer is
        // already managing a (possibly shared) object, then release the shared
        // reference to that object, and destroy it using its associated
        // deleter if this shared pointer held the last shared reference to
        // that object.  Reset 'rhs' to an empty state, not pointing to any
        // object, unless '*this' is the same object as 'rhs'.  This function
        // does not exist unless a pointer to (template parameter)
        // 'COMPATIBLE_TYPE' is convertible to a pointer to the (template
        // parameter) 'ELEMENT_TYPE' of this 'shared_ptr'.  Note that if 'rhs'
        // is empty, then this shared pointer will also be empty after the
        // assignment.
#else
    template <class COMPATIBLE_TYPE>
    typename
            enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
                      shared_ptr&>::type
    operator=(BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Make this shared pointer refer to and manage the same modifiable
        // object as the specified 'rhs' shared pointer to the (template
        // parameter) type 'COMPATIBLE_TYPE', using the same deleter as 'rhs'
        // and referring to '(ELEMENT_TYPE *)rhs.get()', and return a reference
        // to this modifiable shared pointer.  If this shared pointer is
        // already managing a (possibly shared) object, then release the shared
        // reference to that object, and destroy it using its associated
        // deleter if this shared pointer held the last shared reference to
        // that object.  Reset 'rhs' to an empty state, not pointing to any
        // object, unless '*this' is the same object as 'rhs'.  This function
        // does not exist unless a pointer to (template parameter)
        // 'COMPATIBLE_TYPE' is convertible to a pointer to the (template
        // parameter) 'ELEMENT_TYPE' of this 'shared_ptr'.  Note that if 'rhs'
        // is empty, then this shared pointer will also be empty after the
        // assignment.
#endif

    template <class COMPATIBLE_TYPE>
    typename enable_if<
        is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
        shared_ptr&>::type
    operator=(BloombergLP::bslma::ManagedPtr<COMPATIBLE_TYPE> rhs);
        // Transfer, to this shared pointer, ownership of the modifiable object
        // managed by the specified 'rhs' managed pointer to the (template
        // parameter) type 'COMPATIBLE_TYPE', and make this shared pointer
        // refer to '(ELEMENT_TYPE *)rhs.ptr()'.  The deleter used in the 'rhs'
        // will be used to destroy the shared object when all references have
        // been released.  The *default* *allocator* is used to allocate a
        // 'SharedPtrRep', if needed (users must use the copy-constructor and
        // swap instead of using this operator to supply an alternative
        // allocator).  If this shared pointer is already managing a (possibly
        // shared) object, then release the reference to that shared object,
        // and destroy it using its associated deleter if this shared pointer
        // held the last shared reference to that object.  Note that if 'rhs'
        // is empty, then this shared pointer will be empty after the
        // assignment.  Also note that if 'rhs' owns a reference to another
        // shared object (due to a previous call to
        // 'shared_ptr<T>::managedPtr') then this 'shared_ptr' will adopt the
        // 'ManagedPtr's ownership of that shared object.

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
    template <class COMPATIBLE_TYPE>
    typename enable_if<
        is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
        shared_ptr&>::type
    operator=(std::auto_ptr<COMPATIBLE_TYPE> rhs);
        // Transfer, to this shared pointer, ownership of the modifiable object
        // managed by the specified 'rhs' auto pointer to the (template
        // parameter) type 'COMPATIBLE_TYPE', and make this shared pointer
        // refer to '(ELEMENT_TYPE *)rhs.get()'.  'delete(autoPtr.release())'
        // will be called to destroy the shared object when all references have
        // been released.  If this shared pointer is already managing a
        // (possibly shared) object, then release the reference to that shared
        // object, and destroy it using its associated deleter if this shared
        // pointer held the last shared reference to that object.  Note that if
        // 'rhs' is empty, then this shared pointer will be empty after the
        // assignment.
#endif

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
    template <class COMPATIBLE_TYPE, class UNIQUE_DELETER>
    typename enable_if<
        is_convertible<
            typename std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>::pointer,
                                     ELEMENT_TYPE *>::value,
            shared_ptr&>::type
    operator=(std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>&& rhs);
        // Transfer, to this shared pointer, ownership of the object managed by
        // the specified 'rhs' unique pointer to the (template parameter) type
        // 'COMPATIBLE_TYPE', and make this shared pointer refer to
        // '(ELEMENT_TYPE *)rhs.get()'.  The deleter of 'rhs' will be called to
        // destroy the shared object when all references have been released.
        // If this shared pointer is already managing a (possibly shared)
        // object, then release the reference to that shared object, and
        // destroy it using its associated deleter if this shared pointer held
        // the last shared reference to that object.  This function does not
        // exist unless 'unique_ptr<COMPATIBLE_TYPE, DELETER>::pointer' is
        // convertible to 'ELEMENT_TYPE *'.  Note that if 'rhs' is empty, then
        // this shared pointer will be empty after the assignment.  Also note
        // that this function creates a 'shared_ptr' with an unspecified
        // deleter type that satisfies this contract; the C++11 standard
        // specifies the exact deleter that should be in use after assignment,
        // so this implementation may be non-conforming.
#endif

    void reset() BSLS_KEYWORD_NOEXCEPT;
        // Reset this shared pointer to the empty state.  If this shared
        // pointer is managing a (possibly shared) object, then release the
        // reference to the shared object, calling the associated deleter to
        // destroy the shared object if this shared pointer is the last shared
        // reference.

    template <class COMPATIBLE_TYPE>
    typename
      enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
    reset(COMPATIBLE_TYPE *ptr);
        // Modify this shared pointer to manage the modifiable object of the
        // (template parameter) type 'COMPATIBLE_TYPE' at the specified 'ptr'
        // address and to refer to '(ELEMENT_TYPE *)ptr'.  If this shared
        // pointer is already managing a (possibly shared) object, then, unless
        // an exception is thrown allocating memory to manage 'ptr', release
        // the reference to the shared object, calling the associated deleter
        // to destroy the shared object if this shared pointer is the last
        // reference.  The currently installed default allocator is used to
        // allocate the internal representation of this shared pointer, and the
        // shared object will be destroyed by a call to 'delete ptr' when all
        // references have been released.  If an exception is thrown allocating
        // the internal representation, then 'delete ptr' is called and this
        // shared pointer retains ownership of its original object.  If
        // 'COMPATIBLE_TYPE*' is not implicitly convertible to 'ELEMENT_TYPE*',
        // then a compiler diagnostic will be emitted indicating the error.
        // Note that if 'ptr' is 0, then this shared pointer will still
        // allocate an internal representation to share ownership of that empty
        // state, which will be reclaimed when the last reference is destroyed.

    template <class COMPATIBLE_TYPE, class DELETER>
    typename
      enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
    reset(COMPATIBLE_TYPE *ptr, DELETER deleter);
        // Modify this shared pointer to manage the modifiable object of the
        // (template parameter) type 'COMPATIBLE_TYPE' at the specified 'ptr'
        // address, refer to '(ELEMENT_TYPE *)ptr', and use the specified
        // 'deleter' to delete the shared object when all references have been
        // released.  If this shared pointer is already managing a (possibly
        // shared) object, then unless an exception is thrown allocating memory
        // to manage 'ptr', release the reference to the shared object, calling
        // the associated deleter to destroy the shared object if this shared
        // pointer is the last reference.  If 'DELETER' is an object type, then
        // 'deleter' is assumed to be a function-like deleter that may be
        // invoked to destroy the object referred to by a single argument of
        // type 'COMPATIBLE_TYPE *' (i.e., 'deleter(ptr)' will be called to
        // destroy the shared object).  If 'DELETER' is a pointer type that is
        // not a function pointer, then 'deleter' shall be a pointer to a
        // factory object that exposes a member function that can be invoked as
        // 'deleteObject(ptr)' that will be called to destroy the object at the
        // 'ptr' address (i.e., 'deleter->deleteObject(ptr)' will be called to
        // delete the shared object).  (See the "Deleters" section in the
        // component-level documentation.)  If 'DELETER' is also a pointer to
        // 'bslma::Allocator' or to a class derived from 'bslma::Allocator',
        // then that allocator will also be used to allocate and destroy the
        // internal representation of this shared pointer when all references
        // have been released; otherwise, the currently installed default
        // allocator is used to allocate and destroy the internal
        // representation of this shared pointer when all references have been
        // released.  If an exception is thrown allocating the internal
        // representation, then 'deleter(ptr)' is called (or
        // 'deleter->deleteObject(ptr)' for factory-type deleters) and this
        // shared pointer retains ownership of its original object.  If
        // 'COMPATIBLE_TYPE*' is not implicitly convertible to 'ELEMENT_TYPE*',
        // then a compiler diagnostic will be emitted indicating the error.
        // Note that, for factory deleters, 'deleter' must remain valid until
        // all references to 'ptr' have been released.  If 'ptr' is 0, then an
        // internal representation will still be allocated, and this shared
        // pointer will share ownership of a copy of 'deleter'.  Further note
        // that this function is logically equivalent to:
        //..
        //  *this = shared_ptr<ELEMENT_TYPE>(ptr, deleter);
        //..


    template <class COMPATIBLE_TYPE, class DELETER, class ALLOCATOR>
    typename
      enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
    reset(COMPATIBLE_TYPE *ptr,
          DELETER          deleter,
          ALLOCATOR        basicAllocator);
        // Modify this shared pointer to manage the modifiable object of the
        // (template parameter) type 'COMPATIBLE_TYPE' at the specified 'ptr'
        // address, refer to '(ELEMENT_TYPE *)ptr' and use the specified
        // 'deleter' to delete the shared object when all references have been
        // released.  Use the specified 'basicAllocator' to allocate and
        // deallocate the internal representation of the shared pointer.  If
        // this shared pointer is already managing a (possibly shared) object,
        // then, unless an exception is thrown allocating memory to manage
        // 'ptr', release the shared reference to that shared object, and
        // destroy it using its associated deleter if this shared pointer held
        // the last shared reference to that object.  If 'DELETER' is a
        // reference type, then 'deleter' is assumed to be a function-like
        // deleter that may be invoked to destroy the object referred to by a
        // single argument of type 'COMPATIBLE_TYPE *' (i.e., 'deleter(ptr)'
        // will be called to destroy the shared object).  If 'DELETER' is a
        // pointer type, then 'deleter' is assumed to be a pointer to a factory
        // object that exposes a member function that can be invoked as
        // 'deleteObject(ptr)' that will be called to destroy the object at the
        // 'ptr' address (i.e., 'deleter->deleteObject(ptr)' will be called to
        // delete the shared object).  (See the "Deleters" section in the
        // component-level documentation.)  If an exception is thrown
        // allocating the internal representation, then 'deleter(ptr)' is
        // called (or 'deleter->deleteObject(ptr)' for factory-type deleters)
        // and this shared pointer retains ownership of its original object.
        // The behavior is undefined unless 'deleter(ptr)' is a well-defined
        // expression (or 'deleter->deleteObject(ptr)' for factory-type
        // deleters), and unless the copy constructor for 'deleter' does not
        // throw an exception.  If 'COMPATIBLE_TYPE *' is not implicitly
        // convertible to 'ELEMENT_TYPE *', then a compiler diagnostic will be
        // emitted indicating the error.  Note that, for factory deleters, the
        // 'deleter' must remain valid until all references to 'ptr' have been
        // released.  Also note that if 'ptr' is 0, then an internal
        // representation will still be allocated, and this shared pointer will
        // share ownership of a copy of 'deleter'.  Further note that this
        // function is logically equivalent to:
        //..
        //  *this = shared_ptr<ELEMENT_TYPE>(ptr, deleter, basicAllocator);
        //..

    template <class ANY_TYPE>
    void reset(const shared_ptr<ANY_TYPE>& source, ELEMENT_TYPE *ptr);
        // Modify this shared pointer to manage the same modifiable object (if
        // any) as the specified 'source' shared pointer to the (template
        // parameter) type 'ANY_TYPE', and refer to the modifiable object at
        // the specified 'ptr' address (i.e., make this shared pointer an
        // "alias" of 'source').  If this shared pointer is already managing a
        // (possibly shared) object, then release the reference to the shared
        // object, calling the associated deleter to destroy the shared object
        // if this shared pointer is the last reference.  Note that typically
        // the objects referred to by 'source' and 'ptr' have identical
        // lifetimes (e.g., one might be a part of the other), so that the
        // deleter for 'source' will destroy them both, but do not necessarily
        // have the same type.  Also note that if 'source' is empty, then this
        // shared pointer will be reset to an empty state, even if 'ptr' is not
        // null (in which case this empty shared pointer will refer to the same
        // object as 'ptr').  Also note that if 'ptr' is null and 'source' is
        // not empty, then this shared pointer will be reset to a
        // (reference-counted) null pointer alias.  Further note that the
        // behavior of this method is the same as 'loadAlias(source, ptr)'.
        // Finally note that this is a non-standard BDE extension to the C++
        // Standard 'shared_ptr' interface, which does not provide an alias
        // overload for the 'reset' function.

    void swap(shared_ptr& other) BSLS_KEYWORD_NOEXCEPT;
        // Efficiently exchange the states of this shared pointer and the
        // specified 'other' shared pointer such that each will refer to the
        // object formerly referred to by the other and each will manage the
        // object formerly managed by the other.

    // ADDITIONAL BSL MANIPULATORS
    void createInplace();
        // Create "in-place" in a large enough contiguous memory region both an
        // internal representation for this shared pointer and a
        // default-constructed object of 'ELEMENT_TYPE', and make this shared
        // pointer refer to the newly-created 'ELEMENT_TYPE' object.  The
        // currently installed default allocator is used to supply memory.  If
        // an exception is thrown during allocation or construction of the
        // 'ELEMENT_TYPE' object, this shared pointer will be unchanged.
        // Otherwise, if this shared pointer is already managing a (possibly
        // shared) object, then release the shared reference to that shared
        // object, and destroy it using its associated deleter if this shared
        // pointer held the last shared reference to that object.

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_sharedptr.h
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT 14
#endif
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#endif
#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 0
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 1
    template <class ARGS_01>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 2
    template <class ARGS_01,
              class ARGS_02>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 3
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 4
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 5
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 6
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 7
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 8
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 9
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 10
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 11
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10,
              class ARGS_11>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 12
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10,
              class ARGS_11,
              class ARGS_12>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 13
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10,
              class ARGS_11,
              class ARGS_12,
              class ARGS_13>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 14
    template <class ARGS_01,
              class ARGS_02,
              class ARGS_03,
              class ARGS_04,
              class ARGS_05,
              class ARGS_06,
              class ARGS_07,
              class ARGS_08,
              class ARGS_09,
              class ARGS_10,
              class ARGS_11,
              class ARGS_12,
              class ARGS_13,
              class ARGS_14>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_A >= 14

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class... ARGS>
    void createInplace(BloombergLP::bslma::Allocator *basicAllocator,
                       BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
// }}} END GENERATED CODE
#endif

    template <class ANY_TYPE>
    void loadAlias(const shared_ptr<ANY_TYPE>&  source,
                   ELEMENT_TYPE                *object);
        // [!DEPRECATED!] Use 'reset' instead.
        //
        // Modify this shared pointer to manage the same modifiable object (if
        // any) as the specified 'source' shared pointer to the (template
        // parameter) type 'ANY_TYPE', and refer to the modifiable object at
        // the specified 'object' address (i.e., make this shared pointer an
        // "alias" of 'source').  If this shared pointer is already managing a
        // (possibly shared) object, then release the shared reference to that
        // shared object, and destroy it using its associated deleter if this
        // shared pointer held the last shared reference to that object.  Note
        // that typically the objects referred to by 'source' and 'object' have
        // identical lifetimes (e.g., one might be a part of the other), so
        // that the deleter for 'source' will destroy them both, but they do
        // not necessarily have the same type.  Also note that if 'source' is
        // empty, then this shared pointer will be reset to an empty state,
        // even if 'object' is not null (in which case this empty shared
        // pointer will refer to the same object as 'object').  Also note that
        // if 'object' is null and 'source' is not empty, then this shared
        // pointer will be reset to a (reference-counted) null pointer alias.
        // Also note that this function is logically equivalent to:
        //..
        //  *this = shared_ptr<ELEMENT_TYPE>(source, object);
        //..
        // Further note that the behavior of this method is the same as
        // 'reset(source, object)'.

    pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *> release()
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return the pair consisting of the addresses of the modifiable
        // 'ELEMENT_TYPE' object referred to, and the representation shared by,
        // this shared pointer, and reset this shared pointer to the empty
        // state, referring to no object, with no effect on the representation.
        // The reference counter is not modified nor is the shared object
        // deleted; if the reference count of the representation is greater
        // than one, then it is not safe to release the representation (thereby
        // destroying the shared object), but it is always safe to create
        // another shared pointer with the representation using the constructor
        // with the signature
        // 'shared_ptr(ELEMENT_TYPE                     *ptr,
        //             BloombergLP::bslma::SharedPtrRep *rep)'.
        // Note that this function returns a pair of null pointers if this
        // shared pointer is empty.

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
    // DEPRECATED BDE LEGACY MANIPULATORS
    void clear() BSLS_KEYWORD_NOEXCEPT;
        // [!DEPRECATED!] Use 'reset' instead.
        //
        // Reset this shared pointer to the empty state.  If this shared
        // pointer is managing a (possibly shared) object, then release the
        // reference to the shared object, calling the associated deleter to
        // destroy the shared object if this shared pointer is the last
        // reference.  Note that the behavior of this method is the same as
        // 'reset()'.

    template <class COMPATIBLE_TYPE>
    void load(COMPATIBLE_TYPE *ptr);
        // [!DEPRECATED!] Use 'reset' instead.
        //
        // Modify this shared pointer to manage the modifiable object of the
        // (template parameter) type 'COMPATIBLE_TYPE' at the specified 'ptr'
        // address and to refer to '(ELEMENT_TYPE *)ptr'.  If this shared
        // pointer is already managing a (possibly shared) object, then, unless
        // an exception is thrown allocating memory to manage 'ptr', release
        // the reference to the shared object, calling the associated deleter
        // to destroy the shared object if this shared pointer is the last
        // reference.  The currently installed default allocator is used to
        // allocate the internal representation of this shared pointer, and the
        // shared object will be destroyed by a call to 'delete ptr' when all
        // references have been released.  If an exception is thrown allocating
        // the internal representation, then 'delete ptr' is called and this
        // shared pointer retains ownership of its original object.  If
        // 'COMPATIBLE_TYPE*' is not implicitly convertible to 'ELEMENT_TYPE*',
        // then a compiler diagnostic will be emitted indicating the error.
        // Note that if 'ptr' is 0, then this shared pointer will still
        // allocate an internal representation to share ownership of that empty
        // state, which will be reclaimed when the last reference is destroyed.
        // Also note also that the behavior of this method is the same as
        // 'reset(ptr)'.

    template <class COMPATIBLE_TYPE>
    void load(COMPATIBLE_TYPE               *ptr,
              BloombergLP::bslma::Allocator *basicAllocator);
        // [!DEPRECATED!] Use 'reset' instead.
        //
        // Modify this shared pointer to manage the modifiable object of the
        // (template parameter) type 'COMPATIBLE_TYPE' at the specified 'ptr'
        // address and to refer to '(ELEMENT_TYPE *)ptr'.  If this shared
        // pointer is already managing a (possibly shared) object, then, unless
        // an exception is thrown allocating memory to manage 'ptr', release
        // the reference to the shared object, calling the associated deleter
        // to destroy the shared object if this shared pointer is the last
        // reference.  Use the specified 'basicAllocator' to allocate the
        // internal representation of this shared pointer and to destroy the
        // shared object when all references have been released; if
        // 'basicAllocator' is 0, the currently installed default allocator is
        // used.  If an exception is thrown allocating the internal
        // representation, then destroy '*ptr' with a call to
        // 'alloc->deleteObject(ptr)' where 'alloc' is the chosen allocator,
        // and this shared pointer retains ownership of its original object.
        // If 'COMPATIBLE_TYPE *' is not implicitly convertible to
        // 'ELEMENT_TYPE *', then a compiler diagnostic will be emitted
        // indicating the error.  Note that if 'ptr' is 0, then this shared
        // pointer will still allocate an internal representation to share
        // ownership of that empty state, which will be reclaimed when the last
        // reference is destroyed.  Also note that this function is logically
        // equivalent to:
        //..
        //  *this = shared_ptr<ELEMENT_TYPE>(ptr, basicAllocator);
        //..

    template <class COMPATIBLE_TYPE, class DELETER>
    void load(COMPATIBLE_TYPE               *ptr,
              const DELETER&                 deleter,
              BloombergLP::bslma::Allocator *basicAllocator);
        // [!DEPRECATED!] Use 'reset' instead.
        //
        // Modify this shared pointer to manage the modifiable object of the
        // (template parameter) type 'COMPATIBLE_TYPE' at the specified 'ptr'
        // address, refer to '(ELEMENT_TYPE *)ptr' and use the specified
        // 'deleter' to delete the shared object when all references have been
        // released.  Use the specified 'basicAllocator' to allocate and
        // deallocate the internal representation of the shared pointer.  If
        // 'basicAllocator' is 0, the currently installed default allocator is
        // used.  If this shared pointer is already managing a (possibly
        // shared) object, then, unless an exception is thrown creating storage
        // to manage 'ptr', release the shared reference to that shared object,
        // and destroy it using its associated deleter if this shared pointer
        // held the last shared reference to that object.  If 'DELETER' is a
        // reference type, then 'deleter' is assumed to be a function-like
        // deleter that may be invoked to destroy the object referred to by a
        // single argument of type 'COMPATIBLE_TYPE *' (i.e., 'deleter(ptr)'
        // will be called to destroy the shared object).  If 'DELETER' is a
        // pointer type, then 'deleter' is assumed to be a pointer to a factory
        // object that exposes a member function that can be invoked as
        // 'deleteObject(ptr)' that will be called to destroy the object at the
        // 'ptr' address (i.e., 'deleter->deleteObject(ptr)' will be called to
        // delete the shared object).  (See the "Deleters" section in the
        // component-level documentation.)  If an exception is thrown
        // allocating the internal representation, then 'deleter(ptr)' is
        // called (or 'deleter->deleteObject(ptr)' for factory-type deleters)
        // and this shared pointer retains ownership of its original object.
        // The behavior is undefined unless 'deleter(ptr)' is a well-defined
        // expression (or 'deleter->deleteObject(ptr)' for factory-type
        // deleters), and unless the copy constructor for 'deleter' does not
        // throw an exception.  If 'COMPATIBLE_TYPE *' is not implicitly
        // convertible to 'ELEMENT_TYPE *', then a compiler diagnostic will be
        // emitted indicating the error.  Note that, for factory deleters, the
        // 'deleter' must remain valid until all references to 'ptr' have been
        // released.  Also note that if 'ptr' is 0, then an internal
        // representation will still be allocated, and this shared pointer will
        // share ownership of a copy of 'deleter'.  Further note that this
        // function is logically equivalent to:
        //..
        //  *this = shared_ptr<ELEMENT_TYPE>(ptr, deleter, basicAllocator);
        //..

#endif // BDE_OMIT_INTERNAL_DEPRECATED

    // ACCESSORS
    operator BoolType() const BSLS_KEYWORD_NOEXCEPT;
        // Return a value of an "unspecified bool" type that evaluates to
        // 'false' if this shared pointer does not refer to an object, and
        // 'true' otherwise.  Note that this conversion operator allows a
        // shared pointer to be used within a conditional context (e.g., within
        // an 'if' or 'while' statement), but does *not* allow shared pointers
        // to unrelated types to be compared (e.g., via '<' or '>').

    typename add_lvalue_reference<ELEMENT_TYPE>::type
    operator*() const BSLS_KEYWORD_NOEXCEPT;
        // Return a reference providing modifiable access to the object
        // referred to by this shared pointer.  The behavior is undefined
        // unless this shared pointer refers to an object, and 'ELEMENT_TYPE'
        // is not (potentially 'const' or 'volatile' qualified) 'void'.

    ELEMENT_TYPE *operator->() const BSLS_KEYWORD_NOEXCEPT;
        // Return the address providing modifiable access to the object
        // referred to by this shared pointer, or 0 if this shared pointer does
        // not refer to an object.  Note that applying this operator
        // conventionally (e.g., to invoke a method) to an shared pointer that
        // does not refer to an object will result in undefined behavior.

    element_type *get() const BSLS_KEYWORD_NOEXCEPT;
        // Return the address providing modifiable access to the object
        // referred to by this shared pointer, or 0 if this shared pointer does
        // not refer to an object.

    typename add_lvalue_reference<element_type>::type
    operator[](ptrdiff_t index) const;
        // Return a reference providing modifiable access to the object at the
        // specified 'index' offset in the object referred to by this shared
        // pointer.  The behavior is undefined unless this shared pointer is
        // not empty, 'ELEMENT_TYPE' is not 'void' (a compiler error will be
        // generated if this operator is instantiated within the
        // 'shared_ptr<void>' class), and this shared pointer refers to an
        // array of 'ELEMENT_TYPE' objects.  Instead of 'element_type &', we
        // use 'add_lvalue_reference<element_type>::type' for the return type
        // because that allows people to instantiate 'shared_ptr<cv_void>', as
        // long as they don't use this method.  Note that this method is
        // logically equivalent to '*(get() + index)'.

    template<class ANY_TYPE>
    bool owner_before(const shared_ptr<ANY_TYPE>& other) const
                                                         BSLS_KEYWORD_NOEXCEPT;
    template<class ANY_TYPE>
    bool owner_before(const weak_ptr<ANY_TYPE>& other) const
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return 'true' if the address of the
        // 'BloombergLP::bslma::SharedPtrRep' object used by this shared
        // pointer is ordered before the address of the
        // 'BloombergLP::bslma::SharedPtrRep' object used by the specified
        // 'other' shared pointer under the total ordering defined by
        // 'std::less<BloombergLP::bslma::SharedPtrRep *>', and 'false'
        // otherwise.

    BSLS_DEPRECATE_FEATURE("bsl",
                           "deprecated_cpp17_standard_library_features",
                           "do not use")
    bool unique() const BSLS_KEYWORD_NOEXCEPT;
        // Return 'true' if this shared pointer is not empty and does not share
        // ownership of the object it managed with any other shared pointer,
        // and 'false' otherwise.  Note that a shared pointer with a custom
        // deleter can refer to a null pointer without being empty, and so may
        // be 'unique'.  Also note that the result of this function may not be
        // reliable in a multi-threaded program, where a weak pointer may be
        // locked on another thread.
        //
        // DEPRECATED: This function is deprecated in C++17 because its
        // correctness is not guaranteed since the value returned by the used
        // 'use_count' function is approximate.

    long use_count() const BSLS_KEYWORD_NOEXCEPT;
        // Return a "snapshot" of the number of shared pointers (including this
        // one) that share ownership of the object managed by this shared
        // pointer.  Note that 0 is returned if this shared pointer is empty.
        // Also note that any result other than 0 may be unreliable in a
        // multi-threaded program, where another pointer sharing ownership in a
        // different thread may be copied or destroyed, or a weak pointer may
        // be locked in the case that 1 is returned (that would otherwise
        // indicate unique ownership).

    // ADDITIONAL BSL ACCESSORS
    BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE> managedPtr() const;
        // Return a managed pointer that refers to the same object as this
        // shared pointer.  If this shared pointer is not empty, and is not
        // null, then increment the shared count on the shared object, and give
        // the managed pointer a deleter that decrements the reference count
        // for the shared object.  Note that if this 'shared_ptr' is reference-
        // counting a null pointer, the empty 'bslma::ManagedPtr' returned will
        // not participate in that shared ownership.

    BloombergLP::bslma::SharedPtrRep *rep() const BSLS_KEYWORD_NOEXCEPT;
        // Return the address providing modifiable access to the
        // 'BloombergLP::bslma::SharedPtrRep' object used by this shared
        // pointer, or 0 if this shared pointer is empty.

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
    // DEPRECATED BDE LEGACY ACCESSORS
    int numReferences() const BSLS_KEYWORD_NOEXCEPT;
        // [!DEPRECATED!] Use 'use_count' instead.
        //
        // Return a "snapshot" of the number of shared pointers (including this
        // one) that share ownership of the object managed by this shared
        // pointer.  Note that the behavior of this function is the same as
        // 'use_count', and the result may be unreliable in multi-threaded code
        // for the same reasons.

    ELEMENT_TYPE *ptr() const BSLS_KEYWORD_NOEXCEPT;
        // [!DEPRECATED!] Use 'get' instead.
        //
        // Return the address providing modifiable access to the object
        // referred to by this shared pointer, or 0 if this shared pointer does
        // not refer to an object.  Note that the behavior of this function is
        // the same as 'get'.
#endif // BDE_OMIT_INTERNAL_DEPRECATED
};

#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
// CLASS TEMPLATE DEDUCTION GUIDES

//  The obvious deduction guide:
//  template <class T>
//  shared_ptr(T*) -> shared_ptr<T>;
//  is not provided because there's no way to distinguish from T* and T[].

template<class ELEMENT_TYPE>
shared_ptr(weak_ptr<ELEMENT_TYPE>) -> shared_ptr<ELEMENT_TYPE>;
    // Deduce the specified type 'ELEMENT_TYPE' corresponding template
    // parameter of the 'bsl::weak_ptr' supplied to the constructor of
    // 'shared_ptr'.

template<class ELEMENT_TYPE, class DELETER>
shared_ptr(std::unique_ptr<ELEMENT_TYPE, DELETER>)
-> shared_ptr<ELEMENT_TYPE>;
    // Deduce the specified type 'ELEMENT_TYPE' corresponding template
    // parameter of the 'std::unique_ptr' supplied to the constructor of
    // 'shared_ptr'.

template<class ELEMENT_TYPE,
         class DELETER,
         class ALLOC,
         class = typename bsl::enable_if_t<
               bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
         >
shared_ptr(std::unique_ptr<ELEMENT_TYPE, DELETER>, ALLOC *)
-> shared_ptr<ELEMENT_TYPE>;
    // Deduce the specified type 'ELEMENT_TYPE' corresponding template
    // parameter of the 'std::unique_ptr' supplied to the constructor of
    // 'shared_ptr'.  This guide does not participate in deduction unless the
    // specified 'ALLOC' inherits from 'bslma::Allocator'.

// Deduction guides for 'auto_ptr' and 'auto_ptr_ref' are deliberately not
// provided, since auto_ptr has been removed from C++17.

template<class ELEMENT_TYPE>
shared_ptr(BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>)
-> shared_ptr<ELEMENT_TYPE>;
    // Deduce the specified type 'ELEMENT_TYPE' corresponding template
    // parameter of the 'bslma::ManagedPtr' supplied to the constructor of
    // 'shared_ptr'.

template<class ELEMENT_TYPE,
         class ALLOC,
         class = typename bsl::enable_if_t<
               bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
         >
shared_ptr(BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>, ALLOC *)
-> shared_ptr<ELEMENT_TYPE>;
    // Deduce the specified type 'ELEMENT_TYPE' corresponding template
    // parameter of the 'bslma::ManagedPtr' supplied to the constructor of
    // 'shared_ptr'.  This guide does not participate in deduction unless the
    // specified 'ALLOC' inherits from 'bslma::Allocator'.
#endif

// FREE OPERATORS
template <class LHS_TYPE, class RHS_TYPE>
bool operator==(const shared_ptr<LHS_TYPE>& lhs,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer refers to the same
    // object (if any) as that referred to by the specified 'rhs' shared
    // pointer (if any), and 'false' otherwise; a compiler diagnostic will be
    // emitted indicating the error unless a (raw) pointer to 'LHS_TYPE' can
    // be compared to a (raw) pointer to 'RHS_TYPE'.  Note that two shared
    // pointers that compare equal do not necessarily manage the same object
    // due to aliasing.

template <class LHS_TYPE, class RHS_TYPE>
bool operator!=(const shared_ptr<LHS_TYPE>& lhs,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer does not refer to
    // the same object (if any) as that referred to by the specified 'rhs'
    // shared pointer (if any), and 'false' otherwise; a compiler diagnostic
    // will be emitted indicating the error unless a (raw) pointer to
    // 'LHS_TYPE' can be compared to a (raw) pointer to 'RHS_TYPE'.  Note that
    // two shared pointers that do not compare equal may manage the same object
    // due to aliasing.

template<class LHS_TYPE, class RHS_TYPE>
bool operator<(const shared_ptr<LHS_TYPE>& lhs,
               const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the address of the object that the specified 'lhs'
    // shared pointer refers to is ordered before the address of the object
    // that the specified 'rhs' shared pointer refers to under the total
    // ordering supplied by 'std::less<T *>', where 'T *' is the composite
    // pointer type of 'LHS_TYPE *' and 'RHS_TYPE *', and 'false' otherwise.

template<class LHS_TYPE, class RHS_TYPE>
bool operator>(const shared_ptr<LHS_TYPE>& lhs,
               const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the address of the object that the specified 'lhs'
    // shared pointer refers to is ordered after the address of the object
    // that the specified 'rhs' shared pointer refers to under the total
    // ordering supplied by 'std::less<T *>', where 'T *' is the composite
    // pointer type of 'LHS_TYPE *' and 'RHS_TYPE *', and 'false' otherwise.

template<class LHS_TYPE, class RHS_TYPE>
bool operator<=(const shared_ptr<LHS_TYPE>& lhs,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer refers to the same
    // object as the specified 'rhs' shared pointer, or if the address of the
    // object referred to by 'lhs' (if any) is ordered before the address of
    // the object referred to by 'rhs' (if any) under the total ordering
    // supplied by 'std::less<T *>', where 'T *' is the composite pointer type
    // of 'LHS_TYPE *' and 'RHS_TYPE *', and 'false' otherwise.

template<class LHS_TYPE, class RHS_TYPE>
bool operator>=(const shared_ptr<LHS_TYPE>& lhs,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer refers to the same
    // object as the specified 'rhs' shared pointer, or if the address of the
    // object referred to by 'lhs' (if any) is ordered after the address of the
    // object referred to by 'rhs' (if any) under the total ordering supplied
    // by 'std::less<T *>', where 'T *' is the composite pointer type of
    // 'LHS_TYPE *' and 'RHS_TYPE *', and 'false' otherwise.

template <class LHS_TYPE>
bool operator==(const shared_ptr<LHS_TYPE>& lhs,
                nullptr_t) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer does not refer to an
    // object, and 'false' otherwise.

template <class RHS_TYPE>
bool operator==(nullptr_t,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'rhs' shared pointer does not refer to an
    // object, and 'false' otherwise.

template <class LHS_TYPE>
bool operator!=(const shared_ptr<LHS_TYPE>& lhs,
                nullptr_t) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer refers to an object,
    // and 'false' otherwise.

template <class RHS_TYPE>
bool operator!=(nullptr_t,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'rhs' shared pointer refers to an object,
    // and 'false' otherwise.

template <class LHS_TYPE>
bool operator<(const shared_ptr<LHS_TYPE>& lhs, nullptr_t)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the address of the object referred to by the specified
    // 'lhs' shared pointer is ordered before the null-pointer value under the
    // total ordering supplied by 'std::less<LHS_TYPE *>', and 'false'
    // otherwise.

template <class RHS_TYPE>
bool operator<(nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the address of the object referred to by the specified
    // 'rhs' shared pointer is ordered after the null-pointer value under the
    // total ordering supplied by 'std::less<RHS_TYPE *>', and 'false'
    // otherwise.

template <class LHS_TYPE>
bool operator<=(const shared_ptr<LHS_TYPE>& lhs,
                nullptr_t) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer does not refer to an
    // object, or if the address of the object referred to by 'lhs' is ordered
    // before the null-pointer value under the total ordering supplied by
    // 'std::less<LHS_TYPE *>', and 'false' otherwise.

template <class RHS_TYPE>
bool operator<=(nullptr_t,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'rhs' shared pointer does not refer to an
    // object, or if the address of the object referred to by 'rhs' is ordered
    // after the null-pointer value under the total ordering supplied by
    // 'std::less<RHS_TYPE *>', and 'false' otherwise.

template <class LHS_TYPE>
bool operator>(const shared_ptr<LHS_TYPE>& lhs, nullptr_t)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the address of the object referred to by the specified
    // 'lhs' shared pointer is ordered after the null-pointer value under the
    // total ordering supplied by 'std::less<LHS_TYPE *>', and 'false'
    // otherwise.

template <class RHS_TYPE>
bool operator>(nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the address of the object referred to by the specified
    // 'rhs' shared pointer is ordered before the null-pointer value under the
    // total ordering supplied by 'std::less<RHS_TYPE *>', and 'false'
    // otherwise.

template <class LHS_TYPE>
bool operator>=(const shared_ptr<LHS_TYPE>& lhs,
                nullptr_t) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'lhs' shared pointer does not refer to an
    // object, or if the address of the object referred to by 'lhs' is ordered
    // after the null-pointer value under the total ordering supplied by
    // 'std::less<LHS_TYPE *>', and 'false' otherwise.

template <class RHS_TYPE>
bool operator>=(nullptr_t,
                const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    // Return 'true' if the specified 'rhs' shared pointer does not refer to an
    // object, or if the address of the object referred to by 'rhs' is ordered
    // before the null-pointer value under the total ordering supplied by
    // 'std::less<RHS_TYPE *>', and 'false' otherwise.

template<class CHAR_TYPE, class CHAR_TRAITS, class ELEMENT_TYPE>
std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>&
operator<<(std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& stream,
           const shared_ptr<ELEMENT_TYPE>&             rhs);
    // Print to the specified 'stream' the address of the shared object
    // referred to by the specified 'rhs' shared pointer and return a reference
    // to the modifiable 'stream'.

// ASPECTS
template <class HASHALG, class ELEMENT_TYPE>
void hashAppend(HASHALG& hashAlg, const shared_ptr<ELEMENT_TYPE>& input);
    // Pass the address of the object referred to by the specified 'input'
    // shared pointer to the specified 'hashAlg' hashing algorithm of (template
    // parameter) type 'HASHALG'.

template <class ELEMENT_TYPE>
void swap(shared_ptr<ELEMENT_TYPE>& a, shared_ptr<ELEMENT_TYPE>& b)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Efficiently exchange the states of the specified 'a' and 'b' shared
    // pointers such that each will refer to the object formerly referred to by
    // the other, and each will manage the object formerly managed by the
    // other.

// STANDARD FREE FUNCTIONS
template<class DELETER, class ELEMENT_TYPE>
DELETER *get_deleter(const shared_ptr<ELEMENT_TYPE>& p) BSLS_KEYWORD_NOEXCEPT;
    // Return the address of deleter used by the specified 'p' shared pointer
    // if the (template parameter) type 'DELETER' is the type of the deleter
    // installed in 'p', and a null pointer value otherwise.

// STANDARD CAST FUNCTIONS
template<class TO_TYPE, class FROM_TYPE>
shared_ptr<TO_TYPE> const_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return a 'shared_ptr<TO_TYPE>' object sharing ownership of the same
    // object as the specified 'source' shared pointer to the (template
    // parameter) 'FROM_TYPE', and referring to
    // 'const_cast<TO_TYPE *>(source.get())'.  Note that if 'source' cannot be
    // 'const'-cast to 'TO_TYPE *', then a compiler diagnostic will be emitted
    // indicating the error.

template<class TO_TYPE, class FROM_TYPE>
shared_ptr<TO_TYPE> dynamic_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return a 'shared_ptr<TO_TYPE>' object sharing ownership of the same
    // object as the specified 'source' shared pointer to the (template
    // parameter) 'FROM_TYPE', and referring to
    // 'dynamic_cast<TO_TYPE*>(source.get())'.  If 'source' cannot be
    // dynamically cast to 'TO_TYPE *', then an empty 'shared_ptr<TO_TYPE>'
    // object is returned.

template<class TO_TYPE, class FROM_TYPE>
shared_ptr<TO_TYPE> static_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Return a 'shared_ptr<TO_TYPE>' object sharing ownership of the same
    // object as the specified 'source' shared pointer to the (template
    // parameter) 'FROM_TYPE', and referring to
    // 'static_cast<TO_TYPE *>(source.get())'.  Note that if 'source' cannot be
    // statically cast to 'TO_TYPE *', then a compiler diagnostic will be
    // emitted indicating the error.

template<class TO_TYPE, class FROM_TYPE>
shared_ptr<TO_TYPE> reinterpret_pointer_cast(
                    const shared_ptr<FROM_TYPE>& source) BSLS_KEYWORD_NOEXCEPT;
    // Return a 'shared_ptr<TO_TYPE>' object sharing ownership of the same
    // object as the specified 'source' shared pointer to the (template
    // parameter) 'FROM_TYPE', and referring to
    // 'reinterpret_cast<TO_TYPE *>(source.get())'.  Note that if 'source'
    // cannot be reinterpret_cast-ed to 'TO_TYPE *', then a compiler diagnostic
    // will be emitted indicating the error.


// STANDARD FACTORY FUNCTIONS
#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_sharedptr.h
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT 14
#endif
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#endif
#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 0
template<class ELEMENT_TYPE, class ALLOC>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 1
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 2
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 3
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 4
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 5
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 6
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 7
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 8
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 9
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 10
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 11
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 12
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 13
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 14
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13,
                                          class ARGS_14>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 14


#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 0
template<class ELEMENT_TYPE, class ALLOC>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 1
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 2
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 3
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 4
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 5
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 6
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 7
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 8
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 9
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 10
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 11
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 12
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 13
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 14
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13,
                                          class ARGS_14>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                           BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 14


#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 0
template<class ELEMENT_TYPE>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared();
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 1
template<class ELEMENT_TYPE, class ARGS_01>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 2
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 3
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 4
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 5
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 6
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 7
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 8
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 9
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 10
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 11
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 12
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11,
                             class ARGS_12>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 13
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11,
                             class ARGS_12,
                             class ARGS_13>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 14
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11,
                             class ARGS_12,
                             class ARGS_13,
                             class ARGS_14>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14);
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_B >= 14

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename enable_if<!is_pointer<ALLOC>::value && !is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# else
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
# endif
allocate_shared(ALLOC basicAllocator,
                              BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);

template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
allocate_shared(ALLOC *basicAllocator,
                              BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);

template<class ELEMENT_TYPE, class... ARGS>
typename enable_if<!is_array<ELEMENT_TYPE>::value,
                   shared_ptr<ELEMENT_TYPE> >::type
make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
// }}} END GENERATED CODE
#endif

                        // ==============
                        // class weak_ptr
                        // ==============

template <class ELEMENT_TYPE>
class weak_ptr {
    // This 'class' provides a mechanism to create weak references to
    // reference-counted shared ('shared_ptr') objects.  A weak reference
    // provides conditional access to a shared object managed by a
    // 'shared_ptr', but, unlike a shared (or "strong") reference, does not
    // affect the shared object's lifetime.

    // DATA
    ELEMENT_TYPE                     *d_ptr_p; // pointer to the referenced
                                               // object

    BloombergLP::bslma::SharedPtrRep *d_rep_p; // pointer to the representation
                                               // object that manages the
                                               // shared object (held, not
                                               // owned)

    // PRIVATE MANIPULATORS
    void privateAssign(BloombergLP::bslma::SharedPtrRep *rep,
                       ELEMENT_TYPE                     *target);
        // Release weak ownership of the currently managed shared pointer rep
        // and assign to this weak pointer weak ownership of the specified
        // shared pointer 'rep', aliasing the specified 'target' pointer.

    // FRIENDS
    template <class COMPATIBLE_TYPE>
    friend class weak_ptr;
        // This 'friend' declaration provides access to the internal data
        // members while constructing a weak pointer from a weak pointer of a
        // different type.

    friend struct BloombergLP::bslstl::SharedPtr_ImpUtil;

  public:
    // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(weak_ptr<ELEMENT_TYPE>,
                                   bsl::is_nothrow_move_constructible);

    // TYPES
    typedef typename bsl::remove_extent<ELEMENT_TYPE>::type element_type;
        // For weak pointers to non-array types, 'element_type' is an alias to
        // the 'ELEMENT_TYPE' template parameter.  Otherwise, it is an alias to
        // the type contained in the array.

    // CREATORS
    BSLS_KEYWORD_CONSTEXPR
    weak_ptr() BSLS_KEYWORD_NOEXCEPT;
        // Create a weak pointer in the empty state and referring to no object,
        // i.e., a weak pointer having no representation.

    weak_ptr(BloombergLP::bslmf::MovableRef<weak_ptr> original)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Create a weak pointer that refers to the same object (if any) as the
        // specified 'original' weak pointer, and reset 'original' to an empty
        // state.

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    weak_ptr(weak_ptr<COMPATIBLE_TYPE>&& other) BSLS_KEYWORD_NOEXCEPT;
#else
    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    weak_ptr(BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > other)
                                                         BSLS_KEYWORD_NOEXCEPT;
#endif
        // Create a weak pointer that refers to the same object (if any) as the
        // specified 'other' weak pointer, and reset 'original' to an empty
        // state.  Note that this operation does not involve any change to
        // reference counts.

    weak_ptr(const weak_ptr& original) BSLS_KEYWORD_NOEXCEPT;
        // Create a weak pointer that refers to the same object (if any) as the
        // specified 'original' weak pointer, and increment the number of weak
        // references to the object managed by 'original' (if any).  Note that
        // if 'original' is in the empty state, this weak pointer will be
        // initialized to the empty state.

    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    weak_ptr(const shared_ptr<COMPATIBLE_TYPE>& other) BSLS_KEYWORD_NOEXCEPT;
                                                                    // IMPLICIT
    template <class COMPATIBLE_TYPE
              BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE>
    weak_ptr(const weak_ptr<COMPATIBLE_TYPE>& other) BSLS_KEYWORD_NOEXCEPT;
                                                                    // IMPLICIT
        // Create a weak pointer that refers to the same object (if any) as the
        // specified 'other' (shared or weak) pointer of the (template
        // parameter) 'COMPATIBLE_TYPE', and increment the number of weak
        // references to the object managed by 'other' (if any).  If
        // 'COMPATIBLE_TYPE *' is not implicitly convertible to
        // 'ELEMENT_TYPE *', then a compiler diagnostic will be emitted.  Note
        // that if 'other' is in the empty state, this weak pointer will be
        // initialized to the empty state.

    ~weak_ptr();
        // Destroy this weak pointer object.  If this weak pointer manages a
        // (possibly shared) object, release the weak reference to that object.

    // MANIPULATORS
    weak_ptr& operator=(BloombergLP::bslmf::MovableRef<weak_ptr> rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Make this weak pointer refer to the same object (if any) as the
        // specified 'rhs' weak pointer.  If 'rhs' is not a reference to this
        // weak pointer, decrement the number of weak references to the object
        // this weak pointer managed (if any), and reset 'rhs' to an empty
        // state.  Return a reference providing modifiable access to this weak
        // pointer.  Note that if 'rhs' is in an empty state, this weak pointer
        // will be set to an empty state.

    weak_ptr& operator=(const weak_ptr& rhs) BSLS_KEYWORD_NOEXCEPT;
        // Make this weak pointer refer to the same object (if any) as the
        // specified 'rhs' weak pointer.  Decrement the number of weak
        // references to the object this weak pointer manages (if any), and
        // increment the number of weak references to the object managed by
        // 'rhs' (if any).  Return a reference providing modifiable access to
        // this weak pointer.  Note that if 'rhs' is in an empty state, this
        // weak pointer will be set to an empty state.

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
    template <class COMPATIBLE_TYPE>
    typename enable_if<
     is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value, weak_ptr&>::type
    operator=(weak_ptr<COMPATIBLE_TYPE>&& rhs) BSLS_KEYWORD_NOEXCEPT;
#else
    template <class COMPATIBLE_TYPE>
    typename enable_if<
     is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value, weak_ptr&>::type
    operator=(BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
#endif
        // Make this weak pointer refer to the same object (if any) as the
        // specified 'rhs' weak pointer.  Decrement the number of weak
        // references to the object this weak pointer managed (if any), and
        // reset 'rhs' to an empty state.  Return a reference providing
        // modifiable access to this weak pointer.  This function does not
        // exist unless a pointer to (the template parameter) 'COMPATIBLE_TYPE'
        // is convertible to a pointer to (the template parameter)
        // 'ELEMENT_TYPE'.  Note that if 'rhs' is in an empty state, this weak
        // pointer will be set to an empty state.

    template <class COMPATIBLE_TYPE>
    typename enable_if<
     is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value, weak_ptr&>::type
    operator=(const shared_ptr<COMPATIBLE_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
    template <class COMPATIBLE_TYPE>
    typename enable_if<
     is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value, weak_ptr&>::type
    operator=(const weak_ptr<COMPATIBLE_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
        // Make this weak pointer refer to the same object (if any) as the
        // specified 'rhs' (shared or weak) pointer to the (template parameter)
        // 'COMPATIBLE_TYPE'.  Decrement the number of weak references to the
        // object to which this weak pointer currently manages (if any), and
        // increment the number of weak references to the object managed by
        // 'rhs' (if any).  Return a reference providing modifiable access to
        // this weak pointer.  If 'COMPATIBLE_TYPE *' is not implicitly
        // convertible to 'TYPE *', then a compiler diagnostic will be emitted.
        // Note that if 'rhs' is in the empty state, this weak pointer will be
        // set to the empty state.

    void reset() BSLS_KEYWORD_NOEXCEPT;
        // Reset this weak pointer to the empty state.  If this weak pointer
        // manages a (possibly shared) object, then decrement the number of
        // weak references to that object.

    void swap(weak_ptr& other) BSLS_KEYWORD_NOEXCEPT;
        // Efficiently exchange the states of this weak pointer and the
        // specified 'other' weak pointer such that each will refer to the
        // object (if any) and representation (if any) formerly referred to and
        // managed by the other.

    // ACCESSORS
    bool expired() const BSLS_KEYWORD_NOEXCEPT;
        // Return 'true' if this weak pointer is in the empty state or the
        // object that it originally referenced has been destroyed, and 'false'
        // otherwise.

    shared_ptr<ELEMENT_TYPE> lock() const BSLS_KEYWORD_NOEXCEPT;
        // Return a shared pointer to the object referred to by this weak
        // pointer if 'false == expired()', and a shared pointer in the empty
        // state otherwise.

    template <class ANY_TYPE>
    bool owner_before(const shared_ptr<ANY_TYPE>& other) const
                                                         BSLS_KEYWORD_NOEXCEPT;
    template <class ANY_TYPE>
    bool owner_before(const weak_ptr<ANY_TYPE>& other) const
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return 'true' if the address of the
        // 'BloombergLP::bslma::SharedPtrRep' object used by this weak pointer
        // is ordered before the address of the
        // 'BloombergLP::bslma::SharedPtrRep' object used by the specified
        // 'other' shared pointer under the total ordering defined by
        // 'std::less<BloombergLP::bslma::SharedPtrRep *>', and 'false'
        // otherwise.

    BloombergLP::bslma::SharedPtrRep *rep() const BSLS_KEYWORD_NOEXCEPT;
        // Return the address providing modifiable access to the
        // 'BloombergLP::bslma::SharedPtrRep' object held by this weak pointer,
        // or 0 if this weak pointer is in the empty state.

    long use_count() const BSLS_KEYWORD_NOEXCEPT;
        // Return a "snapshot" of the current number of shared pointers that
        // share ownership of the object referred to by this weak pointer, or 0
        // if this weak pointer is in the empty state.  Note that any result
        // other than 0 may be unreliable in a multi-threaded program, where
        // another pointer sharing ownership in a different thread may be
        // copied or destroyed, or another weak pointer may be locked in the
        // case that 1 is returned (that would otherwise indicate unique
        // ownership).

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
    // DEPRECATED BDE LEGACY ACCESSORS
    shared_ptr<ELEMENT_TYPE> acquireSharedPtr() const BSLS_KEYWORD_NOEXCEPT;
        // Return a shared pointer to the object referred to by this weak
        // pointer and managing the same object as that managed by this weak
        // pointer (if any) if 'false == expired()', and a shared pointer in
        // the empty state otherwise.  Note that the behavior of this method is
        // the same as that of 'lock'.

    int numReferences() const BSLS_KEYWORD_NOEXCEPT;
        // [!DEPRECATED!] Use 'use_count' instead.
        //
        // Return a "snapshot" of the current number of shared pointers that
        // share ownership of the object referred to by this weak pointer, or 0
        // if this weak pointer is in the empty state.  Note that the behavior
        // of this method is the same as that of 'use_count', and the result
        // may be unreliable in multi-threaded code for the same reasons.
#endif // BDE_OMIT_INTERNAL_DEPRECATED
};

#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
// CLASS TEMPLATE DEDUCTION GUIDES

template<class ELEMENT_TYPE>
weak_ptr(shared_ptr<ELEMENT_TYPE>) -> weak_ptr<ELEMENT_TYPE>;
    // Deduce the specified type 'ELEMENT_TYPE' corresponding template
    // parameter of the 'bsl::shared_ptr' supplied to the constructor of
    // 'weak_ptr'.
#endif

                    //==============================
                    // class enable_shared_from_this
                    //==============================

template<class ELEMENT_TYPE>
class enable_shared_from_this {
    // This class allows an object that is currently managed by a 'shared_ptr'
    // to safely generate a copy of the managing 'shared_ptr' object.
    // Inheriting from 'enable_shared_from_this<ELEMENT_TYPE>' provides the
    // (template parameter) 'ELEMENT_TYPE' type with a member function
    // 'shared_from_this'.  If an object of type 'ELEMENT_TYPE' is managed by a
    // 'shared_ptr' then calling 'shared_from_this' will return a
    // 'shared_ptr<ELEMENT_TYPE>' that shares ownership of that object.  It is
    // undefined behavior to call 'shared_from_this' on an object unless that
    // object is managed by a 'shared_ptr'.
    //
    // The intended use of 'enable_shared_from_this' is that the (template
    // parameter) type 'ELEMENT_TYPE' inherits directly from the
    // 'enable_shared_from_this' class template.  In the case of multiple
    // inheritance, only one of the base classes should inherit from the
    // 'enable_shared_from_this' class template.  If multiple base classes
    // inherit from 'enable_shared_from_this', then there will be ambiguous
    // calls to the 'shared_from_this' function.

    // FRIENDS
    friend struct BloombergLP::bslstl::SharedPtr_ImpUtil;
        // Allows 'shared_ptr' to initialize 'd_weakThis' when it detects an
        // 'enable_shared_from_this' base class.

  private:
    // DATA
    mutable bsl::weak_ptr<ELEMENT_TYPE> d_weakThis;

  protected:
    // PROTECTED CREATORS
    enable_shared_from_this() BSLS_KEYWORD_NOEXCEPT;
        // Create an 'enable_shared_from_this' object that is not owned by any
        // 'shared_ptr' object.

    enable_shared_from_this(const enable_shared_from_this& unused)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Create an 'enable_shared_from_this' object that is not owned by any
        // 'shared_ptr' object.  Note that the specified 'unused' argument is
        // not used by this constructor.

    ~enable_shared_from_this();
        // Destroy this 'enable_shared_form_this'.

    // PROTECTED MANIPULATORS
    enable_shared_from_this& operator=(const enable_shared_from_this& rhs)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return '*this'. This object is unchanged.  Note that the specified
        // 'rhs' is not used.

  public:
    // MANIPULATORS
    bsl::shared_ptr<ELEMENT_TYPE> shared_from_this();
        // Return a 'shared_ptr<ELEMENT_TYPE>' that shares ownership with an
        // existing 'shared_ptr' object that managed this object, and throw a
        // 'std::bad_weak_ptr' exception if there is no 'shared_ptr' currently
        // managing this object.  If multiple groups of 'shared_ptr's are
        // managing this object, the returned 'shared_ptr' will share ownership
        // with the group that first managed this object.

    bsl::weak_ptr<ELEMENT_TYPE> weak_from_this() BSLS_KEYWORD_NOEXCEPT;
        // Return a 'weak_ptr' holding a weak reference to this managed object
        // if this object is currently managed by 'shared_ptr', and return an
        // expired 'weak_ptr' otherwise.  If multiple groups of 'shared_ptr's
        // are managing this object, the returned 'weak_ptr' will hold a weak
        // reference to the group that first managed this object.

    // ACCESSORS
    bsl::shared_ptr<const ELEMENT_TYPE> shared_from_this() const;
        // Return a 'shared_ptr<const ELEMENT_TYPE>' that shares ownership with
        // an existing 'shared_ptr' object that managed this object, and throw
        // a 'std::bad_weak_ptr' exception if there is no 'shared_ptr'
        // currently managing this object.  If multiple groups of 'shared_ptr's
        // are managing this object, the returned 'shared_ptr' will share
        // ownership with the group that first managed this object.


    bsl::weak_ptr<const ELEMENT_TYPE> weak_from_this() const
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return a 'weak_ptr' holding a weak reference (with only 'const'
        // access) to this managed object if this object is currently managed
        // by 'shared_ptr', and return an expired 'weak_ptr' otherwise.  If
        // multiple groups of 'shared_ptr's are managing this object, the
        // returned 'weak_ptr' will hold a weak reference to the group that
        // first managed this object.
};

// ASPECTS
template <class ELEMENT_TYPE>
void swap(weak_ptr<ELEMENT_TYPE>& a, weak_ptr<ELEMENT_TYPE>& b)
                                                         BSLS_KEYWORD_NOEXCEPT;
    // Efficiently exchange the states of the specified 'a' and 'b' weak
    // pointers such that each will refer to the object (if any) and
    // representation formerly referred to by the other.

                        // =========================
                        // class hash specialization
                        // =========================

// A partial specialization of 'bsl::hash' is no longer necessary, as the
// primary template has the correct behavior once 'hashAppend' is defined.

}  // close namespace bsl

namespace BloombergLP {
namespace bslstl {

                            // ====================
                            // struct SharedPtrUtil
                            // ====================

struct SharedPtrUtil {
    // This 'struct' provides a namespace for operations on shared pointers.

    // CLASS METHODS
    static
    bsl::shared_ptr<char>
    createInplaceUninitializedBuffer(size_t            bufferSize,
                                     bslma::Allocator *basicAllocator = 0);
        // Return a shared pointer with an in-place representation holding a
        // newly-created uninitialized buffer of the specified 'bufferSize' (in
        // bytes).  Optionally specify a 'basicAllocator' used to supply
        // memory.  If 'basicAllocator' is 0, the currently installed default
        // allocator is used.  The behavior is undefined unless
        // '0 < bufferSize'.

    // CASTING FUNCTIONS
    template <class TARGET, class SOURCE>
    static
    void constCast(bsl::shared_ptr<TARGET>        *target,
                   const bsl::shared_ptr<SOURCE>&  source);
        // Load into the specified 'target' an aliased shared pointer sharing
        // ownership of the object managed by the specified 'source' shared
        // pointer and referring to 'const_cast<TARGET *>(source.get())'.  If
        // '*target' is already managing a (possibly shared) object, then
        // release the shared reference to that object, and destroy it using
        // its associated deleter if that shared pointer held the last shared
        // reference to that object.  Note that a compiler diagnostic will be
        // emitted indicating an error unless
        // 'const_cast<TARGET *>(source.get())' is a valid expression.

    template <class TARGET, class SOURCE>
    static
    bsl::shared_ptr<TARGET> constCast(const bsl::shared_ptr<SOURCE>& source)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return a 'bsl::shared_ptr<TARGET>' object sharing ownership of the
        // same object as the specified 'source' shared pointer to the
        // (template parameter) 'SOURCE' type, and referring to
        // 'const_cast<TARGET *>(source.get())'.  Note that a compiler
        // diagnostic will be emitted indicating an error unless
        // 'const_cast<TARGET *>(source.get())' is a valid expression.

    template <class TARGET, class SOURCE>
    static
    void dynamicCast(bsl::shared_ptr<TARGET>        *target,
                     const bsl::shared_ptr<SOURCE>&  source);
        // Load into the specified 'target' an aliased shared pointer sharing
        // ownership of the object managed by the specified 'source' shared
        // pointer and referring to 'dynamic_cast<TARGET *>(source.get())'.  If
        // '*target' is already managing a (possibly shared) object, then
        // release the shared reference to that object, and destroy it using
        // its associated deleter if that shared pointer held the last shared
        // reference to that object.  If
        // '0 == dynamic_cast<TARGET*>(source.get())', then '*target' shall be
        // reset to an empty state that does not refer to an object.  Note that
        // a compiler diagnostic will be emitted indicating an error unless
        // 'dynamic_cast<TARGET *>(source.get())' is a valid expression.

    template <class TARGET, class SOURCE>
    static
    bsl::shared_ptr<TARGET> dynamicCast(const bsl::shared_ptr<SOURCE>& source)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return a 'bsl::shared_ptr<TARGET>' object sharing ownership of the
        // same object as the specified 'source' shared pointer to the
        // (template parameter) 'SOURCE' type, and referring to
        // 'dynamic_cast<TARGET *>(source.get())'.  If that would return a
        // shared pointer referring to nothing ('0 == get()'), then instead
        // return an (empty) default constructed shared pointer.  Note that a
        // compiler diagnostic will be emitted indicating an error unless
        // 'dynamic_cast<TARGET *>(source.get())' is a valid expression..

    template <class TARGET, class SOURCE>
    static
    void staticCast(bsl::shared_ptr<TARGET>        *target,
                    const bsl::shared_ptr<SOURCE>&  source);
        // Load into the specified 'target' an aliased shared pointer sharing
        // ownership of the object managed by the specified 'source' shared
        // pointer and referring to 'static_cast<TARGET *>(source.get())'.  If
        // '*target' is already managing a (possibly shared) object, then
        // release the shared reference to that object, and destroy it using
        // its associated deleter if that shared pointer held the last shared
        // reference to that object.  Note that a compiler diagnostic will be
        // emitted indicating an error unless
        // 'static_cast<TARGET *>(source.get())' is a valid expression.

    template <class TARGET, class SOURCE>
    static
    bsl::shared_ptr<TARGET> staticCast(const bsl::shared_ptr<SOURCE>& source)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Return a 'bsl::shared_ptr<TARGET>' object sharing ownership of the
        // same object as the specified 'source' shared pointer to the
        // (template parameter) 'SOURCE' type, and referring to
        // 'static_cast<TARGET *>(source.get())'.  Note that a compiler
        // diagnostic will be emitted indicating an error unless
        // 'static_cast<TARGET *>(source.get())' is a valid expression.
};

                        // ==========================
                        // struct SharedPtrNilDeleter
                        // ==========================

struct SharedPtrNilDeleter {
    // This 'struct' provides a function-like shared pointer deleter that does
    // nothing when invoked.

    // ACCESSORS
    void operator()(const volatile void *) const BSLS_KEYWORD_NOEXCEPT;
        // No-Op.
};

                        // ===============================
                        // struct SharedPtr_DefaultDeleter
                        // ===============================

template <bool>
struct SharedPtr_DefaultDeleter {
    // This 'struct' provides a function-like shared pointer deleter that
    // invokes 'delete' with the passed pointer.  If the template parameter is
    // 'true', then the pointer is deleted using 'operator delete []'.
    // Otherwise, it is deleted using 'operator delete'.

    // ACCESSORS
    template <class ANY_TYPE>
    void operator()(ANY_TYPE *ptr) const BSLS_KEYWORD_NOEXCEPT;
        // Call 'delete' with the specified 'ptr'.
};

                        //=========================
                        // struct SharedPtr_ImpUtil
                        //=========================

struct SharedPtr_ImpUtil {
    // This 'struct' should be used by only 'shared_ptr' constructors. Its
    // purpose is to enable 'shared_ptr' constructors to determine if the
    // (template parameter) types 'COMPATIBLE_TYPE' or 'ELEMENT_TYPE' have a
    // specialization of 'enable_shared_from_this' as an unambiguous, publicly
    // accessible, base class.

    // CLASS METHODS
    template<class SHARED_TYPE, class ENABLE_TYPE>
    static void loadEnableSharedFromThis(
                   const bsl::enable_shared_from_this<ENABLE_TYPE> *result,
                   bsl::shared_ptr<SHARED_TYPE>                    *sharedPtr);
        // Load the specified 'result' with the control block (i.e.,
        // 'SharedPtrRep') from the specified 'sharedPtr' if (and only if)
        // 'result' is not 0 and 'result' does not already refer to a
        // non-expired shared-pointer control block.  If 'result' is 0, or if
        // 'result->d_weakThis' has not expired, this operation has no effect.
        // This operation is used to initialize data members from a type that
        // inherits from 'enable_shared_from_this' when constructing an
        // out-of-place shared pointer representation.  This function shall be
        // called only by 'shared_ptr' constructors creating shared pointers
        // for classes that derive publicly and unambiguously from a
        // specialization of 'enabled_shared_from_this'.  Note that overload
        // resolution will select the overload below if a supplied type does
        // not derive from a specialization of 'enable_shared_from_this'.

    static void loadEnableSharedFromThis(const volatile void *, const void *)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Do nothing.  This overload is selected, rather than the immediately
        // preceding template, when the 'SHARED_TYPE' template type parameter
        // of 'shared_ptr<SHARED_TYPE>' does not derive from a specialization
        // of 'enable_shared_from_this'.

    static void throwBadWeakPtr();
        // Throw a 'bsl::bad_weak_ptr' exception.

    template <class TYPE>
    static void *voidify(TYPE *address) BSLS_KEYWORD_NOEXCEPT;
        // Return the specified 'address' cast as a pointer to 'void', even if
        // (the template parameter) 'TYPE' is cv-qualified.

    template <class TYPE>
    static TYPE *unqualify(const volatile TYPE *address) BSLS_KEYWORD_NOEXCEPT;
        // Return the specified 'address' of a potentially 'cv'-qualified
        // object of the given (template parameter) 'TYPE', cast as a pointer
        // to a modifiable non-volatile object of the given 'TYPE'.
};

                        // ==========================
                        // class SharedPtr_RepProctor
                        // ==========================

class SharedPtr_RepProctor {
    // This 'class' implements a proctor that, unless its 'release' method has
    // previously been invoked, automatically releases a reference held by the
    // 'bslma::SharedPtrRep' object that is supplied at construction.

  private:
    // DATA
    bslma::SharedPtrRep *d_rep_p;    // Address of representation being managed

  private:
    // NOT IMPLEMENTED
    SharedPtr_RepProctor(const SharedPtr_RepProctor&);
    SharedPtr_RepProctor& operator=(const SharedPtr_RepProctor&);

  public:
    // CREATORS
    explicit SharedPtr_RepProctor(bslma::SharedPtrRep *rep)
                                                         BSLS_KEYWORD_NOEXCEPT;
        // Create a 'SharedPtr_RepProctor' that conditionally manages the
        // specified 'rep' (if non-zero).

    ~SharedPtr_RepProctor();
        // Destroy this 'SharedPtr_RepProctor', and dispose of (deallocate) the
        // 'bslma::SharedPtrRep' it manages (if any).  If no such object is
        // currently being managed, this method has no effect.  Note that the
        // destructor of the 'bslma::SharedPtrRep' will not be called as the
        // reference count will not be decremented.

    // MANIPULATORS
    void release() BSLS_KEYWORD_NOEXCEPT;
        // Release from management the object currently managed by this
        // proctor.  If no object is currently being managed, this method has
        // no effect.
};

}  // close package namespace
}  // close enterprise namespace

// ============================================================================
//                           INLINE DEFINITIONS
// ============================================================================

#if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
namespace BloombergLP {
namespace bslstl {

template <class FUNCTOR>
struct SharedPtr_TestIsCallable {
  private:
    // PRIVATE TYPES
    typedef BloombergLP::bslmf::Util Util;

    struct TrueType {
        char d_padding;
    };
    struct FalseType {
        char d_padding[17];
    };

    // The two structs 'TrueType' and 'FalseType' are guaranteed to have
    // distinct sizes, so that a 'sizeof(expression)' query, where 'expression'
    // returns one of these two types, will give different answers depending on
    // which type is returned.

  public:
    // CLASS METHODS
    template <class ARG>
    static FalseType test(...);
    template <class ARG>
    static TrueType
    test(typename bsl::enable_if<static_cast<bool>(
                    sizeof(BSLSTL_SHAREDPTR_SFINAE_DISCARD(
                               Util::declval<FUNCTOR>()(Util::declval<ARG>())),
                           0))>::type *);
        // This function is never defined.  It provides a property-checker that
        // an entity of (template parameter) type 'FACTORY' can be called like
        // a function with a single argument, which is a pointer to an object
        // of (template parameter) type 'ARG'.  The 'sizeof' expression
        // provides an unevaluated context to check the validity of the
        // enclosed expression, and the ', 0' ensures that the 'sizeof' check
        // remains valid, even if the expression returns 'void'.  Similarly,
        // the cast to 'void' ensures that there are no surprises with types
        // that overload the comma operator.  Note that the cast to 'void' is
        // elided for Clang compilers using versions of LLVM prior to 12, which
        // fail to evaluate the trait properly.
};

#if defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1920
// Microsoft needs a workaround to correctly handle calling through function
// pointers with incompatible types in Visual Studio 2017.  In Visual Studio
// 2019 the workaround isn't needed and crashes the compiler if enabled!
// (Visual Studio versions prior to 2017 appear to not need the workaround,
// based on further testing, but it's being left in place so as not to alter
// this code for people using older compiler versions.)

template <class RESULT, class PARAM>
struct SharedPtr_TestIsCallable<RESULT(PARAM)> {
  private:
    // PRIVATE TYPES
    typedef BloombergLP::bslmf::Util Util;

    struct TrueType  { char d_padding; };
    struct FalseType { char d_padding[17]; };

    // PRIVATE CLASS METHODS
    static RESULT callMe(PARAM);

  public:
    // CLASS METHODS
    template <class ARG>
    static FalseType test(...);
    template <class ARG>
    static TrueType test(typename bsl::enable_if<(bool)sizeof(
                                        ((void)callMe(Util::declval<ARG>())), 0
                                                       )>::type *);
        // This function is never defined.  It provides a property-checker that
        // an entity of (template parameter) type 'FACTORY' can be called like
        // a function with a single argument, which is a pointer to an object
        // of (template parameter) type 'ARG'.  The 'sizeof' expression
        // provides an unevaluated context to check the validity of the
        // enclosed expression, and the ', 0' ensures that the 'sizeof' check
        // remains valid, even if the expression returns 'void'.  Similarly,
        // the cast to 'void' ensures that there are no surprises with types
        // that overload the comma operator.
};

template <class RESULT, class PARAM>
struct SharedPtr_TestIsCallable<RESULT(*)(PARAM)>
    :  SharedPtr_TestIsCallable<RESULT(PARAM)> {
};

template <class RESULT, class PARAM>
struct SharedPtr_TestIsCallable<RESULT(&)(PARAM)>
    :  SharedPtr_TestIsCallable<RESULT(PARAM)> {
};

#if BSLS_PLATFORM_CMP_VERSION >= 1910
// MSVC 2017 expression-SFINAE has a regression that is failing in two
// additional cases:
//  1) for pointers to object types
//  2) where '0' is used for a null pointer literal, deducing as 'int'.
// We resolve those issues with a couple more specializations below.

template <class TYPE>
struct SharedPtr_TestIsCallable<TYPE *> {
    struct TrueType  { char d_padding; };
    struct FalseType { char d_padding[17]; };

    template <class ARG>
    static FalseType test(...);
};

template <>
struct SharedPtr_TestIsCallable<int> {
    struct TrueType  { char d_padding; };
    struct FalseType { char d_padding[17]; };

    template <class ARG>
    static FalseType test(...);
};
#endif  // MSVC 2017

#endif  // BSLS_PLATFORM_CMP_MSVC

template <class FUNCTOR, class ARG>
struct SharedPtr_IsCallable {
    enum { k_VALUE =
          sizeof(SharedPtr_TestIsCallable<FUNCTOR>::template test<ARG>(0)) == 1
    };
};


struct SharedPtr_IsFactoryFor_Impl {
  private:
    // PRIVATE TYPES
    struct TrueType {
        char d_padding;
    };
    struct FalseType {
        char d_padding[17];
    };

  public:
    // CLASS METHODS
    template <class FACTORY, class ARG>
    static FalseType test(...);
    template <class FACTORY, class ARG>
    static TrueType test(typename bsl::enable_if<static_cast<bool>(sizeof(
                                  BSLSTL_SHAREDPTR_SFINAE_DISCARD(
                                      (*(FACTORY *)0)->deleteObject((ARG *)0)),
                                  0))>::type *);
        // This function is never defined.  It provides a property-checker that
        // an object of (template parameter) type 'FACTORY' has a
        // member-function called 'deleteObject' that can be called with a
        // single argument, which is a pointer to an object of (template
        // parameter) type 'ARG'.  The 'sizeof' expression provides an
        // unevaluated context to check the validity of the enclosed
        // expression, and the ', 0' ensures that the 'sizeof' check remains
        // valid, even if the expression returns 'void'.  Similarly, the cast
        // to 'void' ensures that there are no surprises with types that
        // overload the comma operator.  Note that the cast to 'void' is elided
        // for Clang compilers using versions of LLVM prior to 12, which fail
        // to evaluate the trait properly.
};

template <class FACTORY, class ARG>
struct SharedPtr_IsFactoryFor {
    enum { k_VALUE =
                sizeof(SharedPtr_IsFactoryFor_Impl::test<FACTORY, ARG>(0)) == 1
    };
};


struct SharedPtr_IsNullableFactory_Impl {
  private:
    // PRIVATE TYPES
    struct TrueType {
        char d_padding;
    };
    struct FalseType {
        char d_padding[17];
    };

  public:
    // CLASS METHODS
    template <class FACTORY>
    static FalseType test(...);
    template <class FACTORY>
    static TrueType test(typename bsl::enable_if<static_cast<bool>(sizeof(
                                   BSLSTL_SHAREDPTR_SFINAE_DISCARD(
                                       (*(FACTORY *)0)->deleteObject(nullptr)),
                                   0))>::type *);
        // This function is never defined.  It provides a property-checker that
        // an object of (template parameter) type 'FACTORY' has a
        // member-function called 'deleteObject' that can be called with a
        // single argument, which is a pointer to an object of (template
        // parameter) type 'ARG'.  The 'sizeof' expression provides an
        // unevaluated context to check the validity of the enclosed
        // expression, and the ', 0' ensures that the 'sizeof' check remains
        // valid, even if the expression returns 'void'.  Similarly, the cast
        // to 'void' ensures that there are no surprises with types that
        // overload the comma operator.  Note that the cast to 'void' is elided
        // for Clang compilers using versions of LLVM prior to 12, which fail
        // to evaluate the trait properly.
};

template <class FACTORY>
struct SharedPtr_IsNullableFactory {
    enum { k_VALUE =
                sizeof(SharedPtr_IsNullableFactory_Impl::test<FACTORY>(0)) == 1
    };
};


template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerConvertible_Impl
: bsl::is_convertible<SOURCE_TYPE *, DEST_TYPE *>::type {};

template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerConvertible_Impl<SOURCE_TYPE, DEST_TYPE[]>
: bsl::is_convertible<SOURCE_TYPE (*)[], DEST_TYPE (*)[]>::type {};

template <class SOURCE_TYPE, class DEST_TYPE, size_t DEST_SIZE>
struct SharedPtr_IsPointerConvertible_Impl<SOURCE_TYPE, DEST_TYPE[DEST_SIZE]>
: bsl::is_convertible<SOURCE_TYPE (*)[DEST_SIZE],
                      DEST_TYPE (*)[DEST_SIZE]>::type {};


template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerConvertible
: SharedPtr_IsPointerConvertible_Impl<SOURCE_TYPE, DEST_TYPE>::type {};


template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerCompatible_Impl
    : bsl::is_convertible<SOURCE_TYPE *, DEST_TYPE *>::type {};

template <class TYPE, size_t SIZE>
struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], TYPE[]>
     : bsl::true_type {};

template <class TYPE, size_t SIZE>
struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], const TYPE[]>
     : bsl::true_type {};

template <class TYPE, size_t SIZE>
struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], volatile TYPE[]>
     : bsl::true_type {};

template <class TYPE, size_t SIZE>
struct SharedPtr_IsPointerCompatible_Impl<TYPE[SIZE], const volatile TYPE[]>
     : bsl::true_type {};


template <class SOURCE_TYPE, class DEST_TYPE>
struct SharedPtr_IsPointerCompatible
: SharedPtr_IsPointerCompatible_Impl<SOURCE_TYPE, DEST_TYPE>::type {};

}  // close package namespace
}  // close enterprise namespace
#endif  // BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS


namespace bsl {
                    //------------------------------
                    // class enable_shared_from_this
                    //------------------------------
// CREATORS
template<class ELEMENT_TYPE>
inline // constexpr
enable_shared_from_this<ELEMENT_TYPE>::enable_shared_from_this()
                                                          BSLS_KEYWORD_NOEXCEPT
: d_weakThis()
{
}

template<class ELEMENT_TYPE>
inline
enable_shared_from_this<ELEMENT_TYPE>::enable_shared_from_this(
                                                const enable_shared_from_this&)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_weakThis()
{
}

template<class ELEMENT_TYPE>
inline
enable_shared_from_this<ELEMENT_TYPE>::~enable_shared_from_this()
{
}

// MANIPULATORS
template<class ELEMENT_TYPE>
inline
enable_shared_from_this<ELEMENT_TYPE>&
enable_shared_from_this<ELEMENT_TYPE>::operator=(
                                                const enable_shared_from_this&)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return *this;
}

template<class ELEMENT_TYPE>
inline
shared_ptr<ELEMENT_TYPE>
enable_shared_from_this<ELEMENT_TYPE>::shared_from_this()
{
    return shared_ptr<ELEMENT_TYPE>(d_weakThis);
}

template<class ELEMENT_TYPE>
inline
shared_ptr<const ELEMENT_TYPE>
enable_shared_from_this<ELEMENT_TYPE>::shared_from_this() const
{
    return shared_ptr<const ELEMENT_TYPE>(d_weakThis);
}

template<class ELEMENT_TYPE>
inline
weak_ptr<ELEMENT_TYPE>
enable_shared_from_this<ELEMENT_TYPE>::weak_from_this() BSLS_KEYWORD_NOEXCEPT
{
    return d_weakThis;
}

template<class ELEMENT_TYPE>
inline
weak_ptr<const ELEMENT_TYPE>
enable_shared_from_this<ELEMENT_TYPE>::weak_from_this() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return d_weakThis;
}

                            // ----------------
                            // class shared_ptr
                            // ----------------

// PRIVATE CLASS METHODS
template <class ELEMENT_TYPE>
template <class INPLACE_REP>
inline
BloombergLP::bslma::SharedPtrRep *
shared_ptr<ELEMENT_TYPE>::makeInternalRep(
                                         ELEMENT_TYPE                     *,
                                         INPLACE_REP                      *,
                                         BloombergLP::bslma::SharedPtrRep *rep)
{
    return rep;
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE, class ALLOCATOR>
inline
BloombergLP::bslma::SharedPtrRep *
shared_ptr<ELEMENT_TYPE>::makeInternalRep(
                                      COMPATIBLE_TYPE               *ptr,
                                      ALLOCATOR                     *,
                                      BloombergLP::bslma::Allocator *allocator)
{
    typedef BloombergLP::bslma::SharedPtrOutofplaceRep<
                                               COMPATIBLE_TYPE,
                                               BloombergLP::bslma::Allocator *>
                                                                      RepMaker;

    return RepMaker::makeOutofplaceRep(ptr, allocator, allocator);
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE, class DELETER>
inline
BloombergLP::bslma::SharedPtrRep *
shared_ptr<ELEMENT_TYPE>::makeInternalRep(COMPATIBLE_TYPE *ptr,
                                          DELETER         *deleter,
                                          ...)
{
    typedef BloombergLP::bslma::SharedPtrOutofplaceRep<COMPATIBLE_TYPE,
                                                       DELETER *>     RepMaker;

    return RepMaker::makeOutofplaceRep(ptr, deleter, 0);
}

// CREATORS
template <class ELEMENT_TYPE>
inline
BSLS_KEYWORD_CONSTEXPR
shared_ptr<ELEMENT_TYPE>::shared_ptr() BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(0)
, d_rep_p(0)
{
}

template <class ELEMENT_TYPE>
inline
BSLS_KEYWORD_CONSTEXPR
shared_ptr<ELEMENT_TYPE>::shared_ptr(bsl::nullptr_t) BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(0)
, d_rep_p(0)
{
}

template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(CONVERTIBLE_TYPE *ptr)
: d_ptr_p(ptr)
{
    typedef BloombergLP::bslstl::SharedPtr_DefaultDeleter<
                                   bsl::is_array<ELEMENT_TYPE>::value> Deleter;
    typedef BloombergLP::bslma::SharedPtrOutofplaceRep<CONVERTIBLE_TYPE,
                                                       Deleter>       RepMaker;

    d_rep_p = RepMaker::makeOutofplaceRep(ptr, Deleter(), 0);
    if (!bsl::is_array<ELEMENT_TYPE>::value) {
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
                                                                         this);
    }
}

template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                                 CONVERTIBLE_TYPE              *ptr,
                                 BloombergLP::bslma::Allocator *basicAllocator)
: d_ptr_p(ptr)
{
    typedef BloombergLP::bslma::SharedPtrOutofplaceRep<
                                               CONVERTIBLE_TYPE,
                                               BloombergLP::bslma::Allocator *>
                                                                      RepMaker;

    d_rep_p = RepMaker::makeOutofplaceRep(ptr, basicAllocator, basicAllocator);
    if (!bsl::is_array<ELEMENT_TYPE>::value) {
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
                                                                         this);
    }
}

template <class ELEMENT_TYPE>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(ELEMENT_TYPE                     *ptr,
                                     BloombergLP::bslma::SharedPtrRep *rep)
: d_ptr_p(ptr)
, d_rep_p(rep)
{
    BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
                                                                     this);
}

template <class ELEMENT_TYPE>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                       ELEMENT_TYPE                     *ptr,
                       BloombergLP::bslma::SharedPtrRep *rep,
                       BloombergLP::bslstl::SharedPtr_RepFromExistingSharedPtr)
: d_ptr_p(ptr)
, d_rep_p(rep)
{
}

template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE,
          class DISPATCH
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE
          BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(DISPATCH *, CONVERTIBLE_TYPE)>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(CONVERTIBLE_TYPE *ptr,
                                     DISPATCH         *dispatch)
: d_ptr_p(ptr)
, d_rep_p(makeInternalRep(ptr, dispatch, dispatch))
{
    if (!bsl::is_array<ELEMENT_TYPE>::value) {
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
                                                                         this);
    }
}

template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE,
          class DELETER
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE
          BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                                 CONVERTIBLE_TYPE              *ptr,
                                 DELETER                        deleter,
                                 BloombergLP::bslma::Allocator *basicAllocator)
: d_ptr_p(ptr)
{
    typedef BloombergLP::bslma::SharedPtrOutofplaceRep<CONVERTIBLE_TYPE,
                                                       DELETER> RepMaker;

    d_rep_p = RepMaker::makeOutofplaceRep(ptr, deleter, basicAllocator);
    if (!bsl::is_array<ELEMENT_TYPE>::value) {
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
                                                                         this);
    }
}

template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE,
          class DELETER,
          class ALLOCATOR
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE
          BSLSTL_SHAREDPTR_DEFINE_IF_DELETER(DELETER, CONVERTIBLE_TYPE)>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(CONVERTIBLE_TYPE *ptr,
                                     DELETER           deleter,
                                     ALLOCATOR         basicAllocator,
                                     typename ALLOCATOR::value_type *)
: d_ptr_p(ptr)
{
#ifdef BSLS_PLATFORM_CMP_MSVC
    // This is not quite C++11 'decay' as we do not need to worry about array
    // types, and do not want to remove reference or cv-qualification from
    // DELETER otherwise.  This works around a Microsoft bug turning function
    // pointers into function references.

    typedef typename bsl::conditional<bsl::is_function<DELETER>::value,
                                      typename bsl::add_pointer<DELETER>::type,
                                      DELETER>::type DeleterType;
#else
    typedef DELETER DeleterType;
#endif

    typedef
    BloombergLP::bslstl::SharedPtrAllocateOutofplaceRep<CONVERTIBLE_TYPE,
                                                        DeleterType,
                                                        ALLOCATOR> RepMaker;

    d_rep_p = RepMaker::makeOutofplaceRep(ptr, deleter, basicAllocator);
    if (!bsl::is_array<ELEMENT_TYPE>::value) {
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(ptr,
                                                                         this);
    }
}

template <class ELEMENT_TYPE>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(nullptr_t,
                                     BloombergLP::bslma::Allocator *)
: d_ptr_p(0)
, d_rep_p(0)
{
}

template <class ELEMENT_TYPE>
template <class DELETER
          BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(DELETER)>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                                 nullptr_t,
                                 DELETER                        deleter,
                                 BloombergLP::bslma::Allocator *basicAllocator)
: d_ptr_p(0)
{
    typedef BloombergLP::bslma::SharedPtrOutofplaceRep<ELEMENT_TYPE,
                                                       DELETER> RepMaker;

    if (bsl::is_convertible<DELETER, BloombergLP::bslma::Allocator *>::value &&
        bsl::is_pointer<DELETER>::value) {
        d_rep_p = 0;
    }
    else {
        d_rep_p = RepMaker::makeOutofplaceRep((ELEMENT_TYPE *)0,
                                              deleter,
                                              basicAllocator);
    }
}

template <class ELEMENT_TYPE>
template <class DELETER, class ALLOCATOR
          BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER(DELETER)>
inline
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                                nullptr_t,
                                DELETER                         deleter,
                                ALLOCATOR                       basicAllocator,
                                typename ALLOCATOR::value_type *)
: d_ptr_p(0)
{
#ifdef BSLS_PLATFORM_CMP_MSVC
    // This is not quite C++11 'decay' as we do not need to worry about array
    // types, and do not want to remove reference or cv-qualification from
    // DELETER otherwise.  This works around a Microsoft bug turning function
    // pointers into function references.

    typedef typename bsl::conditional<bsl::is_function<DELETER>::value,
                                      typename bsl::add_pointer<DELETER>::type,
                                      DELETER>::type DeleterType;
#else
    typedef DELETER DeleterType;
#endif

    typedef
    BloombergLP::bslstl::SharedPtrAllocateOutofplaceRep<ELEMENT_TYPE,
                                                        DeleterType,
                                                        ALLOCATOR> RepMaker;

    d_rep_p = RepMaker::makeOutofplaceRep((ELEMENT_TYPE *)0,
                                          deleter,
                                          basicAllocator);
}

template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(
              BloombergLP::bslma::ManagedPtr<CONVERTIBLE_TYPE>  managedPtr,
              BloombergLP::bslma::Allocator                    *basicAllocator)
: d_ptr_p(managedPtr.ptr())
, d_rep_p(0)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<
                            BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE> > Rep;

    if (d_ptr_p) {
        ELEMENT_TYPE *pPotentiallyShared = static_cast<ELEMENT_TYPE *>(
                                                managedPtr.deleter().object());

        if (&BloombergLP::bslma::SharedPtrRep::managedPtrDeleter ==
                                              managedPtr.deleter().deleter()) {
            d_rep_p = static_cast<BloombergLP::bslma::SharedPtrRep *>
                                       (managedPtr.release().second.factory());
        }
        else if (&BloombergLP::bslma::SharedPtrRep::managedPtrEmptyDeleter ==
                                              managedPtr.deleter().deleter()) {
            d_rep_p = 0;
            managedPtr.release();
        }
        else {
            basicAllocator =
                        BloombergLP::bslma::Default::allocator(basicAllocator);
            Rep *rep = new (*basicAllocator) Rep(basicAllocator);
            (*rep->ptr()) = managedPtr;
            d_rep_p = rep;
        }

        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
                                                            pPotentiallyShared,
                                                            this);
    }
}

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                              std::auto_ptr<CONVERTIBLE_TYPE>&  autoPtr,
                              BloombergLP::bslma::Allocator    *basicAllocator)
: d_ptr_p(autoPtr.get())
, d_rep_p(0)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<
                                         std::auto_ptr<CONVERTIBLE_TYPE> > Rep;

    if (d_ptr_p) {
        basicAllocator =
                        BloombergLP::bslma::Default::allocator(basicAllocator);
        Rep *rep = new (*basicAllocator) Rep(basicAllocator);
        (*rep->ptr()) = autoPtr;
        d_rep_p = rep;
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
                                                                       d_ptr_p,
                                                                       this);
    }
}

template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                               std::auto_ptr_ref<ELEMENT_TYPE>  autoRef,
                               BloombergLP::bslma::Allocator   *basicAllocator)
: d_ptr_p(0)
, d_rep_p(0)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<
                                             std::auto_ptr<ELEMENT_TYPE> > Rep;

    std::auto_ptr<ELEMENT_TYPE> autoPtr(autoRef);
    if (autoPtr.get()) {
        basicAllocator =
                        BloombergLP::bslma::Default::allocator(basicAllocator);
        Rep *rep = new (*basicAllocator) Rep(basicAllocator);
        d_ptr_p = autoPtr.get();
        (*rep->ptr()) = autoPtr;
        d_rep_p = rep;
    }
}
#endif

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
# if defined(BSLSTL_SHAREDPTR_SUPPORTS_SFINAE_CHECKS)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE,
          class UNIQUE_DELETER,
          typename enable_if<is_convertible<
                      typename std::unique_ptr<COMPATIBLE_TYPE,
                                               UNIQUE_DELETER>::pointer,
                      ELEMENT_TYPE *>::value>::type *>
shared_ptr<ELEMENT_TYPE>::shared_ptr(
            std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>&&  adoptee,
            BloombergLP::bslma::Allocator                      *basicAllocator)
: d_ptr_p(adoptee.get())
, d_rep_p(0)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<
                        std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER> > Rep;

    if (d_ptr_p) {
        basicAllocator =
                        BloombergLP::bslma::Default::allocator(basicAllocator);
        Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                            BloombergLP::bslmf::MovableRefUtil::move(adoptee));
        d_rep_p = rep;
        BloombergLP::bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(
                                                                       d_ptr_p,
                                                                       this);
    }
}
# endif
#endif

template <class ELEMENT_TYPE>
template <class ANY_TYPE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(const shared_ptr<ANY_TYPE>&  source,
                                     ELEMENT_TYPE                *object)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(object)
, d_rep_p(source.d_rep_p)
{
    if (d_rep_p) {
        d_rep_p->acquireRef();
    }
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
shared_ptr<ELEMENT_TYPE>::
shared_ptr(const shared_ptr<COMPATIBLE_TYPE>& other) BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(other.d_ptr_p)
, d_rep_p(other.d_rep_p)
{
    if (d_rep_p) {
        d_rep_p->acquireRef();
    }
}

template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(const shared_ptr& original)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(original.d_ptr_p)
, d_rep_p(original.d_rep_p)
{
    if (d_rep_p) {
        d_rep_p->acquireRef();
    }
}

template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>::shared_ptr
                          (BloombergLP::bslmf::MovableRef<shared_ptr> original)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_ptr_p)
, d_rep_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p)
{
    BloombergLP::bslmf::MovableRefUtil::access(original).d_ptr_p = 0;
    BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p = 0;
}

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(shared_ptr<COMPATIBLE_TYPE>&& other)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(other.d_ptr_p)
, d_rep_p(other.d_rep_p)
{
    other.d_ptr_p = 0;
    other.d_rep_p = 0;
}
#else
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
shared_ptr<ELEMENT_TYPE>::
shared_ptr(BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > other)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(BloombergLP::bslmf::MovableRefUtil::access(other).d_ptr_p)
, d_rep_p(BloombergLP::bslmf::MovableRefUtil::access(other).d_rep_p)
{
    BloombergLP::bslmf::MovableRefUtil::access(other).d_ptr_p = 0;
    BloombergLP::bslmf::MovableRefUtil::access(other).d_rep_p = 0;
}
#endif

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(const weak_ptr<COMPATIBLE_TYPE>& other)
: d_ptr_p(0)
, d_rep_p(0)
{
    // This implementation handles two awkward cases:
    //
    // i) a ref-counted null pointer, means we cannot simply test 'if (!value)'
    // ii) a null pointer aliasing a non-null pointer is still expired, and so
    //     should throw.

    SelfType value = other.lock();
    if (other.expired()) {
        // Test after lock to avoid a race between testing 'expired' and
        // claiming the lock.

        BloombergLP::bslstl::SharedPtr_ImpUtil::throwBadWeakPtr();
    }

    swap(value);
}

#if !defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
shared_ptr<ELEMENT_TYPE>::shared_ptr(
                BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > ptr)
: d_ptr_p(0)
, d_rep_p(0)
{
    // This implementation handles two awkward cases:
    //
    // i) a ref-counted null pointer, means we cannot simply test 'if (!value)'
    // ii) a null pointer aliasing a non-null pointer is still expired, and so
    //     should throw.

    weak_ptr<COMPATIBLE_TYPE>& other = ptr;

    SelfType value = other.lock();
    if (other.expired()) {
        // Test after lock to avoid a race between testing 'expired' and
        // claiming the lock.

        BloombergLP::bslstl::SharedPtr_ImpUtil::throwBadWeakPtr();
    }

    swap(value);
}
#endif

template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>::~shared_ptr()
{
    if (d_rep_p) {
        d_rep_p->releaseRef();
    }
}

// MANIPULATORS
template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>&
shared_ptr<ELEMENT_TYPE>::operator=(const shared_ptr& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    // Instead of testing '&rhs == this', which happens infrequently, optimize
    // for when reps are the same.

    if (rhs.d_rep_p == d_rep_p) {
        d_ptr_p = rhs.d_ptr_p;
    }
    else {
        SelfType(rhs).swap(*this);
    }

    return *this;
}

template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>&
shared_ptr<ELEMENT_TYPE>::operator=(
                                BloombergLP::bslmf::MovableRef<shared_ptr> rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    // No self-assignment to optimize, postcondition demands 'rhs' is left
    // empty, unless it is the exact same object, not just the same 'rep'.

    shared_ptr(BloombergLP::bslmf::MovableRefUtil::move(rhs)).swap(*this);

    return *this;
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    shared_ptr<ELEMENT_TYPE>&>::type
shared_ptr<ELEMENT_TYPE>::operator=(const shared_ptr<COMPATIBLE_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    // Instead of testing '&rhs == this', which happens infrequently, optimize
    // for when reps are the same.

    if (rhs.d_rep_p == d_rep_p) {
        d_ptr_p = rhs.d_ptr_p;
    }
    else {
        SelfType(rhs).swap(*this);
    }

    return *this;
}

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
                   shared_ptr<ELEMENT_TYPE>&>::type
shared_ptr<ELEMENT_TYPE>::operator=(shared_ptr<COMPATIBLE_TYPE>&& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
#else
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
                   shared_ptr<ELEMENT_TYPE>&>::type
shared_ptr<ELEMENT_TYPE>::operator=(
              BloombergLP::bslmf::MovableRef<shared_ptr<COMPATIBLE_TYPE> > rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
#endif
{
    // No self-assignment to optimize, postcondition demands 'rhs' is left
    // empty, unless it is the exact same object, not just the same 'rep'.

    shared_ptr(BloombergLP::bslmf::MovableRefUtil::move(rhs)).swap(*this);

    return *this;
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
inline
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    shared_ptr<ELEMENT_TYPE>&>::type
shared_ptr<ELEMENT_TYPE>::operator=(
                           BloombergLP::bslma::ManagedPtr<COMPATIBLE_TYPE> rhs)
{
    SelfType(rhs).swap(*this);
    return *this;
}

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP98_AUTO_PTR)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
inline
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    shared_ptr<ELEMENT_TYPE>&>::type
shared_ptr<ELEMENT_TYPE>::operator=(std::auto_ptr<COMPATIBLE_TYPE> rhs)
{
    SelfType(rhs).swap(*this);
    return *this;
}
#endif

#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_UNIQUE_PTR)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE, class UNIQUE_DELETER>
inline
typename enable_if<
    is_convertible<
        typename std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>::pointer,
        ELEMENT_TYPE *>::value,
    shared_ptr<ELEMENT_TYPE>&>::type
shared_ptr<ELEMENT_TYPE>::operator=(
                        std::unique_ptr<COMPATIBLE_TYPE, UNIQUE_DELETER>&& rhs)
{
    SelfType(BloombergLP::bslmf::MovableRefUtil::move(rhs)).swap(*this);
    return *this;
}
#endif

template <class ELEMENT_TYPE>
inline
void shared_ptr<ELEMENT_TYPE>::reset() BSLS_KEYWORD_NOEXCEPT
{
    BloombergLP::bslma::SharedPtrRep *rep = d_rep_p;

    // Clear 'd_rep_p' first so that a self-referencing shared pointer's
    // destructor does not try to call 'releaseRef' again.

    d_rep_p = 0;
    d_ptr_p = 0;

    if (rep) {
        rep->releaseRef();
    }
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
inline
typename
      enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
shared_ptr<ELEMENT_TYPE>::reset(COMPATIBLE_TYPE *ptr)
{
    SelfType(ptr).swap(*this);
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE, class DELETER>
inline
typename
      enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
shared_ptr<ELEMENT_TYPE>::reset(COMPATIBLE_TYPE *ptr,
                                DELETER          deleter)
{
    SelfType(ptr, deleter).swap(*this);
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE, class DELETER, class ALLOCATOR>
inline
typename
      enable_if<is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value>::type
shared_ptr<ELEMENT_TYPE>::reset(COMPATIBLE_TYPE *ptr,
                                DELETER          deleter,
                                ALLOCATOR        basicAllocator)
{
    SelfType(ptr, deleter, basicAllocator).swap(*this);
}

template <class ELEMENT_TYPE>
template <class ANY_TYPE>
inline
void shared_ptr<ELEMENT_TYPE>::reset(const shared_ptr<ANY_TYPE>&  source,
                                     ELEMENT_TYPE                *ptr)
{
    // Optimize for the (expected) common case where aliases are managing the
    // same data structure.

    if (source.d_rep_p == d_rep_p && ptr) {
        d_ptr_p = ptr;
    }
    else {
        SelfType(source, ptr).swap(*this);
    }
}

template <class ELEMENT_TYPE>
inline
void shared_ptr<ELEMENT_TYPE>::swap(shared_ptr& other) BSLS_KEYWORD_NOEXCEPT
{
    // We directly implement swapping of two pointers, rather than simply
    // calling 'bsl::swap' or using 'bslalg::SwapUtil', to avoid (indirectly)
    // including the platform <algorithm> header, which may transitively
    // include other standard headers.  This reduces the risk of
    // platform-specific cycles, which have been observed to cause problems.

    // Also, as 'shared_ptr' is bitwise-moveable, we could simplify this to
    // 'memcpy'-ing through an (aligned?) array of sufficient 'char'.

    ELEMENT_TYPE *tempPtr_p = d_ptr_p;
    d_ptr_p       = other.d_ptr_p;
    other.d_ptr_p = tempPtr_p;

    BloombergLP::bslma::SharedPtrRep *tempRep_p = d_rep_p;
    d_rep_p       = other.d_rep_p;
    other.d_rep_p = tempRep_p;
}

// ADDITIONAL BSL MANIPULATORS
template<class ELEMENT_TYPE>
void
shared_ptr<ELEMENT_TYPE>::createInplace()
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    BloombergLP::bslma::Allocator *basicAllocator =
                                      BloombergLP::bslma::Default::allocator();

    Rep *rep = new (*basicAllocator) Rep(basicAllocator);
    SelfType(rep->ptr(), rep).swap(*this);
}

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_sharedptr.h
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT 14
#endif
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#endif
#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 0
template <class ELEMENT_TYPE>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator);
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 1
template <class ELEMENT_TYPE>
template <class ARGS_01>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 2
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 3
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 4
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 5
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 6
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 7
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 8
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 9
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 10
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 11
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10,
          class ARGS_11>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 12
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10,
          class ARGS_11,
          class ARGS_12>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 13
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10,
          class ARGS_11,
          class ARGS_12,
          class ARGS_13>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_13,args_13));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 14
template <class ELEMENT_TYPE>
template <class ARGS_01,
          class ARGS_02,
          class ARGS_03,
          class ARGS_04,
          class ARGS_05,
          class ARGS_06,
          class ARGS_07,
          class ARGS_08,
          class ARGS_09,
          class ARGS_10,
          class ARGS_11,
          class ARGS_12,
          class ARGS_13,
          class ARGS_14>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_13,args_13),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_14,args_14));
    SelfType(rep->ptr(), rep).swap(*this);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_C >= 14

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class ELEMENT_TYPE>
template <class... ARGS>
void
shared_ptr<ELEMENT_TYPE>::createInplace(
                                 BloombergLP::bslma::Allocator *basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    typedef BloombergLP::bslma::SharedPtrInplaceRep<ELEMENT_TYPE> Rep;

    basicAllocator = BloombergLP::bslma::Default::allocator(basicAllocator);
    Rep *rep = new (*basicAllocator) Rep(basicAllocator,
                                  BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);
    SelfType(rep->ptr(), rep).swap(*this);
}
// }}} END GENERATED CODE
#endif

template <class ELEMENT_TYPE>
template <class ANY_TYPE>
void
shared_ptr<ELEMENT_TYPE>::loadAlias(const shared_ptr<ANY_TYPE>&  source,
                                    ELEMENT_TYPE                *object)
{
    if (source.d_rep_p == d_rep_p && object) {
        d_ptr_p = object;
    }
    else {
        SelfType(source, object).swap(*this);
    }
}

template <class ELEMENT_TYPE>
pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *>
shared_ptr<ELEMENT_TYPE>::release() BSLS_KEYWORD_NOEXCEPT
{
    pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *> ret(d_ptr_p,
                                                                 d_rep_p);
    d_ptr_p = 0;
    d_rep_p = 0;
    return ret;
}

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
// DEPRECATED BDE LEGACY MANIPULATORS
template <class ELEMENT_TYPE>
inline
void shared_ptr<ELEMENT_TYPE>::clear() BSLS_KEYWORD_NOEXCEPT
{
    reset();
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
inline
void shared_ptr<ELEMENT_TYPE>::load(COMPATIBLE_TYPE *ptr)
{
    SelfType(ptr).swap(*this);
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
inline
void
shared_ptr<ELEMENT_TYPE>::load(COMPATIBLE_TYPE               *ptr,
                               BloombergLP::bslma::Allocator *basicAllocator)
{
    SelfType(ptr, basicAllocator).swap(*this);
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE, class DELETER>
inline
void
shared_ptr<ELEMENT_TYPE>::load(COMPATIBLE_TYPE               *ptr,
                               const DELETER&                 deleter,
                               BloombergLP::bslma::Allocator *basicAllocator)
{
    SelfType(ptr, deleter, basicAllocator).swap(*this);
}
#endif // BDE_OMIT_INTERNAL_DEPRECATED

// ACCESSORS
template <class ELEMENT_TYPE>
inline
# if defined(BSLS_PLATFORM_CMP_IBM)     // Last tested with xlC 12.1
shared_ptr<ELEMENT_TYPE>::operator typename shared_ptr::BoolType() const
                                                          BSLS_KEYWORD_NOEXCEPT
# else
shared_ptr<ELEMENT_TYPE>::operator BoolType() const BSLS_KEYWORD_NOEXCEPT
# endif
{
    return BloombergLP::bsls::UnspecifiedBool<shared_ptr>::makeValue(d_ptr_p);
}

template <class ELEMENT_TYPE>
inline
typename add_lvalue_reference<ELEMENT_TYPE>::type
shared_ptr<ELEMENT_TYPE>::operator*() const BSLS_KEYWORD_NOEXCEPT
{
    BSLS_ASSERT_SAFE(d_ptr_p);

    return *d_ptr_p;
}

template <class ELEMENT_TYPE>
inline
ELEMENT_TYPE *shared_ptr<ELEMENT_TYPE>::operator->() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return d_ptr_p;
}

template <class ELEMENT_TYPE>
inline
typename shared_ptr<ELEMENT_TYPE>::element_type *
shared_ptr<ELEMENT_TYPE>::get() const BSLS_KEYWORD_NOEXCEPT
{
    return d_ptr_p;
}

template <class ELEMENT_TYPE>
inline typename
add_lvalue_reference<typename shared_ptr<ELEMENT_TYPE>::element_type>::type
shared_ptr<ELEMENT_TYPE>::operator[](ptrdiff_t index) const
{
    BSLS_ASSERT_SAFE(d_ptr_p);

    return *(d_ptr_p + index);
}

template <class ELEMENT_TYPE>
template<class ANY_TYPE>
inline
bool shared_ptr<ELEMENT_TYPE>::owner_before(const shared_ptr<ANY_TYPE>& other)
                                                    const BSLS_KEYWORD_NOEXCEPT
{
    return std::less<BloombergLP::bslma::SharedPtrRep *>()(rep(), other.rep());
}

template <class ELEMENT_TYPE>
template<class ANY_TYPE>
inline
bool
shared_ptr<ELEMENT_TYPE>::owner_before(const weak_ptr<ANY_TYPE>& other) const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<BloombergLP::bslma::SharedPtrRep *>()(rep(), other.rep());
}

template <class ELEMENT_TYPE>
inline
bool shared_ptr<ELEMENT_TYPE>::unique() const BSLS_KEYWORD_NOEXCEPT
{
    return 1 == use_count();
}

template <class ELEMENT_TYPE>
inline
long shared_ptr<ELEMENT_TYPE>::use_count() const BSLS_KEYWORD_NOEXCEPT
{
    return d_rep_p ? d_rep_p->numReferences() : 0;
}

// ADDITIONAL BSL ACCESSORS
template <class ELEMENT_TYPE>
BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE>::managedPtr() const
{
    if (d_rep_p && d_ptr_p) {
        d_rep_p->acquireRef();
        return BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>(d_ptr_p,
                                                            d_rep_p,
                         &BloombergLP::bslma::SharedPtrRep::managedPtrDeleter);
                                                                      // RETURN
    }

    return BloombergLP::bslma::ManagedPtr<ELEMENT_TYPE>(
                     d_ptr_p,
                    (BloombergLP::bslma::SharedPtrRep *)0,
                    &BloombergLP::bslma::SharedPtrRep::managedPtrEmptyDeleter);
}

template <class ELEMENT_TYPE>
inline
BloombergLP::bslma::SharedPtrRep *shared_ptr<ELEMENT_TYPE>::rep() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return d_rep_p;
}

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
// DEPRECATED BDE LEGACY ACCESSORS
template <class ELEMENT_TYPE>
inline
int shared_ptr<ELEMENT_TYPE>::numReferences() const BSLS_KEYWORD_NOEXCEPT
{
    return d_rep_p ? d_rep_p->numReferences() : 0;
}

template <class ELEMENT_TYPE>
inline
ELEMENT_TYPE *shared_ptr<ELEMENT_TYPE>::ptr() const BSLS_KEYWORD_NOEXCEPT
{
    return d_ptr_p;
}
#endif // BDE_OMIT_INTERNAL_DEPRECATED

                        // --------------
                        // class weak_ptr
                        // --------------

// CREATORS
template <class ELEMENT_TYPE>
inline
BSLS_KEYWORD_CONSTEXPR
weak_ptr<ELEMENT_TYPE>::weak_ptr() BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(0)
, d_rep_p(0)
{
}

template <class ELEMENT_TYPE>
weak_ptr<ELEMENT_TYPE>::weak_ptr(
         BloombergLP::bslmf::MovableRef<weak_ptr> original)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_ptr_p)
, d_rep_p(BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p)
{
    BloombergLP::bslmf::MovableRefUtil::access(original).d_rep_p = 0;
//    original.d_ptr_p = 0; // this seems overkill for a /weak/ pointer
}

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
weak_ptr<ELEMENT_TYPE>::weak_ptr(weak_ptr<COMPATIBLE_TYPE>&& original)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(original.d_ptr_p)
, d_rep_p(original.d_rep_p)
{
    original.d_rep_p = 0;
//    original.d_ptr_p = 0; // this seems overkill for a /weak/ pointer
}
#else
template <class ELEMENT_TYPE>
template <class CONVERTIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE>
weak_ptr<ELEMENT_TYPE>::weak_ptr(
          BloombergLP::bslmf::MovableRef<weak_ptr<CONVERTIBLE_TYPE> > original)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(original.d_ptr_p)
, d_rep_p(original.d_rep_p)
{
    original.d_rep_p = 0;
//    original.d_ptr_p = 0; // this seems overkill for a /weak/ pointer
}
#endif

template <class ELEMENT_TYPE>
weak_ptr<ELEMENT_TYPE>::weak_ptr(const weak_ptr<ELEMENT_TYPE>& original)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(original.d_ptr_p)
, d_rep_p(original.d_rep_p)
{
    if (d_rep_p) {
        d_rep_p->acquireWeakRef();
    }
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
weak_ptr<ELEMENT_TYPE>::weak_ptr(const shared_ptr<COMPATIBLE_TYPE>& other)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(other.get())
, d_rep_p(other.rep())
{
    if (d_rep_p) {
        d_rep_p->acquireWeakRef();
    }
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE
          BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE>
weak_ptr<ELEMENT_TYPE>::weak_ptr(const weak_ptr<COMPATIBLE_TYPE>& other)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_ptr_p(other.d_ptr_p)
, d_rep_p(other.d_rep_p)
{
    if (d_rep_p) {
        d_rep_p->acquireWeakRef();
    }
}

template <class ELEMENT_TYPE>
inline
weak_ptr<ELEMENT_TYPE>::~weak_ptr()
{
    if (d_rep_p) {
        d_rep_p->releaseWeakRef();
    }
}

// PRIVATE MANIPULATORS
template <class ELEMENT_TYPE>
inline
void weak_ptr<ELEMENT_TYPE>::privateAssign(
                                      BloombergLP::bslma::SharedPtrRep *rep,
                                      ELEMENT_TYPE                     *target)
{
    if (d_rep_p) {
        d_rep_p->releaseWeakRef();
    }

    d_ptr_p = target;
    d_rep_p = rep;
    d_rep_p->acquireWeakRef();
}

// MANIPULATORS
template <class ELEMENT_TYPE>
weak_ptr<ELEMENT_TYPE>& weak_ptr<ELEMENT_TYPE>::operator=(
                                  BloombergLP::bslmf::MovableRef<weak_ptr> rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    weak_ptr tmp(BloombergLP::bslmf::MovableRefUtil::move(rhs));
    tmp.swap(*this);
    return *this;
}

#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    weak_ptr<ELEMENT_TYPE>&>::type
weak_ptr<ELEMENT_TYPE>::operator=(weak_ptr<COMPATIBLE_TYPE>&& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    weak_ptr tmp(BloombergLP::bslmf::MovableRefUtil::move(rhs));
    tmp.swap(*this);
    return *this;
}
#else
template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    weak_ptr<ELEMENT_TYPE>&>::type
weak_ptr<ELEMENT_TYPE>::operator=(
                BloombergLP::bslmf::MovableRef<weak_ptr<COMPATIBLE_TYPE> > rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    weak_ptr tmp(BloombergLP::bslmf::MovableRefUtil::move(rhs));
    tmp.swap(*this);
    return *this;
}
#endif

template <class ELEMENT_TYPE>
weak_ptr<ELEMENT_TYPE>& weak_ptr<ELEMENT_TYPE>::operator=(
                                             const weak_ptr<ELEMENT_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
#if 1
    weak_ptr tmp(rhs);
    tmp.swap(*this);
#else
    // needs friendship, or use the cheating util class.
    privateAssign(rhs.d_rep_p, rhs.d_ptr_p);
#endif
    return *this;
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    weak_ptr<ELEMENT_TYPE>&>::type
weak_ptr<ELEMENT_TYPE>::operator=(const shared_ptr<COMPATIBLE_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
#if 1
    weak_ptr tmp(rhs);
    tmp.swap(*this);
#else
    // needs friendship, or use the cheating util class.
    privateAssign(rhs.d_rep_p, rhs.d_ptr_p);
#endif
    return *this;
}

template <class ELEMENT_TYPE>
template <class COMPATIBLE_TYPE>
typename enable_if<
    is_convertible<COMPATIBLE_TYPE *, ELEMENT_TYPE *>::value,
    weak_ptr<ELEMENT_TYPE>&>::type
weak_ptr<ELEMENT_TYPE>::operator=(const weak_ptr<COMPATIBLE_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
#if 1
    weak_ptr tmp(rhs);
    tmp.swap(*this);
#else
    // needs friendship, or use the cheating util class.
    privateAssign(rhs.d_rep_p, rhs.d_ptr_p);
#endif
    return *this;
}

template <class ELEMENT_TYPE>
inline
void weak_ptr<ELEMENT_TYPE>::reset() BSLS_KEYWORD_NOEXCEPT
{
    if (d_rep_p) {
        d_rep_p->releaseWeakRef();
    }

    d_ptr_p = 0;
    d_rep_p = 0;
}

template <class ELEMENT_TYPE>
inline
void weak_ptr<ELEMENT_TYPE>::swap(weak_ptr<ELEMENT_TYPE>& other)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    // We directly implement swapping of two pointers, rather than simply
    // calling 'bsl::swap' or using 'bslalg::SwapUtil', to avoid (indirectly)
    // including the platform <algorithm> header, which may transitively
    // include other standard headers.  This reduces the risk of
    // platform-specific cycles, which have been observed to cause problems.

    ELEMENT_TYPE *tempPtr_p = d_ptr_p;
    d_ptr_p       = other.d_ptr_p;
    other.d_ptr_p = tempPtr_p;

    BloombergLP::bslma::SharedPtrRep *tempRep_p = d_rep_p;
    d_rep_p       = other.d_rep_p;
    other.d_rep_p = tempRep_p;
}

// ACCESSORS
template <class ELEMENT_TYPE>
inline
bool weak_ptr<ELEMENT_TYPE>::expired() const BSLS_KEYWORD_NOEXCEPT
{
    return !(d_rep_p && d_rep_p->numReferences());
}

template <class ELEMENT_TYPE>
shared_ptr<ELEMENT_TYPE> weak_ptr<ELEMENT_TYPE>::lock() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    if (d_rep_p && d_rep_p->tryAcquireRef()) {
        return shared_ptr<ELEMENT_TYPE>(
                    d_ptr_p,
                    d_rep_p,
                    BloombergLP::bslstl::SharedPtr_RepFromExistingSharedPtr());
                                                                      // RETURN
    }
    return shared_ptr<ELEMENT_TYPE>();
}

template <class ELEMENT_TYPE>
template <class ANY_TYPE>
inline
bool
weak_ptr<ELEMENT_TYPE>::owner_before(const shared_ptr<ANY_TYPE>& other) const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<BloombergLP::bslma::SharedPtrRep *>()(d_rep_p,
                                                           other.rep());
}

template <class ELEMENT_TYPE>
template <class ANY_TYPE>
inline
bool
weak_ptr<ELEMENT_TYPE>::owner_before(const weak_ptr<ANY_TYPE>& other) const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<BloombergLP::bslma::SharedPtrRep *>()(d_rep_p,
                                                           other.d_rep_p);
}

template <class ELEMENT_TYPE>
inline
BloombergLP::bslma::SharedPtrRep *weak_ptr<ELEMENT_TYPE>::rep() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return d_rep_p;
}

template <class ELEMENT_TYPE>
inline
long weak_ptr<ELEMENT_TYPE>::use_count() const BSLS_KEYWORD_NOEXCEPT
{
    return d_rep_p ? d_rep_p->numReferences() : 0;
}

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
// DEPRECATED BDE LEGACY ACCESSORS
template <class ELEMENT_TYPE>
inline
shared_ptr<ELEMENT_TYPE> weak_ptr<ELEMENT_TYPE>::acquireSharedPtr() const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return lock();
}

template <class ELEMENT_TYPE>
inline
int weak_ptr<ELEMENT_TYPE>::numReferences() const BSLS_KEYWORD_NOEXCEPT
{
    return d_rep_p ? d_rep_p->numReferences() : 0;
}
#endif // BDE_OMIT_INTERNAL_DEPRECATED

}  // close namespace bsl

namespace BloombergLP {
namespace bslstl {

                            // -----------------
                            // SharedPtr_ImpUtil
                            // -----------------

template <class SHARED_TYPE, class ENABLE_TYPE>
inline
void SharedPtr_ImpUtil::loadEnableSharedFromThis(
                    const bsl::enable_shared_from_this<ENABLE_TYPE> *result,
                    bsl::shared_ptr<SHARED_TYPE>                    *sharedPtr)
{
    BSLS_ASSERT(0 != sharedPtr);

    if (0 != result && result->d_weakThis.expired()) {
        result->d_weakThis.privateAssign(
                         sharedPtr->d_rep_p,
                         const_cast <ENABLE_TYPE      *>(
                         static_cast<ENABLE_TYPE const*>(sharedPtr->d_ptr_p)));
    }
}

inline
void bslstl::SharedPtr_ImpUtil::loadEnableSharedFromThis(const volatile void *,
                                                         const void *)
                                                          BSLS_KEYWORD_NOEXCEPT
{
}

template <class TYPE>
inline
TYPE *SharedPtr_ImpUtil::unqualify(const volatile TYPE *address)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return const_cast<TYPE *>(address);
}

template <class TYPE>
inline
void *SharedPtr_ImpUtil::voidify(TYPE *address) BSLS_KEYWORD_NOEXCEPT
{
    return static_cast<void *>(
            const_cast<typename bsl::remove_cv<TYPE>::type *>(address));
}

                            // --------------------
                            // struct SharedPtrUtil
                            // --------------------

// CLASS METHODS
template <class TARGET, class SOURCE>
inline
void SharedPtrUtil::constCast(bsl::shared_ptr<TARGET>        *target,
                              const bsl::shared_ptr<SOURCE>&  source)
{
    BSLS_ASSERT(0 != target);

    target->reset(source, const_cast<TARGET *>(source.get()));
}

template <class TARGET, class SOURCE>
inline
bsl::shared_ptr<TARGET>
SharedPtrUtil::constCast(const bsl::shared_ptr<SOURCE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return bsl::shared_ptr<TARGET>(source,
                                   const_cast<TARGET *>(source.get()));
}

template <class TARGET, class SOURCE>
inline
void SharedPtrUtil::dynamicCast(bsl::shared_ptr<TARGET>        *target,
                                const bsl::shared_ptr<SOURCE>&  source)
{
    BSLS_ASSERT(0 != target);

    if (TARGET *castPtr = dynamic_cast<TARGET *>(source.get())) {
        target->reset(source, castPtr);
    }
    else {
        target->reset();
    }
}

template <class TARGET, class SOURCE>
inline
bsl::shared_ptr<TARGET>
SharedPtrUtil::dynamicCast(const bsl::shared_ptr<SOURCE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    if (TARGET *castPtr = dynamic_cast<TARGET *>(source.get())) {
        return bsl::shared_ptr<TARGET>(source, castPtr);              // RETURN
    }

    return bsl::shared_ptr<TARGET>();
}

template <class TARGET, class SOURCE>
inline
void SharedPtrUtil::staticCast(bsl::shared_ptr<TARGET>        *target,
                               const bsl::shared_ptr<SOURCE>&  source)
{
    BSLS_ASSERT(0 != target);

    target->reset(source, static_cast<TARGET *>(source.get()));
}

template <class TARGET, class SOURCE>
inline
bsl::shared_ptr<TARGET>
SharedPtrUtil::staticCast(const bsl::shared_ptr<SOURCE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return bsl::shared_ptr<TARGET>(source,
                                   static_cast<TARGET *>(source.get()));
}

                        // --------------------------
                        // struct SharedPtrNilDeleter
                        // --------------------------

// ACCESSORS
inline
void SharedPtrNilDeleter::operator()(const volatile void *) const
                                                          BSLS_KEYWORD_NOEXCEPT
{
}

                        // -------------------------------
                        // struct SharedPtr_DefaultDeleter
                        // -------------------------------

// ACCESSORS
template <>
template <class ANY_TYPE>
inline
void SharedPtr_DefaultDeleter<true>::operator()(ANY_TYPE *ptr) const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    delete [] ptr;
}

template <>
template <class ANY_TYPE>
inline
void SharedPtr_DefaultDeleter<false>::operator()(ANY_TYPE *ptr) const
                                                          BSLS_KEYWORD_NOEXCEPT
{
    delete ptr;
}

                        // --------------------------
                        // class SharedPtr_RepProctor
                        // --------------------------

// CREATORS
inline
SharedPtr_RepProctor::SharedPtr_RepProctor(bslma::SharedPtrRep *rep)
                                                          BSLS_KEYWORD_NOEXCEPT
: d_rep_p(rep)
{
}

inline
SharedPtr_RepProctor::~SharedPtr_RepProctor()
{
    if (d_rep_p) {
        d_rep_p->disposeRep();
    }
}

// MANIPULATORS
inline
void SharedPtr_RepProctor::release() BSLS_KEYWORD_NOEXCEPT
{
    d_rep_p = 0;
}

}  // close package namespace
}  // close enterprise namespace

// FREE OPERATORS
template <class LHS_TYPE, class RHS_TYPE>
inline
bool bsl::operator==(const shared_ptr<LHS_TYPE>& lhs,
                     const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    return lhs.get() == rhs.get();
}

template <class LHS_TYPE, class RHS_TYPE>
inline
bool bsl::operator!=(const shared_ptr<LHS_TYPE>& lhs,
                     const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    return !(lhs == rhs);
}

template <class LHS_TYPE, class RHS_TYPE>
inline
bool bsl::operator<(const shared_ptr<LHS_TYPE>& lhs,
                    const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    return std::less<const void *>()(lhs.get(), rhs.get());
}

template <class LHS_TYPE, class RHS_TYPE>
inline
bool bsl::operator>(const shared_ptr<LHS_TYPE>& lhs,
                    const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    return rhs < lhs;
}

template <class LHS_TYPE, class RHS_TYPE>
inline
bool bsl::operator<=(const shared_ptr<LHS_TYPE>& lhs,
                     const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    return !(rhs < lhs);
}

template <class LHS_TYPE, class RHS_TYPE>
inline
bool bsl::operator>=(const shared_ptr<LHS_TYPE>& lhs,
                     const shared_ptr<RHS_TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    return !(lhs < rhs);
}

template <class LHS_TYPE>
inline
bool bsl::operator==(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return !lhs;
}

template <class RHS_TYPE>
inline
bool bsl::operator==(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return !rhs;
}

template <class LHS_TYPE>
inline
bool bsl::operator!=(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return static_cast<bool>(lhs);
}

template <class RHS_TYPE>
inline
bool bsl::operator!=(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return static_cast<bool>(rhs);
}

template <class LHS_TYPE>
inline
bool bsl::operator<(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<LHS_TYPE *>()(lhs.get(), 0);
}

template <class RHS_TYPE>
inline
bool bsl::operator<(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<RHS_TYPE *>()(0, rhs.get());
}

template <class LHS_TYPE>
inline
bool bsl::operator<=(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return !std::less<LHS_TYPE *>()(0, lhs.get());
}

template <class RHS_TYPE>
inline
bool bsl::operator<=(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return !std::less<RHS_TYPE *>()(rhs.get(), 0);
}

template <class LHS_TYPE>
inline
bool bsl::operator>(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<LHS_TYPE *>()(0, lhs.get());
}

template <class RHS_TYPE>
inline
bool bsl::operator>(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return std::less<RHS_TYPE *>()(rhs.get(), 0);
}

template <class LHS_TYPE>
inline
bool bsl::operator>=(const shared_ptr<LHS_TYPE>& lhs, bsl::nullptr_t)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return !std::less<LHS_TYPE *>()(lhs.get(), 0);
}

template <class RHS_TYPE>
inline
bool bsl::operator>=(bsl::nullptr_t, const shared_ptr<RHS_TYPE>& rhs)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return !std::less<RHS_TYPE *>()(0, rhs.get());
}

template <class CHAR_TYPE, class CHAR_TRAITS, class ELEMENT_TYPE>
inline
std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>&
bsl::operator<<(std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& stream,
                const shared_ptr<ELEMENT_TYPE>&             rhs)
{
    return stream << rhs.get();
}

// ASPECTS
template <class HASHALG, class ELEMENT_TYPE>
inline
void bsl::hashAppend(HASHALG& hashAlg, const shared_ptr<ELEMENT_TYPE>& input)
{
    hashAppend(hashAlg, input.get());
}

template <class ELEMENT_TYPE>
inline
void bsl::swap(shared_ptr<ELEMENT_TYPE>& a, shared_ptr<ELEMENT_TYPE>& b)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    a.swap(b);
}

template <class ELEMENT_TYPE>
inline
void bsl::swap(weak_ptr<ELEMENT_TYPE>& a, weak_ptr<ELEMENT_TYPE>& b)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    a.swap(b);
}

// STANDARD FREE FUNCTIONS
template<class DELETER, class ELEMENT_TYPE>
inline
DELETER *bsl::get_deleter(const shared_ptr<ELEMENT_TYPE>& p)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    BloombergLP::bslma::SharedPtrRep *rep = p.rep();
    return rep ? static_cast<DELETER *>(rep->getDeleter(typeid(DELETER))) : 0;
}

// STANDARD CAST FUNCTIONS
template<class TO_TYPE, class FROM_TYPE>
inline
bsl::shared_ptr<TO_TYPE>
bsl::const_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return shared_ptr<TO_TYPE>(source, const_cast<TO_TYPE *>(source.get()));
}

template<class TO_TYPE, class FROM_TYPE>
inline
bsl::shared_ptr<TO_TYPE>
bsl::dynamic_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    if (TO_TYPE *castPtr = dynamic_cast<TO_TYPE *>(source.get())) {
        return shared_ptr<TO_TYPE>(source, castPtr);                  // RETURN
    }

    return shared_ptr<TO_TYPE>();
}

template<class TO_TYPE, class FROM_TYPE>
inline
bsl::shared_ptr<TO_TYPE>
bsl::static_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return shared_ptr<TO_TYPE>(source, static_cast<TO_TYPE *>(source.get()));
}

template<class TO_TYPE, class FROM_TYPE>
inline
bsl::shared_ptr<TO_TYPE>
bsl::reinterpret_pointer_cast(const shared_ptr<FROM_TYPE>& source)
                                                          BSLS_KEYWORD_NOEXCEPT
{
    return shared_ptr<TO_TYPE>(source,
                               reinterpret_cast<TO_TYPE *>(source.get()));
}

// STANDARD FACTORY FUNCTIONS
#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_sharedptr.h
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT 14
#endif
#ifndef BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D
#define BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D BSLSTL_SHAREDPTR_VARIADIC_LIMIT
#endif


#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 0
template<class ELEMENT_TYPE, class ALLOC>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 1
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 2
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 3
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 4
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 5
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 6
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 7
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 8
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 9
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 10
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 11
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 12
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 13
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_13,args_13));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 14
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13,
                                          class ARGS_14>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_13,args_13),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_14,args_14));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 14


#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 0
template<class ELEMENT_TYPE, class ALLOC>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 1
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 2
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 3
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 4
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 5
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 6
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 7
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 8
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 9
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 10
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 11
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 12
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 13
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_13,args_13));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 14
template<class ELEMENT_TYPE, class ALLOC, class ARGS_01,
                                          class ARGS_02,
                                          class ARGS_03,
                                          class ARGS_04,
                                          class ARGS_05,
                                          class ARGS_06,
                                          class ARGS_07,
                                          class ARGS_08,
                                          class ARGS_09,
                                          class ARGS_10,
                                          class ARGS_11,
                                          class ARGS_12,
                                          class ARGS_13,
                                          class ARGS_14>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_11,args_11),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_12,args_12),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_13,args_13),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_14,args_14));
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 14



#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 0
template<class ELEMENT_TYPE>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared()
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                                 );
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 0

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 1
template<class ELEMENT_TYPE, class ARGS_01>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 1

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 2
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 2

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 3
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 3

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 4
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 4

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 5
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 5

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 6
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 6

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 7
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 7

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 8
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 8

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 9
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 9

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 10
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 10

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 11
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_11, args_11));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 11

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 12
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11,
                             class ARGS_12>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_11, args_11),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_12, args_12));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 12

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 13
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11,
                             class ARGS_12,
                             class ARGS_13>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_11, args_11),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_12, args_12),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_13, args_13));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 13

#if BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 14
template<class ELEMENT_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07,
                             class ARGS_08,
                             class ARGS_09,
                             class ARGS_10,
                             class ARGS_11,
                             class ARGS_12,
                             class ARGS_13,
                             class ARGS_14>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_11) args_11,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_12) args_12,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_13) args_13,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_14) args_14)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_11, args_11),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_12, args_12),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_13, args_13),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_14, args_14));
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
#endif  // BSLSTL_SHAREDPTR_VARIADIC_LIMIT_D >= 14

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.


template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
# if defined(BSLSTL_SHAREDPTR_NO_PARTIAL_ORDER_ON_ALLOCATOR_POINTER)
typename bsl::enable_if<!bsl::is_pointer<ALLOC>::value &&
                                           !bsl::is_array<ELEMENT_TYPE>::value,
                         bsl::shared_ptr<ELEMENT_TYPE> >::type
# else
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
# endif
bsl::allocate_shared(ALLOC basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<ELEMENT_TYPE,
                                                             ALLOC> Rep;
    Rep *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    bsl::allocator_traits<ALLOC>::construct(
                                  basicAllocator,
                                  ImpUtil::unqualify(rep_p->ptr()),
                                  BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}

template<class ELEMENT_TYPE, class ALLOC, class... ARGS>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::allocate_shared(ALLOC *basicAllocator,
                               BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;
    typedef bsl::allocator_traits<AllocatorType>   AllocatorTraits;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;
    AllocatorType  alloc(basicAllocator);
    Rep           *rep_p = Rep::makeRep(alloc);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    AllocatorTraits::construct(alloc,
                               ImpUtil::unqualify(rep_p->ptr()),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);
    proctor.release();
    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}


template<class ELEMENT_TYPE, class... ARGS>
inline
typename bsl::enable_if<!bsl::is_array<ELEMENT_TYPE>::value,
                        bsl::shared_ptr<ELEMENT_TYPE> >::type
bsl::make_shared(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    typedef BloombergLP::bslstl::SharedPtr_ImpUtil ImpUtil;
    typedef bsl::allocator<char>                   AllocatorType;

    typedef BloombergLP::bslstl::SharedPtrAllocateInplaceRep<
                                                            ELEMENT_TYPE,
                                                            AllocatorType> Rep;

    AllocatorType  basicAllocator;
    Rep           *rep_p = Rep::makeRep(basicAllocator);

    BloombergLP::bslstl::SharedPtr_RepProctor proctor(rep_p);
    ::new (ImpUtil::voidify(rep_p->ptr())) ELEMENT_TYPE(
                                 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
    proctor.release();

    return shared_ptr<ELEMENT_TYPE>(rep_p->ptr(), rep_p);
}
// }}} END GENERATED CODE
#endif

// ============================================================================
//                              TYPE TRAITS
// ============================================================================

// Type traits for smart pointers:
//: o 'shared_ptr' has pointer semantics, but 'weak_ptr' does not.
//:
//: o Although 'shared_ptr' constructs with an allocator, it does not 'use' an
//:   allocator in the manner of the 'UsesBslmaAllocator' trait, and should be
//:   explicitly specialized as a clear sign to code inspection tools.
//:
//: o Smart pointers are bitwise-movable as long as there is no opportunity for
//:   holding a pointer to internal state in the immediate object itself.  As
//:   'd_ptr_p' is never exposed by reference, it is not possible to create an
//:   internal pointer, so the trait should be 'true'.

namespace BloombergLP {

namespace bslma {

template <class ELEMENT_TYPE>
struct UsesBslmaAllocator< ::bsl::shared_ptr<ELEMENT_TYPE> >
    : bsl::false_type
{};

}  // close namespace bslma

namespace bslmf {

template <class ELEMENT_TYPE>
struct HasPointerSemantics< ::bsl::shared_ptr<ELEMENT_TYPE> >
    : bsl::true_type
{};

template <class ELEMENT_TYPE>
struct IsBitwiseMoveable< ::bsl::shared_ptr<ELEMENT_TYPE> >
    : bsl::true_type
{};

template <class ELEMENT_TYPE>
struct IsBitwiseMoveable< ::bsl::weak_ptr<ELEMENT_TYPE> >
    : bsl::true_type
{};

}  // close namespace bslmf

}  // close enterprise namespace

#if defined(BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC)
# pragma GCC diagnostic pop
#endif

#undef BSLSTL_SHAREDPTR_DECLARE_IF_CONVERTIBLE
#undef BSLSTL_SHAREDPTR_DEFINE_IF_CONVERTIBLE

#undef BSLSTL_SHAREDPTR_DECLARE_IF_COMPATIBLE
#undef BSLSTL_SHAREDPTR_DEFINE_IF_COMPATIBLE

#undef BSLSTL_SHAREDPTR_DECLARE_IF_DELETER
#undef BSLSTL_SHAREDPTR_DEFINE_IF_DELETER

#undef BSLSTL_SHAREDPTR_DECLARE_IF_NULLPTR_DELETER
#undef BSLSTL_SHAREDPTR_DEFINE_IF_NULLPTR_DELETER

#undef BSLSTL_SHAREDPTR_SFINAE_DISCARD

#else // if ! defined(DEFINED_BSLSTL_SHAREDPTR_H)
# error Not valid except when included from bslstl_sharedptr.h
#endif // ! defined(COMPILING_BSLSTL_SHAREDPTR_H)

#endif // ! defined(INCLUDED_BSLSTL_SHAREDPTR_CPP03)

// ----------------------------------------------------------------------------
// Copyright 2023 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------