// bslalg_arrayprimitives_cpp03.h                                     -*-C++-*-

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

#ifndef INCLUDED_BSLALG_ARRAYPRIMITIVES_CPP03
#define INCLUDED_BSLALG_ARRAYPRIMITIVES_CPP03

//@PURPOSE: Provide C++03 implementation for bslalg_arrayprimitives.h
//
//@CLASSES: See bslalg_arrayprimitives.h for list of classes
//
//@SEE_ALSO: bslalg_arrayprimitives
//
//@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  1 13:02:05 2023
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h

#ifdef COMPILING_BSLALG_ARRAYPRIMITIVES_H

#if defined(BSLS_PLATFORM_CMP_IBM)      // IBM needs specific workarounds.
# define BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER 1
    // xlC has problem removing pointer from function pointer types.

# define BSLALG_ARRAYPRIMITIVES_NON_ZERO_NULL_VALUE_FOR_MEMBER_POINTERS 1
    // xlC representation for a null member pointer is not all zero bits.
#endif

namespace BloombergLP {

namespace bslalg {

struct ArrayPrimitives_Imp;

                        // ======================
                        // struct ArrayPrimitives
                        // ======================

struct ArrayPrimitives {
    // This 'struct' provides a namespace for a suite of independent utility
    // functions that operate on arrays of elements of parameterized type
    // 'TARGET_TYPE'.  Depending on the traits of 'TARGET_TYPE', the default
    // and copy constructors, destructor, assignment operators, etcetera may
    // not be invoked, optimized away by no-op or bit-wise move or copy.

  public:
    // TYPES
    typedef ArrayPrimitives_Imp         Imp;
    typedef std::size_t                 size_type;
    typedef std::ptrdiff_t              difference_type;

    // CLASS METHODS
    template <class ALLOCATOR, class FWD_ITER>
    static void
    copyConstruct(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin,
                 FWD_ITER                                           fromBegin,
                 FWD_ITER                                           fromEnd,
                 ALLOCATOR                                          allocator);
    template <class ALLOCATOR, class SOURCE_TYPE>
    static void
    copyConstruct(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                SOURCE_TYPE                                        *fromBegin,
                SOURCE_TYPE                                        *fromEnd,
                ALLOCATOR                                           allocator);
        // Copy the elements of type 'allocator_traits<ALLOCATOR>::value_type'
        // in the range beginning at the specified 'fromBegin' location and
        // ending immediately before the specified 'fromEnd' location into the
        // uninitialized array beginning at the specified 'toBegin' location,
        // using the specified 'allocator' to supply memory (if required).  If
        // a constructor throws an exception during this operation, the output
        // array is left in an uninitialized state.  The behavior is undefined
        // unless 'toBegin' refers to space sufficient to hold
        // 'fromEnd - fromBegin' elements.

    template <class TARGET_TYPE, class FWD_ITER>
    static void copyConstruct(TARGET_TYPE      *toBegin,
                              FWD_ITER          fromBegin,
                              FWD_ITER          fromEnd,
                              bslma::Allocator *allocator);
    template <class TARGET_TYPE, class SOURCE_TYPE>
    static void copyConstruct(TARGET_TYPE      *toBegin,
                              SOURCE_TYPE      *fromBegin,
                              SOURCE_TYPE      *fromEnd,
                              bslma::Allocator *allocator);
        // Copy into an uninitialized array of (the template parameter)
        // 'TARGET_TYPE' beginning at the specified 'toBegin' address, the
        // elements in the array of 'TARGET_TYPE' starting at the specified
        // 'fromBegin' address and ending immediately before the specified
        // 'fromEnd' address.  If the (template parameter) 'ALLOCATOR' type is
        // derived from 'bslma::Allocator' and 'TARGET_TYPE' supports 'bslma'
        // allocators, then the specified 'allocator' is passed to each
        // invocation of the 'TARGET_TYPE' copy constructor.  If a
        // 'TARGET_TYPE' constructor throws an exception during the operation,
        // then the destructor is called on any newly-constructed elements,
        // leaving the output array in an uninitialized state.

    template <class ALLOCATOR>
    static void
    moveConstruct(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd,
                 ALLOCATOR                                          allocator);
        // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type'
        // in the range beginning at the specified 'fromBegin' location and
        // ending immediately before the specified 'fromEnd' location into the
        // uninitialized array beginning at the specified 'toBegin' location,
        // using the specified 'allocator' to supply memory (if required).  The
        // elements in the input array are left in a valid but unspecified
        // state.  If a constructor throws an exception during this operation,
        // the output array is left in an uninitialized state.  The behavior is
        // undefined unless 'toBegin' refers to space sufficient to hold
        // 'fromEnd - fromBegin' elements.

    template <class TARGET_TYPE>
    static void moveConstruct(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *fromBegin,
                              TARGET_TYPE      *fromEnd,
                              bslma::Allocator *allocator);
        // Move the elements of the (template parameter) 'TARGET_TYPE' starting
        // at the specified 'fromBegin' address and ending immediately before
        // the specified 'fromEnd' address into the uninitialized array of
        // 'TARGET_TYPE' beginning at the specified 'toBegin' address, using
        // the specified 'allocator' to supply memory (if required).  The
        // elements in the input array are left in a valid but unspecified
        // state.  If a constructor throws an exception during this operation,
        // the output array is left in an uninitialized state.  The behavior is
        // undefined unless 'toBegin' refers to space sufficient to hold
        // 'fromEnd - fromBegin' elements.

    template <class ALLOCATOR>
    static void defaultConstruct(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  begin,
               size_type                                           numElements,
               ALLOCATOR                                           allocator);
        // Value-inititalize the specified 'numElements' objects of type
        // 'allocator_traits<ALLOCATOR>::value_type' into the uninitialized
        // array beginning at the specified 'begin' location, using the
        // specified 'allocator' to supply memory (if required).  If a
        // constructor throws an exception during this operation, then the
        // destructor is called on any newly constructed elements, leaving the
        // output array in an uninitialized state.  The behavior is undefined
        // unless the 'begin' refers to space sufficient to hold 'numElements'.

    template <class TARGET_TYPE>
    static void defaultConstruct(TARGET_TYPE      *begin,
                                 size_type         numElements,
                                 bslma::Allocator *allocator);
        // Construct each of the elements of an array of the specified
        // 'numElements' of the parameterized 'TARGET_TYPE' starting at the
        // specified 'begin' address by value-initialization.  If the (template
        // parameter) 'ALLOCATOR' type is derived from 'bslma::Allocator' and
        // 'TARGET_TYPE' supports 'bslma' allocators, then the specified
        // 'allocator' is passed to each 'TARGET_TYPE' default constructor
        // call.  The behavior is undefined unless the output array contains at
        // least 'numElements' uninitialized elements after 'begin'.  If a
        // 'TARGET_TYPE' constructor throws an exception during this operation,
        // then the destructor is called on any newly-constructed elements,
        // leaving the output array in an uninitialized state.

    template <class ALLOCATOR>
    static void destructiveMove(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd,
                 ALLOCATOR                                          allocator);
        // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type'
        // in the range beginning at the specified 'fromBegin' location and
        // ending immediately before the specified 'fromEnd' location into the
        // uninitialized array beginning at the specified 'toBegin' location,
        // using the specified 'allocator' to supply memory (if required).  On
        // return, the elements in the input range are invalid, i.e., their
        // destructors must not be called after this operation returns.  If a
        // constructor throws an exception during this operation, the output
        // array is left in an uninitialized state.  If a constructor other
        // than the move constructor of a non-copy-constructible type throws
        // an exception during this operation, the input array is unaffected;
        // otherwise, if the move constructor of a non-copy-constructible type
        // throws an exception during this operation, the input array is left
        // in a valid but unspecified state.  The behavior is undefined unless
        // 'toBegin' refers to space sufficient to hold 'fromEnd - fromBegin'
        // elements.

    template <class TARGET_TYPE>
    static void destructiveMove(TARGET_TYPE      *toBegin,
                                TARGET_TYPE      *fromBegin,
                                TARGET_TYPE      *fromEnd,
                                bslma::Allocator *allocator);
        // Move the elements of the parameterized 'TARGET_TYPE' in the array
        // starting at the specified 'fromBegin' address and ending immediately
        // before the specified 'fromEnd' address into an uninitialized array
        // of 'TARGET_TYPE' beginning at the specified 'toBegin' address.  On
        // return, the elements in the input range are invalid, i.e., their
        // destructors must not be called after this operation returns.  If the
        // parameterized 'ALLOCATOR' type is derived from 'bslma::Allocator'
        // and 'TARGET_TYPE' supports 'bslma' allocators, then the specified
        // 'allocator' is used by the objects in their new location.  If an
        // exception is thrown by a 'TARGET_TYPE' constructor during the
        // operation, then the output array is left in an uninitialized state
        // and the input elements remain in their original state.

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10
#endif
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#endif

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 0
    template <class ALLOCATOR>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 1
    template <class ALLOCATOR, class ARGS_01>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 2
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 3
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 4
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 5
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 6
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05,
                               class ARGS_06>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 7
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05,
                               class ARGS_06,
                               class ARGS_07>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 8
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05,
                               class ARGS_06,
                               class ARGS_07,
                               class ARGS_08>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 9
    template <class ALLOCATOR, 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>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 10
    template <class ALLOCATOR, 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>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 10

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

    template <class ALLOCATOR, class... ARGS>
    static void destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);

// }}} END GENERATED CODE
#endif

    template <class ALLOCATOR>
    static void destructiveMoveAndInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               size_type                                           numElements,
               ALLOCATOR                                           allocator);
        // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type'
        // in the range beginning at the specified 'fromBegin' location and
        // ending immediately before the specified 'fromEnd' location into the
        // uninitialized array beginning at the specified 'toBegin' location
        // using the specified 'allocator' to supply memory (if required),
        // inserting at the specified 'position' (after translating from
        // 'fromBegin' to 'toBegin') the specified 'numElements' objects
        // initialized to default values, ensuring that the specified
        // 'fromEndPtr' points to the first uninitialized element in
        // '[fromBegin .. fromEnd)' as the elements are moved from source to
        // destination.  On return, the elements in the input range are
        // invalid, i.e., their destructors must not be called after this
        // operation returns.  If a constructor throws an exception during this
        // operation, the output array is left in an uninitialized state.  If a
        // default constructor throws an exception, the input array is
        // unaffected; otherwise, if a (copy or move) constructor throws an
        // exception during this operation, the input elements in the range
        // '[fromBegin .. *fromEndPtr)' are left in a valid but unspecified
        // state and the remaining portion of the input array is left in an
        // uninitialized state.  The behavior is undefined unless 'fromBegin <=
        // position <= fromEnd' and 'toBegin' refers to space sufficient to
        // hold 'fromEnd - fromBegin + 1' elements.

    template <class TARGET_TYPE>
    static void destructiveMoveAndInsert(TARGET_TYPE         *toBegin,
                                         TARGET_TYPE        **fromEndPtr,
                                         TARGET_TYPE         *fromBegin,
                                         TARGET_TYPE         *position,
                                         TARGET_TYPE         *fromEnd,
                                         size_type            numElements,
                                         bslma::Allocator    *allocator);
        // Move the elements of the (template parameter) 'TARGET_TYPE' in the
        // starting at the specified 'fromBegin' address and ending immediately
        // before the specified 'fromEnd' address into the uninitialized array
        // beginning at the specified 'toBegin' location using the specified
        // 'allocator' to supply memory (if required), inserting at the
        // specified 'position' (after translating from 'fromBegin' to
        // 'toBegin') 'numElements' objects initialized to default values,
        // ensuring that the specified 'fromEndPtr' points to the first
        // uninitialized element in '[fromBegin .. fromEnd)' as the elements
        // are moved from source to destination.  On return, the elements in
        // the input range are invalid, i.e., their destructors must not be
        // called after this operation returns.  If a constructor throws an
        // exception during this operation, the output array is left in an
        // uninitialized state.  If a default constructor throws an exception,
        // the input array is unaffected; otherwise, if a (copy or move)
        // constructor throws an exception during this operation, the input
        // elements in the range '[fromBegin .. *fromEndPtr)' are left in a
        // valid but unspecified state and the remaining portion of the input
        // array is left in an uninitialized state.  The behavior is undefined
        // unless 'fromBegin <= position <= fromEnd' and 'toBegin' refers to
        // space sufficient to hold 'fromEnd - fromBegin + numElements'
        // elements.

    template <class ALLOCATOR>
    static void destructiveMoveAndInsert(
     typename bsl::allocator_traits<ALLOCATOR>::pointer            toBegin,
     typename bsl::allocator_traits<ALLOCATOR>::pointer           *fromEndPtr,
     typename bsl::allocator_traits<ALLOCATOR>::pointer            fromBegin,
     typename bsl::allocator_traits<ALLOCATOR>::pointer            position,
     typename bsl::allocator_traits<ALLOCATOR>::pointer            fromEnd,
     const typename bsl::allocator_traits<ALLOCATOR>::value_type&  value,
     size_type                                                     numElements,
     ALLOCATOR                                                     allocator);
        // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type'
        // in the range beginning at the specified 'fromBegin' location and
        // ending immediately before the specified 'fromEnd' location into the
        // uninitialized array beginning at the specified 'toBegin' location
        // using the specified 'allocator' to supply memory (if required),
        // inserting at the specified 'position' (after translating from
        // 'fromBegin' to 'toBegin') the specified 'numElements' copies of the
        // specified 'value', ensuring that the specified 'fromEndPtr' points
        // to the first uninitialized element in '[fromBegin .. fromEnd)' as
        // the elements are moved from source to destination.  On return, the
        // elements in the input range are invalid, i.e., their destructors
        // must not be called after this operation returns.  If a constructor
        // throws an exception during this operation, the output array is left
        // in an uninitialized state.  If a (copy or move) constructor throws
        // an exception during this operation, the input elements in the range
        // '[fromBegin .. *fromEndPtr)' are left in a valid but unspecified
        // state and the remaining portion of the input array is left in an
        // uninitialized state.  The behavior is undefined unless
        // 'fromBegin <= position <= fromEnd' and 'toBegin' refers to space
        // sufficient to hold 'fromEnd - fromBegin + numElements' elements.

    template <class TARGET_TYPE>
    static void destructiveMoveAndInsert(TARGET_TYPE         *toBegin,
                                         TARGET_TYPE        **fromEndPtr,
                                         TARGET_TYPE         *fromBegin,
                                         TARGET_TYPE         *position,
                                         TARGET_TYPE         *fromEnd,
                                         const TARGET_TYPE&   value,
                                         size_type            numElements,
                                         bslma::Allocator    *allocator);
        // Move the elements of the parameterized 'TARGET_TYPE' in the array
        // starting at the specified 'fromBegin' address and ending immediately
        // before the specified 'fromEnd' address into an uninitialized array
        // of 'TARGET_TYPE' at the specified 'toBegin' address, inserting at
        // the specified 'position' (after translating from 'fromBegin' to
        // 'toBegin') the specified 'numElements' copies of the specified
        // 'value'.  Keep the pointer at the specified 'fromEndPtr' address
        // pointing to the first uninitialized element in '[ fromBegin,
        // fromEnd)' as the elements are moved from source to destination.  The
        // behavior is undefined unless 'fromBegin <= position <= fromEnd' and
        // the destination array contains at least
        // '(fromEnd - fromBegin) + numElements' uninitialized elements.  If a
        // copy constructor or assignment operator for 'TARGET_TYPE' throws an
        // exception, then any elements created in the output array are
        // destroyed and the elements in the range '[ fromBegin, *fromEndPtr )'
        // will have unspecified but valid values.

    template <class ALLOCATOR, class FWD_ITER>
    static void destructiveMoveAndInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               FWD_ITER                                            first,
               FWD_ITER                                            last,
               size_type                                           numElements,
               ALLOCATOR                                           allocator);
        // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type'
        // in the range beginning at the specified 'fromBegin' location and
        // ending immediately before the specified 'fromEnd' location into the
        // uninitialized array beginning at the specified 'toBegin' location
        // using the specified 'allocator' to supply memory (if required),
        // inserting at the specified 'position' (after translating from
        // 'fromBegin' to 'toBegin') the specified 'numElements' copies of the
        // non-modifiable elements from the range starting at the specified
        // 'first' iterator of (template parameter) type 'FWD_ITER' and ending
        // immediately before the specified 'last' iterator, ensuring that the
        // specified 'fromEndPtr' points to the first uninitialized element in
        // '[fromBegin .. fromEnd)' as the elements are moved from source to
        // destination.  On return, the elements in the input range are
        // invalid, i.e., their destructors must not be called after this
        // operation returns.  If a constructor throws an exception during this
        // operation, the output array is left in an uninitialized state.  If
        // a constructor other than the copy or move constructor throws an
        // exception during this operation, the input array is unaffected;
        // otherwise, if a copy or move constructor throws an exception during
        // this operation, the input elements in the range
        // '[fromBegin .. *fromEndPtr)' are left in a valid but unspecified
        // state and the remaining portion of the input array is left in an
        // uninitialized state.  The behavior is undefined unless
        // 'fromBegin <= position <= fromEnd' and 'toBegin' refers to space
        // sufficient to hold 'fromEnd - fromBegin + numElements' elements.

    template <class TARGET_TYPE, class FWD_ITER>
    static void destructiveMoveAndInsert(TARGET_TYPE       *toBegin,
                                         TARGET_TYPE      **fromEndPtr,
                                         TARGET_TYPE       *fromBegin,
                                         TARGET_TYPE       *position,
                                         TARGET_TYPE       *fromEnd,
                                         FWD_ITER           first,
                                         FWD_ITER           last,
                                         size_type          numElements,
                                         bslma::Allocator  *allocator);
        // Move the elements of the parameterized 'TARGET_TYPE' in the array
        // starting at the specified 'fromBegin' address and ending immediately
        // before the specified 'fromEnd' address into an uninitialized array
        // of 'TARGET_TYPE' at the specified 'toBegin' address, inserting at
        // the specified 'position' (after translating from 'fromBegin' to
        // 'toBegin') the specified 'numElements' copies of the non-modifiable
        // elements from the range starting at the specified 'first' iterator
        // of the parameterized 'FWD_ITER' type and ending immediately before
        // the specified 'last' iterator.  Keep the pointer at the specified
        // 'fromEndPtr' to point to the first uninitialized element in
        // '[fromBegin, fromEnd)' as the elements are moved from source to
        // destination.  The behavior is undefined unless
        // 'fromBegin <= position <= fromEnd', the destination array contains
        // at least '(fromEnd - fromBegin) + numElements' uninitialized
        // elements after 'toBegin', and 'numElements' is the distance from
        // 'first' to 'last'.  If a copy constructor or assignment operator for
        // 'TARGET_TYPE' throws an exception, then any elements created in the
        // output array are destroyed and the elements in the range
        // '[ fromBegin, *fromEndPtr )' will have unspecified but valid values.

    template <class ALLOCATOR>
    static void destructiveMoveAndMoveInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *lastPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  first,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  last,
               size_type                                           numElements,
               ALLOCATOR                                           allocator);
        // TBD: improve comment
        // Move, into an uninitialized array beginning at the specified
        // 'toBegin' pointer, elements of type given by the 'allocator_traits'
        // class template for (template parameter) 'ALLOCATOR', from elements
        // starting at the specified 'fromBegin' pointer and ending immediately
        // before the specified 'fromEnd' address, moving into the specified
        // 'position' (after translating from 'fromBegin' to 'toBegin') the
        // specified 'numElements' elements starting at the specified 'first'
        // pointer and ending immediately before the specified 'last' pointer.
        // Keep the pointer at the specified 'fromEndPtr' address pointing to
        // the first uninitialized element in '[ fromBegin, fromEnd)' as the
        // elements are moved from source to destination.  The behavior is
        // undefined unless 'fromBegin <= position <= fromEnd' and the
        // destination array contains at least
        // '(fromEnd - fromBegin) + numElements' uninitialized elements.  If a
        // constructor or assignment operator for the target type throws an
        // exception, then any elements created in the output array are
        // destroyed and the elements in the range '[ fromBegin, *fromEndPtr )'
        // will have valid but unspecified values.

    template <class TARGET_TYPE>
    static void destructiveMoveAndMoveInsert(TARGET_TYPE       *toBegin,
                                             TARGET_TYPE      **fromEndPtr,
                                             TARGET_TYPE      **lastPtr,
                                             TARGET_TYPE       *fromBegin,
                                             TARGET_TYPE       *position,
                                             TARGET_TYPE       *fromEnd,
                                             TARGET_TYPE       *first,
                                             TARGET_TYPE       *last,
                                             size_type          numElements,
                                             bslma::Allocator  *allocator);
        // Move the elements of (template parameter) 'TARGET_TYPE' in the array
        // starting at the specified 'fromBegin' address and ending immediately
        // before the specified 'fromEnd' address into an uninitialized array
        // of 'TARGET_TYPE' at the specified 'toBegin' address, moving into the
        // specified 'position' (after translating from 'fromBegin' to
        // 'toBegin') the specified 'numElements' of the 'TARGET_TYPE' from the
        // array starting at the specified 'first' address and ending
        // immediately before the specified 'last' address.  Keep the pointer
        // at the specified 'fromEndPtr' address pointing to the first
        // uninitialized element in '[fromBegin, fromEnd)', and the pointer at
        // the specified 'lastPtr' address pointing to the end of the moved
        // range as the elements from the range '[ first, last)' are moved from
        // source to destination.  The behavior is undefined unless
        // 'fromBegin <= position <= fromEnd', the destination array contains
        // at least '(fromEnd - fromBegin) + numElements' uninitialized
        // elements after 'toBegin', and 'numElements' is the distance from
        // 'first' to 'last'.  If a copy constructor or assignment operator for
        // 'TARGET_TYPE' throws an exception, then any elements in
        // '[ *lastPtr, last )' as well as in '[ toBegin, ... )' are destroyed,
        // and the elements in the ranges '[ first, *lastPtr )' and
        // '[ fromBegin, *fromEndPtr )' will have unspecified but valid values.

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10
#endif
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#endif
#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0
    template <class ALLOCATOR>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1
    template <class ALLOCATOR, class ARGS_01>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05,
                               class ARGS_06>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05,
                               class ARGS_06,
                               class ARGS_07>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8
    template <class ALLOCATOR, class ARGS_01,
                               class ARGS_02,
                               class ARGS_03,
                               class ARGS_04,
                               class ARGS_05,
                               class ARGS_06,
                               class ARGS_07,
                               class ARGS_08>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9
    template <class ALLOCATOR, 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>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10
    template <class ALLOCATOR, 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>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10


#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0
    template <class TARGET_TYPE>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1
    template <class TARGET_TYPE, class ARGS_01>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2
    template <class TARGET_TYPE, class ARGS_01,
                                 class ARGS_02>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3
    template <class TARGET_TYPE, class ARGS_01,
                                 class ARGS_02,
                                 class ARGS_03>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4
    template <class TARGET_TYPE, class ARGS_01,
                                 class ARGS_02,
                                 class ARGS_03,
                                 class ARGS_04>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5
    template <class TARGET_TYPE, class ARGS_01,
                                 class ARGS_02,
                                 class ARGS_03,
                                 class ARGS_04,
                                 class ARGS_05>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6
    template <class TARGET_TYPE, class ARGS_01,
                                 class ARGS_02,
                                 class ARGS_03,
                                 class ARGS_04,
                                 class ARGS_05,
                                 class ARGS_06>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7
    template <class TARGET_TYPE, class ARGS_01,
                                 class ARGS_02,
                                 class ARGS_03,
                                 class ARGS_04,
                                 class ARGS_05,
                                 class ARGS_06,
                                 class ARGS_07>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8
    template <class TARGET_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>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9
    template <class TARGET_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>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10
    template <class TARGET_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>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class ALLOCATOR, class... ARGS>
    static void emplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments);

    template <class TARGET_TYPE, class... ARGS>
    static void emplace(TARGET_TYPE               *toBegin,
                        TARGET_TYPE               *toEnd,
                        bslma::Allocator          *allocator,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);

// }}} END GENERATED CODE
#endif

#if defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900
    template <class CLASS_TYPE, class MEMBER_TYPE, class... ARGS>
    static void emplace(MEMBER_TYPE CLASS_TYPE::* *toBegin,
                        MEMBER_TYPE CLASS_TYPE::* *toEnd,
                        bslma::Allocator          *allocator)
        // Old Microsoft compilers need help value-initializing elements that
        // are pointer-to-member types.
    {
        emplace(toBegin, toEnd, allocator, nullptr);
    }
#endif

    template <class ALLOCATOR>
    static void
    erase(typename bsl::allocator_traits<ALLOCATOR>::pointer first,
          typename bsl::allocator_traits<ALLOCATOR>::pointer middle,
          typename bsl::allocator_traits<ALLOCATOR>::pointer last,
          ALLOCATOR                                          allocator);
        // TBD: improve comment
        // Destroy the elements of type given by the 'allocator_traits' class
        // template for (template parameter) 'ALLOCATOR' starting at the
        // specified 'first' 'first' pointer and ending immediately before the
        // specified 'middle' pointer, and move the elements in the array
        // starting at 'middle' and ending at the specified 'last' pointer down
        // to the 'first' pointer.  If an assignment throws an exception during
        // this process, all of the elements in the range '[ first, last )'
        // will have unspecified but valid values, and no elements are
        // destroyed.  The behavior is undefined unless
        // 'first <= middle <= last'.

    template <class TARGET_TYPE>
    static void erase(TARGET_TYPE      *first,
                      TARGET_TYPE      *middle,
                      TARGET_TYPE      *last,
                      bslma::Allocator *allocator = 0);
        // Destroy the elements of the parameterized 'TARGET_TYPE' in the array
        // starting at the specified 'first' address and ending immediately
        // before the specified 'middle' address, and move the elements in the
        // array starting at 'middle' and ending at the specified 'last'
        // address down to the 'first' address.  If an assignment throws an
        // exception during this process, all of the elements in the range
        // '[ first, last )' will have unspecified but valid values, and no
        // elements are destroyed.  The behavior is undefined unless
        // 'first <= middle <= last'.

    template <class ALLOCATOR>
    static void
    insert(typename bsl::allocator_traits<ALLOCATOR>::pointer     toBegin,
           typename bsl::allocator_traits<ALLOCATOR>::pointer     toEnd,
           bslmf::MovableRef<
           typename bsl::allocator_traits<ALLOCATOR>::value_type> value,
           ALLOCATOR                                              allocator);
        // Insert the specified 'value' into the array of
        // 'allocator_traits<ALLOCATOR>::value_type' objects at the specified
        // 'toBegin' location, shifting forward the elements from 'toBegin' to
        // the specified 'toEnd' location by one position.  'value' is left in
        // a valid but unspecified state.  If a (copy or move) constructor or a
        // (copy or move) assignment operator throws an exception, then any
        // elements created after 'toEnd' are destroyed and the elements in the
        // range '[toBegin .. toEnd )' are left in a valid but unspecified
        // state.  The behavior is undefined unless 'toBegin' refers to
        // sufficient space to hold at least 'toEnd - toBegin + 1' elements.

    template <class TARGET_TYPE>
    static void insert(TARGET_TYPE                                *toBegin,
                       TARGET_TYPE                                *toEnd,
                       bslmf::MovableRef<TARGET_TYPE>              value,
                       bslma::Allocator                           *allocator);
        // Insert the specified 'value' into the array of the (template
        // parameter) type 'TARGET_TYPE' at the specified 'toBegin' address,
        // shifting the elements from 'toBegin' to the specified 'toEnd'
        // address by one position towards larger addresses.  'value' is left
        // in a valid but unspecified state.  If a (copy or move) constructor
        // or a (copy or move) assignment operator throws an exception, then
        // any elements created after 'toEnd' are destroyed and the elements in
        // the range '[toBegin .. toEnd )' are left in a valid but unspecified
        // state.  The behavior is undefined unless 'toBegin' refers to
        // sufficient space to hold at least 'toEnd - toBegin + 1' elements.

    template <class ALLOCATOR>
    static void
    insert(
      typename bsl::allocator_traits<ALLOCATOR>::pointer           toBegin,
      typename bsl::allocator_traits<ALLOCATOR>::pointer           toEnd,
      const typename bsl::allocator_traits<ALLOCATOR>::value_type& value,
      size_type                                                    numElements,
      ALLOCATOR                                                    allocator);
        // Insert the specified 'numElements' copies of the specified 'value'
        // into the array of type 'allocator_traits<ALLOCATOR>::value_type'
        // starting at the specified 'toBegin' location, shifting forward the
        // elements from 'toBegin' to the specified 'toEnd' location by
        // 'numElements' positions.  If a (copy or move) constructor or a (copy
        // or move) assignment operator throws an exception, any elements
        // created after 'toEnd' are destroyed and the elements in the range
        // '[toBegin .. toEnd)' are left in a valid but unspecified state.  The
        // behavior is undefined unless 'toBegin' refers to space sufficient to
        // hold at least 'toEnd - toBegin + numElements' elements.

    template <class TARGET_TYPE>
    static void insert(TARGET_TYPE        *toBegin,
                       TARGET_TYPE        *toEnd,
                       const TARGET_TYPE&  value,
                       size_type           numElements,
                       bslma::Allocator   *allocator);
        // Insert the specified 'numElements' copies of the specified 'value'
        // into the array of (template parameter) 'TARGET_TYPE' starting at the
        // specified 'toBegin' address and ending immediately before the
        // specified 'toEnd' address, shifting the elements in the array by
        // 'numElements' positions towards larger addresses.  The behavior is
        // undefined unless the destination array contains at least
        // 'numElements' uninitialized elements after 'toEnd'.  If a copy
        // constructor or assignment operator for 'TARGET_TYPE' throws an
        // exception, then any elements created after 'toEnd' are destroyed and
        // the elements in the range '[ toBegin, toEnd )' will have
        // unspecified, but valid, values.

    template <class ALLOCATOR, class FWD_ITER>
    static void
    insert(typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
           typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
           FWD_ITER                                            fromBegin,
           FWD_ITER                                            fromEnd,
           size_type                                           numElements,
           ALLOCATOR                                           allocator);
    template <class ALLOCATOR, class SOURCE_TYPE>
    static void
    insert(typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
           typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
           SOURCE_TYPE                                        *fromBegin,
           SOURCE_TYPE                                        *fromEnd,
           size_type                                           numElements,
           ALLOCATOR                                           allocator);
        // TBD: improve comment
        // Insert the specified 'numElements' from the range starting at the
        // specified 'fromBegin' and ending immediately before the specified
        // 'fromEnd' iterators of (template parameter) 'FWD_ITER' type (or
        // template parameter 'SOURCE_TYPE *'), into the array of elements of
        // type given by the 'allocator_traits' class template for (template
        // parameter) 'ALLOCATOR', starting at the specified 'toBegin' address,
        // shifting forward the elements in the array by 'numElements'
        // positions.  The behavior is undefined unless the destination array
        // contains 'numElements' uninitialized elements after 'toEnd',
        // 'numElements' is the distance between 'fromBegin' and 'fromEnd',
        // and the input array and the destination array do not overlap.  If a
        // copy constructor or assignment operator throws an exception, then
        // any elements created after 'toEnd' are destroyed and the elements in
        // the range '[ toBegin, toEnd )' will have valid but unspecified
        // values.

    template <class TARGET_TYPE, class FWD_ITER>
    static void insert(TARGET_TYPE      *toBegin,
                       TARGET_TYPE      *toEnd,
                       FWD_ITER          fromBegin,
                       FWD_ITER          fromEnd,
                       size_type         numElements,
                       bslma::Allocator *allocator);
    template <class TARGET_TYPE, class SOURCE_TYPE>
    static void insert(TARGET_TYPE      *toBegin,
                       TARGET_TYPE      *toEnd,
                       SOURCE_TYPE      *fromBegin,
                       SOURCE_TYPE      *fromEnd,
                       size_type         numElements,
                       bslma::Allocator *allocator);
        // Insert, into the array at the specified 'toBegin' location, the
        // specified 'numElements' from the range starting at the specified
        // 'fromBegin' and ending immediately before the specified 'fromEnd'
        // iterators of the (template parameter) 'FWD_ITER' type (or the
        // (template parameter) 'SOURCE_TYPE *'), into the array of elements of
        // the parameterized 'TARGET_TYPE' starting at the specified 'toBegin'
        // address and ending immediately before the specified 'toEnd' address,
        // shifting the elements in the array by 'numElements' positions
        // towards larger addresses.  The behavior is undefined unless the
        // destination array contains 'numElements' uninitialized elements
        // after 'toEnd', 'numElements' is the distance between 'fromBegin' and
        // 'fromEnd', and the input array and the destination array do not
        // overlap.  If a copy constructor or assignment operator for
        // 'TARGET_TYPE' throws an exception, then any elements created after
        // 'toEnd' are destroyed and the elements in the range
        // '[ toBegin, toEnd )' will have unspecified, but valid, values.

    template <class ALLOCATOR>
    static void moveInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               size_type                                           numElements,
               ALLOCATOR                                           allocator);
        // TBD: improve comment
        // Move the elements of type given by the 'allocator_traits' class
        // template for (template parameter) 'ALLOCATOR' in the array starting
        // at the specified 'toBegin' location and ending immediately before
        // the specified 'toEnd' location by the specified 'numElements'
        // positions towards larger addresses, and fill the 'numElements' at
        // the 'toBegin' location by moving the elements from the array
        // starting at the specified 'fromBegin' and ending immediately before
        // the specified 'fromEnd' location.  Keep the iterator at the
        // specified 'fromEndPtr' address pointing to the end of the range as
        // the elements from '[ fromBegin, fromEnd )' are moved from source to
        // destination.  The behavior is undefined unless the destination array
        // contains 'numElements' uninitialized elements after 'toEnd',
        // 'numElements' is the distance from 'fromBegin' to 'fromEnd', and the
        // input and destination arrays do not overlap.  If a copy constructor
        // or assignment operator for 'TARGET_TYPE' throws an exception, then
        // any elements created after 'toEnd' are destroyed, the elements in
        // the ranges '[ toBegin, toEnd)' and '[ fromBegin, *fromEndPtr )' will
        // have unspecified, but valid, values, and the elements in
        // '[ *fromEndPtr, fromEnd )' will be destroyed.

    template <class TARGET_TYPE>
    static void moveInsert(TARGET_TYPE       *toBegin,
                           TARGET_TYPE       *toEnd,
                           TARGET_TYPE      **fromEndPtr,
                           TARGET_TYPE       *fromBegin,
                           TARGET_TYPE       *fromEnd,
                           size_type          numElements,
                           bslma::Allocator  *allocator);
        // Move the elements of the (template parameter) 'TARGET_TYPE' in the
        // array starting at the specified 'toBegin' address and ending
        // immediately before the specified 'toEnd' address by the specified
        // 'numElements' positions towards larger addresses, and fill the
        // 'numElements' at the 'toBegin' address by moving the elements from
        // the array starting at the specified 'fromBegin' and ending
        // immediately before the specified 'fromEnd' address.  Keep the
        // iterator at the specified 'fromEndPtr' address pointing to the end
        // of the range as the elements from '[ fromBegin, fromEnd )' are moved
        // from source to destination.  The behavior is undefined unless the
        // destination array contains 'numElements' uninitialized elements
        // after 'toEnd', 'numElements' is the distance from 'fromBegin' to
        // 'fromEnd', and the input and destination arrays do not overlap.  If
        // a copy constructor or assignment operator for 'TARGET_TYPE' throws
        // an exception, then any elements created after 'toEnd' are destroyed,
        // the elements in the ranges '[ toBegin, toEnd)' and
        // '[ fromBegin, *fromEndPtr )' will have unspecified, but valid,
        // values, and the elements in '[ *fromEndPtr, fromEnd )' will be
        // destroyed.

    template <class TARGET_TYPE>
    static void rotate(TARGET_TYPE *first,
                       TARGET_TYPE *middle,
                       TARGET_TYPE *last);
        // Move the elements of the parameterized 'TARGET_TYPE' in the array
        // starting at the specified 'first' address and ending immediately
        // before the specified 'middle' address to the array of the same
        // length ending at the specified 'last' address (and thus starting at
        // the 'last - (middle - first)' address), and move the elements
        // previously in the array starting at 'middle' and ending at 'last'
        // down to the 'first' address.  If the assignment operator throws an
        // exception during this process, all of the elements in
        // '[ first, last )' will have unspecified, but valid, values.  The
        // behavior is undefined unless 'first <= middle <= last'.

    template <class ALLOCATOR>
    static void uninitializedFillN(
      typename bsl::allocator_traits<ALLOCATOR>::pointer           begin,
      size_type                                                    numElements,
      const typename bsl::allocator_traits<ALLOCATOR>::value_type& value,
      ALLOCATOR                                                    allocator);
        // TBD: improve comment
        // Construct copies of the specified 'value' of type given by the
        // 'allocator_traits' class template for (template parameter)
        // 'ALLOCATOR' into the uninitialized array containing the specified
        // 'numElements' starting at the specified 'begin' location.  The
        // behavior is undefined unless the output array contains at least
        // 'numElements' uninitialized elements after 'begin'.  If a
        // constructor throws an exception during the operation, then the
        // destructor is called on any newly-constructed elements, leaving the
        // output array in an uninitialized state.

    template <class TARGET_TYPE>
    static void uninitializedFillN(TARGET_TYPE        *begin,
                                   size_type           numElements,
                                   const TARGET_TYPE&  value,
                                   bslma::Allocator   *allocator);
        // Construct copies of the specified 'value' of the parameterized type
        // 'TARGET_TYPE' into the uninitialized array containing the specified
        // 'numElements' starting at the specified 'begin' address.  If the
        // (template parameter) 'ALLOCATOR' type is derived from
        // 'bslma::Allocator' and 'TARGET_TYPE' supports 'bslma' allocators,
        // then the specified 'allocator' is passed to each invocation of the
        // 'TARGET_TYPE' copy constructor.  The behavior is undefined unless
        // the output array contains at least 'numElements' uninitialized
        // elements after 'begin'.  If a 'TARGET_TYPE' constructor throws an
        // exception during the operation, then the destructor is called on any
        // newly-constructed elements, leaving the output array in an
        // uninitialized state.  Note that the argument order was chosen to
        // maintain compatibility with the existing 'bslalg'.
};

                     // ==========================
                     // struct ArrayPrimitives_Imp
                     // ==========================

struct ArrayPrimitives_Imp {
    // This 'struct' provides a namespace for a suite of independent utility
    // functions that operate on arrays of elements of a parameterized
    // 'TARGET_TYPE'.  These utility functions are only for the purpose of
    // implementing those in the 'ArrayPrimitives' utility.  For brevity, we do
    // not repeat the main contracts here, but instead refer to the
    // corresponding contract in the 'ArrayPrimitives' utility.

  private:
    // PRIVATE METHODS
    template <class TARGET_TYPE>
    static void assign(TARGET_TYPE *srcStart,
                       TARGET_TYPE *srcEnd,
                       TARGET_TYPE& value);
        // Copy-assign the specified 'value' to the range starting at the
        // specified 'srcStart' and ending immediately before the specified
        // 'srcEnd'.  Note that the (template parameter) 'TARGET_TYPE' must be
        // copy-assignable.  Also note that 'value' should not be an element in
        // the range '[srcStart, srcEnd)'.

    template <class TARGET_TYPE>
    static void reverseAssign(TARGET_TYPE *dest,
                              TARGET_TYPE *srcStart,
                              TARGET_TYPE *srcEnd);
        // Copy-assign the elements in reverse order from the range starting at
        // the specified 'srcStart' and ending immediately before the specified
        // 'srcEnd' to the range starting at the specified 'dest' and ending
        // immediately before 'dest + (srcEnd - srcStart)'.  The behavior is
        // undefined unless each element is both range '[srcStart, srcEnd)' and
        // range '[dest, dest + (srcEnd - srcStart))' is valid.  Note that the
        // (template parameter) 'TARGET_TYPE' must be copy-assignable.  Also
        // note that this method is intended to support range assignment when
        // the two ranges may be overlapped, and 'srcStart <= dest'.

  public:
    // TYPES
    typedef ArrayPrimitives::size_type       size_type;
    typedef ArrayPrimitives::difference_type difference_type;

    enum {
        // These constants are used in the overloads below, when the last
        // argument is of type 'bslmf::MetaInt<N> *', indicating that
        // 'TARGET_TYPE' has the traits for which the enumerator equal to 'N'
        // is named.

        e_IS_ITERATOR_TO_FUNCTION_POINTER  = 6,
        e_IS_POINTER_TO_POINTER            = 5,
        e_IS_FUNDAMENTAL_OR_POINTER        = 4,
        e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS  = 3,
        e_BITWISE_COPYABLE_TRAITS          = 2,
        e_BITWISE_MOVEABLE_TRAITS          = 1,
        e_NIL_TRAITS                       = 0
    };

    enum {
        // Number of bytes for which a stack-allocated buffer can be
        // comfortably obtained to optimize bitwise moves.

        k_INPLACE_BUFFER_SIZE = 16 * bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT
    };

    // CLASS METHODS
    static void bitwiseFillN(char      *begin,
                             size_type  numBytesInitialized,
                             size_type  numBytes);
        // Fill the specified 'numBytes' in the array starting at the specified
        // 'begin' address, as if by bit-wise copying the specified
        // 'numBytesInitialized' at every offset that is a multiple of
        // 'numBytesInitialized' within the output array.  The behavior is
        // undefined unless 'numBytesInitialized <= numBytes'.  Note that
        // 'numBytes' usually is, but does not have to be, a multiple of
        // 'numBytesInitialized'.

    static void uninitializedFillN(
                      bool                                        *begin,
                      bool                                         value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      char                                        *begin,
                      char                                         value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      unsigned char                               *begin,
                      unsigned char                                value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      signed char                                 *begin,
                      signed char                                  value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      wchar_t                                     *begin,
                      wchar_t                                      value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      short                                       *begin,
                      short                                        value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      unsigned short                              *begin,
                      unsigned short                               value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      int                                         *begin,
                      int                                          value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      unsigned int                                *begin,
                      unsigned int                                 value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      long                                        *begin,
                      long                                         value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      unsigned long                               *begin,
                      unsigned long                                value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      bsls::Types::Int64                          *begin,
                      bsls::Types::Int64                           value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      bsls::Types::Uint64                         *begin,
                      bsls::Types::Uint64                          value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      float                                       *begin,
                      float                                        value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      double                                      *begin,
                      double                                       value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                      long double                                 *begin,
                      long double                                  value,
                      size_type                                    numElements,
                      void                                        * = 0,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0);
    static void uninitializedFillN(
                     void                                        **begin,
                     void                                         *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    static void uninitializedFillN(
                     const void                                  **begin,
                     const void                                   *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    static void uninitializedFillN(
                     volatile void                               **begin,
                     volatile void                                *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    static void uninitializedFillN(
                     const volatile void                         **begin,
                     const volatile void                          *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    template <class TARGET_TYPE>
    static void uninitializedFillN(
                     TARGET_TYPE                                 **begin,
                     TARGET_TYPE                                  *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    template <class TARGET_TYPE>
    static void uninitializedFillN(
                     const TARGET_TYPE                           **begin,
                     const TARGET_TYPE                            *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    template <class TARGET_TYPE>
    static void uninitializedFillN(
                     volatile  TARGET_TYPE                       **begin,
                     volatile TARGET_TYPE                         *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    template <class TARGET_TYPE>
    static void uninitializedFillN(
                     const volatile TARGET_TYPE                  **begin,
                     const volatile TARGET_TYPE                   *value,
                     size_type                                     numElements,
                     void                                         * = 0,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  * = 0);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void uninitializedFillN(
                        TARGET_TYPE                               *begin,
                        const TARGET_TYPE&                         value,
                        size_type                                  numElements,
                        ALLOCATOR                                 *allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void uninitializedFillN(TARGET_TYPE                  *begin,
                                   const TARGET_TYPE&            value,
                                   size_type                     numElements,
                                   ALLOCATOR                    *allocator,
                                   bslmf::MetaInt<e_NIL_TRAITS> *);
        // Copy the specified 'value' of the parameterized 'TARGET_TYPE' into
        // every of the specified 'numElements' in the array starting at the
        // specified 'begin' address.  Pass the specified 'allocator' to the
        // copy constructor if appropriate.  Note that if 'TARGET_TYPE' is
        // bit-wise copyable or is not based on 'bslma::Allocator', 'allocator'
        // is ignored.  The last argument is for removing overload ambiguities
        // and is not used.

    template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
    static void copyConstruct(TARGET_TYPE                *toBegin,
                              FWD_ITER                    fromBegin,
                              FWD_ITER                    fromEnd,
                              ALLOCATOR                   allocator,
                              bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void copyConstruct(
                          TARGET_TYPE                               *toBegin,
                          const TARGET_TYPE                         *fromBegin,
                          const TARGET_TYPE                         *fromEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
    static void copyConstruct(TARGET_TYPE                           *toBegin,
                              FWD_ITER                               fromBegin,
                              FWD_ITER                               fromEnd,
                              ALLOCATOR                              allocator,
                          bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *);
    template <class FWD_ITER, class ALLOCATOR>
    static void copyConstruct(void                                 **toBegin,
                              FWD_ITER                               fromBegin,
                              FWD_ITER                               fromEnd,
                              ALLOCATOR                              allocator,
                          bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *);
    template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
    static void copyConstruct(TARGET_TYPE                  *toBegin,
                              FWD_ITER                      fromBegin,
                              FWD_ITER                      fromEnd,
                              ALLOCATOR                     allocator,
                              bslmf::MetaInt<e_NIL_TRAITS> *);
        // These functions follow the 'copyConstruct' contract.  If the
        // (template parameter) 'ALLOCATOR' type is based on 'bslma::Allocator'
        // and the 'TARGET_TYPE' constructors take an allocator argument, then
        // pass the specified 'allocator' to the copy constructor.  The
        // behavior is undefined unless the output array has length at least
        // the distance from the specified 'fromBegin' to the specified
        // 'fromEnd'.  Note that if 'FWD_ITER' is the 'TARGET_TYPE *' pointer
        // type and 'TARGET_TYPE' is bit-wise copyable, then this operation is
        // simply 'memcpy'.  The last argument is for removing overload
        // ambiguities and is not used.

    template <class TARGET_TYPE, class ALLOCATOR>
    static void moveConstruct(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *fromBegin,
                          TARGET_TYPE                               *fromEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void moveConstruct(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *fromBegin,
                          TARGET_TYPE                               *fromEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_NIL_TRAITS> *);
        // TBD: improve comment
        // Move-insert into an uninitialized array beginning at the specified
        // 'toBegin' pointer, elements of type given by the 'allocator_traits'
        // class template for (template parameter) 'ALLOCATOR' from elements
        // starting at the specified 'fromBegin' pointer and ending immediately
        // before the specified 'fromEnd' pointer.  The elements in the range
        // '[fromBegin...fromEnd)' are left in a valid but unspecified state.
        // If a constructor throws an exception during the operation, then the
        // destructor is called on any newly-constructed elements, leaving the
        // output array in an uninitialized state.  The behavior is undefined
        // unless 'toBegin' refers to space sufficient to hold
        // 'fromEnd - fromBegin' elements.

    template <class TARGET_TYPE, class ALLOCATOR>
    static void moveIfNoexcept(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *fromBegin,
                          TARGET_TYPE                               *fromEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_NIL_TRAITS> *);
        // TBD: improve comment
        // Either move- or copy-insert into an uninitialized array beginning at
        // the specified 'toBegin' pointer, elements of type given by the
        // 'allocator_traits' class template for (template parameter)
        // 'ALLOCATOR' from elements starting at the specified 'fromBegin'
        // pointer and ending immediately before the specified 'fromEnd'
        // pointer.  The elements in the range '[fromBegin...fromEnd)' are left
        // in a valid but unspecified state.  Use the move constructor if it is
        // guaranteed to not throw or if the target type does not define a copy
        // constructor; otherwise use the copy constructor.  If a constructor
        // throws an exception during the operation, then the destructor is
        // called on any newly-constructed elements, leaving the output array
        // in an uninitialized state.  The behavior is undefined unless
        // 'toBegin' refers to space sufficient to hold 'fromEnd - fromBegin'
        // elements.

    template <class TARGET_TYPE, class ALLOCATOR>
    static void defaultConstruct(
                TARGET_TYPE                                       *begin,
                size_type                                          numElements,
                ALLOCATOR                                          allocator,
                bslmf::MetaInt<e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void defaultConstruct(
                        TARGET_TYPE                               *begin,
                        size_type                                  numElements,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void defaultConstruct(TARGET_TYPE                  *begin,
                                 size_type                     numElements,
                                 ALLOCATOR                     allocator,
                                 bslmf::MetaInt<e_NIL_TRAITS> *);
        // Use the default constructor of the (template parameter)
        // 'TARGET_TYPE' (or 'memset' to 0 if 'TARGET_TYPE' has a trivial
        // default constructor) on each element of the array starting at the
        // specified 'begin' address and ending immediately before the 'end'
        // address.  Pass the specified 'allocator' to the default constructor
        // if appropriate.  The last argument is for traits overloading
        // resolution only and its value is ignored.

    template <class TARGET_TYPE, class ALLOCATOR>
    static void destructiveMove(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *fromBegin,
                          TARGET_TYPE                               *fromEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void destructiveMove(TARGET_TYPE                  *toBegin,
                                TARGET_TYPE                  *fromBegin,
                                TARGET_TYPE                  *fromEnd,
                                ALLOCATOR                     allocator,
                                bslmf::MetaInt<e_NIL_TRAITS> *);
        // These functions follow the 'destructiveMove' contract.  Note that
        // both arrays cannot overlap (one contains only initialized elements
        // and the other only uninitialized elements), and that if
        // 'TARGET_TYPE' is bit-wise moveable, then this operation is simply
        // 'memcpy'.  The last argument is for removing overload ambiguities
        // and is not used.

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10
#endif
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#endif
#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0
    template <class TARGET_TYPE, class ALLOCATOR>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06,
                                                  class ARGS_07>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06,
                                                  class ARGS_07,
                                                  class ARGS_08>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9
    template <class TARGET_TYPE, class ALLOCATOR, 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>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10
    template <class TARGET_TYPE, class ALLOCATOR, 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>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0
    template <class TARGET_TYPE, class ALLOCATOR>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06,
                                                  class ARGS_07>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06,
                                                  class ARGS_07,
                                                  class ARGS_08>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9
    template <class TARGET_TYPE, class ALLOCATOR, 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>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10
    template <class TARGET_TYPE, class ALLOCATOR, 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>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0
    template <class TARGET_TYPE, class ALLOCATOR>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06,
                                                  class ARGS_07>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8
    template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                                  class ARGS_02,
                                                  class ARGS_03,
                                                  class ARGS_04,
                                                  class ARGS_05,
                                                  class ARGS_06,
                                                  class ARGS_07,
                                                  class ARGS_08>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9
    template <class TARGET_TYPE, class ALLOCATOR, 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>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10
    template <class TARGET_TYPE, class ALLOCATOR, 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>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        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  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class TARGET_TYPE, class ALLOCATOR, class... ARGS>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
    template <class TARGET_TYPE, class ALLOCATOR, class... ARGS>
    static void emplace(TARGET_TYPE                               *toBegin,
                        TARGET_TYPE                               *toEnd,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
    template <class TARGET_TYPE, class ALLOCATOR, class... ARGS>
    static void emplace(TARGET_TYPE                  *toBegin,
                        TARGET_TYPE                  *toEnd,
                        ALLOCATOR                     allocator,
                        bslmf::MetaInt<e_NIL_TRAITS> *,
                        BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
// }}} END GENERATED CODE
#endif

    template <class TARGET_TYPE, class ALLOCATOR>
    static void erase(TARGET_TYPE                               *first,
                      TARGET_TYPE                               *middle,
                      TARGET_TYPE                               *last,
                      ALLOCATOR                                  allocator,
                      bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void erase(TARGET_TYPE                *first,
                      TARGET_TYPE                *middle,
                      TARGET_TYPE                *last,
                      ALLOCATOR                   allocator,
                      bslmf::MetaInt<e_NIL_TRAITS> *);
        // These functions follow the 'erase' contract.  Note that if (template
        // parameter) 'TARGET_TYPE' is bit-wise moveable, then this operation
        // can be implemented by first bit-wise moving the elements in
        // '[middle, last)' towards first, and destroying
        // '[ last - (middle - first), last)'; note that this cannot throw
        // exceptions.

    template <class TARGET_TYPE, class ALLOCATOR>
    static void insert(TARGET_TYPE                               *toBegin,
                       TARGET_TYPE                               *toEnd,
                       const TARGET_TYPE&                         value,
                       size_type                                  numElements,
                       ALLOCATOR                                  allocator,
                       bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void insert(TARGET_TYPE                               *toBegin,
                       TARGET_TYPE                               *toEnd,
                       const TARGET_TYPE&                         value,
                       size_type                                  numElements,
                       ALLOCATOR                                  allocator,
                       bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void insert(TARGET_TYPE                  *toBegin,
                       TARGET_TYPE                  *toEnd,
                       const TARGET_TYPE&            value,
                       size_type                     numElements,
                       ALLOCATOR                     allocator,
                       bslmf::MetaInt<e_NIL_TRAITS> *);
        // These functions follow the 'insert' contract.  Note that if
        // 'TARGET_TYPE' is bit-wise copyable, then this operation is simply
        // 'memmove' followed by 'bitwiseFillN'.  If 'TARGET_TYPE' is bit-wise
        // moveable, then this operation can still be optimized using 'memmove'
        // followed by repeated assignments, but a guard needs to be set up.
        // The last argument is for removing overload ambiguities and is not
        // used.

    template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
    static void insert(TARGET_TYPE                             *toBegin,
                       TARGET_TYPE                             *toEnd,
                       FWD_ITER                                 fromBegin,
                       FWD_ITER                                 fromEnd,
                       size_type                                numElements,
                       ALLOCATOR                                allocator,
                       bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void insert(TARGET_TYPE                               *toBegin,
                       TARGET_TYPE                               *toEnd,
                       const TARGET_TYPE                         *fromBegin,
                       const TARGET_TYPE                         *fromEnd,
                       size_type                                  numElements,
                       ALLOCATOR                                  allocator,
                       bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
    static void insert(TARGET_TYPE                               *toBegin,
                       TARGET_TYPE                               *toEnd,
                       FWD_ITER                                   fromBegin,
                       FWD_ITER                                   fromEnd,
                       size_type                                  numElements,
                       ALLOCATOR                                  allocator,
                       bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *);
    template <class FWD_ITER, class ALLOCATOR>
    static void insert(void                                   **toBegin,
                       void                                   **toEnd,
                       FWD_ITER                                 fromBegin,
                       FWD_ITER                                 fromEnd,
                       size_type                                numElements,
                       ALLOCATOR                                allocator,
                       bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *);
    template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
    static void insert(TARGET_TYPE                  *toBegin,
                       TARGET_TYPE                  *toEnd,
                       FWD_ITER                      fromBegin,
                       FWD_ITER                      fromEnd,
                       size_type                     numElements,
                       ALLOCATOR                     allocator,
                       bslmf::MetaInt<e_NIL_TRAITS> *);
        // These functions follow the 'insert' contract.  Note that if
        // 'TARGET_TYPE' is bit-wise copyable and 'FWD_ITER' is convertible to
        // 'const TARGET_TYPE *', then this operation is simply 'memmove'
        // followed by 'memcpy'.  If 'TARGET_TYPE' is bit-wise moveable and
        // 'FWD_ITER' is convertible to 'const TARGET_TYPE *', then this
        // operation can still be optimized using 'memmove' followed by
        // repeated copies.  The last argument is for removing overload
        // ambiguities and is not used.

    template <class TARGET_TYPE, class ALLOCATOR>
    static void moveInsert(
                       TARGET_TYPE                                *toBegin,
                       TARGET_TYPE                                *toEnd,
                       TARGET_TYPE                               **lastPtr,
                       TARGET_TYPE                                *first,
                       TARGET_TYPE                                *last,
                       size_type                                   numElements,
                       ALLOCATOR                                   allocator,
                       bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>  *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void moveInsert(TARGET_TYPE                   *toBegin,
                           TARGET_TYPE                   *toEnd,
                           TARGET_TYPE                  **lastPtr,
                           TARGET_TYPE                   *first,
                           TARGET_TYPE                   *last,
                           size_type                      numElements,
                           ALLOCATOR                      allocator,
                           bslmf::MetaInt<e_NIL_TRAITS>  *);
        // These functions follow the 'moveInsert' contract.  Note that if
        // 'TARGET_TYPE' is at least bit-wise moveable, then this operation is
        // simply 'memmove' followed by 'memcpy'.

    template <class TARGET_TYPE>
    static void rotate(TARGET_TYPE                               *begin,
                       TARGET_TYPE                               *middle,
                       TARGET_TYPE                               *end,
                       bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *);
    template <class TARGET_TYPE>
    static void rotate(TARGET_TYPE                  *begin,
                       TARGET_TYPE                  *middle,
                       TARGET_TYPE                  *end,
                       bslmf::MetaInt<e_NIL_TRAITS> *);
        // These functions follow the 'rotate' contract, but the first overload
        // is optimized when the parameterized 'TARGET_TYPE' is bit-wise
        // moveable.  The last argument is for removing overload ambiguities
        // and is not used.  Note that if 'TARGET_TYPE' is bit-wise moveable,
        // the 'rotate(char*, char*, char*)' can be used, enabling to take the
        // whole implementation out-of-line.

    template <class ALLOCATOR>
    static void shiftAndInsert(
             typename bsl::allocator_traits<ALLOCATOR>::pointer      begin,
             typename bsl::allocator_traits<ALLOCATOR>::pointer      end,
             bslmf::MovableRef<
             typename bsl::allocator_traits<ALLOCATOR>::value_type>  value,
             ALLOCATOR                                               allocator,
             bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS>              *);
    template <class ALLOCATOR>
    static void shiftAndInsert(
             typename bsl::allocator_traits<ALLOCATOR>::pointer      begin,
             typename bsl::allocator_traits<ALLOCATOR>::pointer      end,
             bslmf::MovableRef<
             typename bsl::allocator_traits<ALLOCATOR>::value_type>  value,
             ALLOCATOR                                               allocator,
             bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>              *);
    template <class ALLOCATOR>
    static void shiftAndInsert(
             typename bsl::allocator_traits<ALLOCATOR>::pointer      begin,
             typename bsl::allocator_traits<ALLOCATOR>::pointer      end,
             bslmf::MovableRef<
             typename bsl::allocator_traits<ALLOCATOR>::value_type>  value,
             ALLOCATOR                                               allocator,
             bslmf::MetaInt<e_NIL_TRAITS>                           *);
        // Shift the specified '[begin, end)' sequence one position right, then
        // insert the specified 'value' at the position pointed by 'begin'.
        // The specified 'allocator' is used for the element construction.  The
        // behavior is undefined unless the specified '[begin, end)' sequence
        // contains at least one element.

    // 'bitwise' METHODS
    static void bitwiseRotate(char *begin, char *middle, char *end);
        // This function follows the 'rotate' contract, but by using bit-wise
        // moves on the underlying 'char' array.

    static void bitwiseRotateBackward(char *begin, char *middle, char *end);
        // Move the characters in the array starting at the specified 'first'
        // address and ending immediately before the specified 'middle' address
        // to the array of the same length ending at the specified 'last'
        // address (and thus starting at the 'last - (middle - first)'
        // address), and move the elements previously in the array starting at
        // 'middle' and ending at 'last' down to the 'first' address.  The
        // behavior is undefined unless
        // 'middle - begin <= k_INPLACE_BUFFER_SIZE'.

    static void bitwiseRotateForward(char *begin, char *middle, char *end);
        // Move the characters in the array starting at the specified 'first'
        // address and ending immediately before the specified 'middle' address
        // to the array of the same length ending at the specified 'last'
        // address (and thus starting at the 'last - (middle - first)'
        // address), and move the elements previously in the array starting at
        // 'middle' and ending at 'last' down to the 'first' address.  The
        // behavior is undefined unless
        // 'end - middle <= k_INPLACE_BUFFER_SIZE'.

    static void bitwiseSwapRanges(char *begin, char *middle, char *end);
        // Swap the characters in the array starting at the specified 'first'
        // address and ending immediately before the specified 'middle' address
        // with the array of the same length starting at the 'middle' address
        // and ending at the specified 'last' address.  The behavior is
        // undefined unless 'middle - begin == end - middle'.

    template <class FORWARD_ITERATOR>
    static bool isInvalidRange(FORWARD_ITERATOR begin, FORWARD_ITERATOR end);
    template <class TARGET_TYPE>
    static bool isInvalidRange(TARGET_TYPE *begin, TARGET_TYPE *end);
        // Return 'true' if the specified 'begin' and the specified 'end'
        // provably do not form a valid semi-open range, '[begin, end)', and
        // 'false' otherwise.  Note that 'begin == null == end' produces a
        // valid range, and any other use of the null pointer value will return
        // 'true'.  Also note that this function is intended to support
        // testing, primarily through assertions, so will return 'false' unless
        // it can *prove* that the passed range is invalid.  Currently, this
        // function can prove invalid ranges only for pointers, although should
        // also encompass generic random access iterators in a future update,
        // where iterator tag types are levelized below 'bslalg'.
};

// ============================================================================
//                      INLINE FUNCTION DEFINITIONS
// ============================================================================
// IMPLEMENTATION NOTES: Specializations of 'uninitializedFillN' for most
// fundamental types are not templates nor inline, and thus can be found in the
// '.cpp' file.

                   // =====================================
                   // struct ArrayPrimitives_CanBitwiseCopy
                   // =====================================

template <class FROM_TYPE, class TO_TYPE>
struct ArrayPrimitives_CanBitwiseCopy
    : bsl::integral_constant<bool,
                             bsl::is_same<
                                   typename bsl::remove_const<FROM_TYPE>::type,
                                   typename bsl::remove_const<TO_TYPE  >::type>
                                                                        ::value
                          && bsl::is_trivially_copyable<
                                   typename bsl::remove_const<TO_TYPE  >::type>
                                                                        ::value
                            > {
};

                       // ----------------------
                       // struct ArrayPrimitives
                       // ----------------------

template <class ALLOCATOR>
inline
void ArrayPrimitives::uninitializedFillN(
      typename bsl::allocator_traits<ALLOCATOR>::pointer           begin,
      size_type                                                    numElements,
      const typename bsl::allocator_traits<ALLOCATOR>::value_type& value,
      ALLOCATOR                                                    allocator)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        // We provide specialized overloads of 'uninitializedFillN' for
        // fundamental and pointer types.  However, function pointers can have
        // extern "C" linkage and SunPro doesn't match them properly with the
        // pointer template function overload in 'Imp', so we resort to the
        // general case for those.

        k_IS_FUNCTION_POINTER = bslmf::IsFunctionPointer<TargetType>::value,
        k_IS_FUNDAMENTAL      = bsl::is_fundamental<TargetType>::value,
        k_IS_POINTER          = bsl::is_pointer<TargetType>::value,

        k_IS_FUNDAMENTAL_OR_POINTER = k_IS_FUNDAMENTAL ||
                                     (k_IS_POINTER && !k_IS_FUNCTION_POINTER),

        k_IS_BITWISECOPYABLE  = bsl::is_trivially_copyable<TargetType>::value,

        k_VALUE =
                 k_IS_FUNDAMENTAL_OR_POINTER ? Imp::e_IS_FUNDAMENTAL_OR_POINTER
               : k_IS_BITWISECOPYABLE        ? Imp::e_BITWISE_COPYABLE_TRAITS
               :                               Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::uninitializedFillN(begin,
                                            value,
                                            numElements,
                                            &allocator,
                                            (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::uninitializedFillN(TARGET_TYPE        *begin,
                                         size_type           numElements,
                                         const TARGET_TYPE&  value,
                                         bslma::Allocator   *basicAllocator)
{
    uninitializedFillN<bsl::allocator<TARGET_TYPE> >(begin,
                                                     numElements,
                                                     value,
                                                     basicAllocator);
}

template <class ALLOCATOR, class FWD_ITER>
void ArrayPrimitives::copyConstruct(
                  typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin,
                  FWD_ITER                                           fromBegin,
                  FWD_ITER                                           fromEnd,
                  ALLOCATOR                                          allocator)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);

    BSLMF_ASSERT(!bsl::is_pointer<FWD_ITER>::value);
    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;
    typedef typename FWD_ITER::value_type FwdTarget;
        // Overload resolution will handle the case where 'FWD_ITER' is a raw
        // pointer, so we need handle only user-defined iterators.  As 'bslalg'
        // is levelized below 'bslstl' we cannot use 'iterator_traits', but
        // rely on the same property as 'iterator_traits' that this typedef
        // must be defined for any standard-conforming iterator, unless the
        // iterator explicitly specialized the 'std::iterator_traits' template.
        // In practice, iterators always prefer to provide the member typedef
        // than specialize the traits as it is a much simpler implementation,
        // so this assumption is good enough.
        //
        // Also note that as we know that 'FWD_ITER' is not a pointer, then we
        // cannot take advantage of bitwise copying as we do not have pointers
        // to pass to the 'memcpy' describing the whole range.  It is not worth
        // the effort to try to bitwise copy one element at a time.

    typedef typename bsl::remove_pointer<TargetType>::type RemovePtrTarget;
        // We want to detect the special case of copying function pointers to
        // 'void *' or 'const void *' pointers.

    enum {
        k_ITER_TO_FUNC_PTRS   = bslmf::IsFunctionPointer<FwdTarget>::value,
        k_TARGET_IS_VOID_PTR  = bsl::is_pointer<TargetType>::value &&
                                bsl::is_void<RemovePtrTarget>::value,

        k_VALUE = k_ITER_TO_FUNC_PTRS && k_TARGET_IS_VOID_PTR
                ? Imp::e_IS_ITERATOR_TO_FUNCTION_POINTER
                : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::copyConstruct(toBegin,
                                       fromBegin,
                                       fromEnd,
                                       allocator,
                                       (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE, class FWD_ITER>
inline
void ArrayPrimitives::copyConstruct(TARGET_TYPE      *toBegin,
                                    FWD_ITER          fromBegin,
                                    FWD_ITER          fromEnd,
                                    bslma::Allocator *basicAllocator)
{
    copyConstruct<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                fromBegin,
                                                fromEnd,
                                                basicAllocator);
}

template <class ALLOCATOR, class SOURCE_TYPE>
inline
void ArrayPrimitives::copyConstruct(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 SOURCE_TYPE                                        *fromBegin,
                 SOURCE_TYPE                                        *fromEnd,
                 ALLOCATOR                                           allocator)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_ARE_PTRS_TO_PTRS = bsl::is_pointer<TargetType>::value &&
                             bsl::is_pointer<SOURCE_TYPE>::value,
        k_IS_BITWISECOPYABLE  =
               ArrayPrimitives_CanBitwiseCopy<SOURCE_TYPE, TargetType>::value,
        k_VALUE = k_ARE_PTRS_TO_PTRS   ? Imp::e_IS_POINTER_TO_POINTER
                : k_IS_BITWISECOPYABLE ? Imp::e_BITWISE_COPYABLE_TRAITS
                :                        Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::copyConstruct(toBegin,
                                       fromBegin,
                                       fromEnd,
                                       allocator,
                                       (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE, class SOURCE_TYPE>
inline
void ArrayPrimitives::copyConstruct(TARGET_TYPE      *toBegin,
                                    SOURCE_TYPE      *fromBegin,
                                    SOURCE_TYPE      *fromEnd,
                                    bslma::Allocator *basicAllocator)
{
    copyConstruct<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                fromBegin,
                                                fromEnd,
                                                basicAllocator);
}

template <class ALLOCATOR>
inline
void ArrayPrimitives::defaultConstruct(
                typename bsl::allocator_traits<ALLOCATOR>::pointer begin,
                size_type                                          numElements,
                ALLOCATOR                                          allocator)
{
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLS_ASSERT_SAFE(begin || 0 == numElements);

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_fundamental<TargetType>::value
               || bsl::is_enum<TargetType>::value
               || bsl::is_pointer<TargetType>::value
#if !defined(BSLALG_ARRAYPRIMITIVES_NON_ZERO_NULL_VALUE_FOR_MEMBER_POINTERS)
               || bsl::is_member_pointer<TargetType>::value
#endif
              ? Imp::e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS
              : bsl::is_trivially_copyable<TargetType>::value &&
                bsl::is_trivially_default_constructible<TargetType>::value
                  ? Imp::e_BITWISE_COPYABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::defaultConstruct(begin,
                                          numElements,
                                          allocator,
                                          (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::defaultConstruct(TARGET_TYPE      *begin,
                                       size_type         numElements,
                                       bslma::Allocator *basicAllocator)
{
    defaultConstruct<bsl::allocator<TARGET_TYPE> >(begin,
                                                   numElements,
                                                   basicAllocator);
}

template <class ALLOCATOR>
inline
void ArrayPrimitives::destructiveMove(
                  typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin,
                  typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin,
                  typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd,
                  ALLOCATOR                                          allocator)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bslmf::IsBitwiseMoveable<TargetType>::value
              ? Imp::e_BITWISE_MOVEABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::destructiveMove(toBegin,
                                         fromBegin,
                                         fromEnd,
                                         allocator,
                                         (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::destructiveMove(TARGET_TYPE      *toBegin,
                                      TARGET_TYPE      *fromBegin,
                                      TARGET_TYPE      *fromEnd,
                                      bslma::Allocator *basicAllocator)
{
    destructiveMove<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                  fromBegin,
                                                  fromEnd,
                                                  basicAllocator);
}

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10
#endif
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#endif
#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 0
template <class ALLOCATOR>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin);

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 1
template <class ALLOCATOR, class ARGS_01>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 2
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 3
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 4
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 5
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04,
                           class ARGS_05>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 6
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04,
                           class ARGS_05,
                           class ARGS_06>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 7
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04,
                           class ARGS_05,
                           class ARGS_06,
                           class ARGS_07>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 8
template <class ALLOCATOR, 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 ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_08,arguments_08));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 9
template <class ALLOCATOR, 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 ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_08,arguments_08),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_09,arguments_09));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 10
template <class ALLOCATOR, 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 ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_08,arguments_08),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_09,arguments_09),
                          BSLS_COMPILERFEATURES_FORWARD(ARGS_10,arguments_10));

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class ALLOCATOR, class... ARGS>
void ArrayPrimitives::destructiveMoveAndEmplace(
                typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
                typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
                ALLOCATOR                                           allocator,
                BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
{

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;


    TargetType *toPositionBegin = toBegin + (position - fromBegin);

    bsl::allocator_traits<ALLOCATOR>::construct(
                             allocator,
                             toPositionBegin,
                             BSLS_COMPILERFEATURES_FORWARD(ARGS,arguments)...);

    TargetType *toPositionEnd = toPositionBegin + 1;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);


    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;
    guard.moveEnd(fromEnd - position);


    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;
    guard.release();
}
// }}} END GENERATED CODE
#endif

template <class ALLOCATOR>
void ArrayPrimitives::destructiveMoveAndInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               size_type                                           numElements,
               ALLOCATOR                                           allocator)
{
    // Key to the transformation diagrams:
    //..
    //  A...H   original contents of '[fromBegin, fromEnd)'  ("source")
    //  v...v   default-constructed values                   ("input")
    //  ; ...   contents of '[toBegin, toEnd)'               ("destination")
    //  ..:..   position of 'fromEndPtr' in the input
    //  _____   uninitialized array elements
    //  [...]   part of array protected by an exception guard object
    //..

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;

    // Note: Construct default values.
    //..
    //  Transformation: ABCDEFGH: ; _____________[]
    //               => ABCDEFGH: ; ____[vvvvv]____
    //..

    TargetType *toPositionBegin = toBegin + (position - fromBegin);
    defaultConstruct(toPositionBegin, numElements, allocator);

    TargetType *toPositionEnd = toPositionBegin + numElements;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);

    //..
    //  Transformation: ABCDEFGH: ; ____[vvvvv]____
    //               => ABCD:____ ; ____[vvvvvEFGH]
    //..

    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;  // shorten input range after partial destruction
    guard.moveEnd(fromEnd - position);  // toEnd

    //..
    //  Transformation: ABCD:____ ; ____[vvvvvEFGH]
    //               => :________ ; ABCDvvvvvEFGH[]
    //..

    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;  // empty input range after final destruction
    guard.release();
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::destructiveMoveAndInsert(
                                             TARGET_TYPE       *toBegin,
                                             TARGET_TYPE      **fromEndPtr,
                                             TARGET_TYPE       *fromBegin,
                                             TARGET_TYPE       *position,
                                             TARGET_TYPE       *fromEnd,
                                             size_type          numElements,
                                             bslma::Allocator  *basicAllocator)
{
    destructiveMoveAndInsert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                           fromEndPtr,
                                                           fromBegin,
                                                           position,
                                                           fromEnd,
                                                           numElements,
                                                           basicAllocator);
}

template <class ALLOCATOR>
void ArrayPrimitives::destructiveMoveAndInsert(
     typename bsl::allocator_traits<ALLOCATOR>::pointer            toBegin,
     typename bsl::allocator_traits<ALLOCATOR>::pointer           *fromEndPtr,
     typename bsl::allocator_traits<ALLOCATOR>::pointer            fromBegin,
     typename bsl::allocator_traits<ALLOCATOR>::pointer            position,
     typename bsl::allocator_traits<ALLOCATOR>::pointer            fromEnd,
     const typename bsl::allocator_traits<ALLOCATOR>::value_type&  value,
     size_type                                                     numElements,
     ALLOCATOR                                                     allocator)
{
    // Key to the transformation diagrams:
    //..
    //  A...H   original contents of '[fromBegin, fromEnd)'  ("source")
    //  v...v   copies of 'value'                            ("input")
    //  ; ...   contents of '[toBegin, toEnd)'               ("destination")
    //  ..:..   position of 'fromEndPtr' in the input
    //  _____   uninitialized array elements
    //  [...]   part of array protected by an exception guard object
    //..

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;

    // Note: Construct copies of 'value' first in case 'value' is a reference
    // in the input range, which would be invalidated by any of the following
    // moves.
    //
    //..
    //  Transformation: ABCDEFGH: ; _____________[]
    //               => ABCDEFGH: ; ____[vvvvv]____
    //..

    TargetType *toPositionBegin = toBegin + (position - fromBegin);
    uninitializedFillN(toPositionBegin, numElements, value, allocator);

    TargetType *toPositionEnd = toPositionBegin + numElements;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);

    //..
    //  Transformation: ABCDEFGH: ; ____[vvvvv]____
    //               => ABCD:____ ; ____[vvvvvEFGH]
    //..

    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;  // shorten input range after partial destruction
    guard.moveEnd(fromEnd - position);  // toEnd

    //..
    //  Transformation: ABCD:____ ; ____[vvvvvEFGH]
    //               => :________ ; ABCDvvvvvEFGH[]
    //..

    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;  // empty input range after final destruction
    guard.release();
}

template <class TARGET_TYPE>
void ArrayPrimitives::destructiveMoveAndInsert(
                                           TARGET_TYPE         *toBegin,
                                           TARGET_TYPE        **fromEndPtr,
                                           TARGET_TYPE         *fromBegin,
                                           TARGET_TYPE         *position,
                                           TARGET_TYPE         *fromEnd,
                                           const TARGET_TYPE&   value,
                                           size_type            numElements,
                                           bslma::Allocator    *basicAllocator)
{
    destructiveMoveAndInsert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                           fromEndPtr,
                                                           fromBegin,
                                                           position,
                                                           fromEnd,
                                                           value,
                                                           numElements,
                                                           basicAllocator);
}

template <class ALLOCATOR, class FWD_ITER>
void ArrayPrimitives::destructiveMoveAndInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               FWD_ITER                                            first,
               FWD_ITER                                            last,
               size_type                                           numElements,
               ALLOCATOR                                           allocator)
{
    // Key to the transformation diagrams:
    //..
    //  A...H   original contents of '[fromBegin, fromEnd)'  ("source")
    //  t...z   original contents of '[first, last)'         ("input")
    //  ; ...   contents of '[toBegin, toEnd)'               ("destination")
    //  ..:..   position of 'fromEndPtr' in the input
    //  _____   uninitialized array elements
    //  [...]   part of array protected by an exception guard object
    //..

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *fromEndPtr = fromEnd;

    // Note: Construct copies of 'value' first in case 'value' is a reference
    // in the input range, which would be invalidated by any of the following
    // moves:
    //..
    //  Transformation: ABCDEFGH: ; _________[]____
    //               => ABCDEFGH: ; ____[tuvxy]____
    //..

    TargetType *toPositionBegin = toBegin + (position - fromBegin);
    copyConstruct(toPositionBegin, first, last, allocator);

    TargetType *toPositionEnd   = toPositionBegin + numElements;

    AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin,
                                                     toPositionEnd,
                                                     allocator);

    //..
    //  Transformation: ABCDEFGH: ; ____[tuvxy]____
    //               => ABCD:____ ; ____[tuvxyEFGH]
    //..

    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;  // shorten input range after partial destruction
    guard.moveEnd(fromEnd - position);  // toEnd

    //..
    //  Transformation: ABCD:____ ; ____[tuvxyEFGH]
    //               => :________ ; ABCDtuvxyEFGH[]
    //..

    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;  // empty input range after final destruction
    guard.release();
}

template <class TARGET_TYPE, class FWD_ITER>
inline
void ArrayPrimitives::destructiveMoveAndInsert(
                                             TARGET_TYPE       *toBegin,
                                             TARGET_TYPE      **fromEndPtr,
                                             TARGET_TYPE       *fromBegin,
                                             TARGET_TYPE       *position,
                                             TARGET_TYPE       *fromEnd,
                                             FWD_ITER           first,
                                             FWD_ITER           last,
                                             size_type          numElements,
                                             bslma::Allocator  *basicAllocator)
{
    destructiveMoveAndInsert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                           fromEndPtr,
                                                           fromBegin,
                                                           position,
                                                           fromEnd,
                                                           first,
                                                           last,
                                                           numElements,
                                                           basicAllocator);
}

template <class ALLOCATOR>
void ArrayPrimitives::destructiveMoveAndMoveInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *lastPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  position,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  first,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  last,
               size_type                                           numElements,
               ALLOCATOR                                           allocator)
{
    // Key to the transformation diagrams:
    //..
    //  A...H   original contents of '[fromBegin, fromEnd)'  ("source")
    //  t...z   original contents of '[first, last)'         ("input")
    //  ; ...   contents of '[toBegin, toEnd)'               ("destination")
    //  ..:..   position of 'fromEndPtr' in the input
    //  _____   uninitialized array elements
    //  [...]   part of array protected by an exception guard object
    //..

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    *lastPtr = last;
    *fromEndPtr = fromEnd;

    //..
    //  Transformation: ABCDEFGH: ; _____________[]
    //               => ABCD:____ ; _________[EFGH]
    //..

    TargetType *toPositionBegin = toBegin + (position - fromBegin);
    TargetType *toPositionEnd   = toPositionBegin + numElements;

    destructiveMove(toPositionEnd,
                    position,
                    fromEnd,
                    allocator);

    *fromEndPtr = position;  // shorten input range after partial destruction

    AutoArrayDestructor<TargetType, ALLOCATOR>
                                   guard(toPositionEnd,
                                         toPositionEnd + (fromEnd - position),
                                         allocator);

    //..
    //  Transformation: ABCD:____ ; _________[EFGH]
    //               => ABCD:____ ; _____[tuvwEFGH]
    //..

    destructiveMove(toPositionBegin,
                    first,
                    last,
                    allocator);

    *lastPtr = first;
    guard.moveBegin(-static_cast<difference_type>(numElements));

    //..
    //  Transformation: ABCD:____ ; ____[tuvwEFGH]
    //               => :________ ; ABCDtuvwEFGH[]
    //..

    destructiveMove(toBegin,
                    fromBegin,
                    position,
                    allocator);

    *fromEndPtr = fromBegin;  // empty input range after final destruction
    guard.release();
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::destructiveMoveAndMoveInsert(
                                             TARGET_TYPE       *toBegin,
                                             TARGET_TYPE      **fromEndPtr,
                                             TARGET_TYPE      **lastPtr,
                                             TARGET_TYPE       *fromBegin,
                                             TARGET_TYPE       *position,
                                             TARGET_TYPE       *fromEnd,
                                             TARGET_TYPE       *first,
                                             TARGET_TYPE       *last,
                                             size_type          numElements,
                                             bslma::Allocator  *basicAllocator)
{
    destructiveMoveAndMoveInsert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                               fromEndPtr,
                                                               lastPtr,
                                                               fromBegin,
                                                               position,
                                                               fromEnd,
                                                               first,
                                                               last,
                                                               numElements,
                                                               basicAllocator);
}

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10
#endif
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#endif
#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0
template <class ALLOCATOR>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0);
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1
template <class ALLOCATOR, class ARGS_01>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
        BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
        BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
        BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04,
                           class ARGS_05>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04,
                           class ARGS_05,
                           class ARGS_06>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7
template <class ALLOCATOR, class ARGS_01,
                           class ARGS_02,
                           class ARGS_03,
                           class ARGS_04,
                           class ARGS_05,
                           class ARGS_06,
                           class ARGS_07>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8
template <class ALLOCATOR, 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
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9
template <class ALLOCATOR, 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
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10
template <class ALLOCATOR, 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
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10


#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0
template <class TARGET_TYPE>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              bslma::Allocator *basicAllocator)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 basicAllocator);
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1
template <class TARGET_TYPE, class ARGS_01>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 basicAllocator,
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2
template <class TARGET_TYPE, class ARGS_01,
                             class ARGS_02>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              bslma::Allocator *basicAllocator,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 basicAllocator,
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3
template <class TARGET_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 basicAllocator,
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4
template <class TARGET_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5
template <class TARGET_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6
template <class TARGET_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7
template <class TARGET_TYPE, class ARGS_01,
                             class ARGS_02,
                             class ARGS_03,
                             class ARGS_04,
                             class ARGS_05,
                             class ARGS_06,
                             class ARGS_07>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8
template <class TARGET_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
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9
template <class TARGET_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
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10
template <class TARGET_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
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              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)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class ALLOCATOR, class... ARGS>
inline
void ArrayPrimitives::emplace(
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
                 typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
                 ALLOCATOR                                           allocator,
                 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::emplace(
        toBegin,
        toEnd,
        allocator,
        (bslmf::MetaInt<k_VALUE> *)0,
        BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
}

template <class TARGET_TYPE, class... ARGS>
inline
void ArrayPrimitives::emplace(TARGET_TYPE      *toBegin,
                              TARGET_TYPE      *toEnd,
                              bslma::Allocator *basicAllocator,
                              BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    emplace<bsl::allocator<TARGET_TYPE> >(
                                 toBegin,
                                 toEnd,
                                 basicAllocator,
                                 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
}

// }}} END GENERATED CODE
#endif

template <class ALLOCATOR>
inline
void ArrayPrimitives::erase(
                  typename bsl::allocator_traits<ALLOCATOR>::pointer first,
                  typename bsl::allocator_traits<ALLOCATOR>::pointer middle,
                  typename bsl::allocator_traits<ALLOCATOR>::pointer last,
                  ALLOCATOR                                          allocator)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    if (first == middle) { // erasing empty range O(1) versus O(N): Do not
                           // remove!
        return;                                                       // RETURN
    }

    enum {
        k_VALUE = bslmf::IsBitwiseMoveable<TargetType>::value
              ? Imp::e_BITWISE_MOVEABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::erase(first,
                               middle,
                               last,
                               allocator,
                               (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::erase(TARGET_TYPE      *first,
                            TARGET_TYPE      *middle,
                            TARGET_TYPE      *last,
                            bslma::Allocator *basicAllocator)
{
    erase<bsl::allocator<TARGET_TYPE> >(first,
                                        middle,
                                        last,
                                        basicAllocator);
}

template <class ALLOCATOR>
inline
void ArrayPrimitives::insert(
              typename bsl::allocator_traits<ALLOCATOR>::pointer     toBegin,
              typename bsl::allocator_traits<ALLOCATOR>::pointer     toEnd,
              bslmf::MovableRef<
              typename bsl::allocator_traits<ALLOCATOR>::value_type> value,
              ALLOCATOR                                              allocator)
{
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    if (toBegin != toEnd) {
        // Insert in the middle.  Note that there is no strong exception
        // guarantee if copy constructor, move constructor, or assignment
        // operator throw.

        enum {
            k_VALUE = bsl::is_trivially_copyable<TargetType>::value
                ? Imp::e_BITWISE_COPYABLE_TRAITS
                : bslmf::IsBitwiseMoveable<TargetType>::value
                    ? Imp::e_BITWISE_MOVEABLE_TRAITS
                    : Imp::e_NIL_TRAITS
        };

        ArrayPrimitives_Imp::shiftAndInsert(toBegin,
                                            toEnd,
                                            bslmf::MovableRefUtil::move(value),
                                            allocator,
                                            (bslmf::MetaInt<k_VALUE>*)0);
    }
    else { // toBegin == toEnd
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toBegin, bslmf::MovableRefUtil::move(value));
    }
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::insert(TARGET_TYPE                    *toBegin,
                             TARGET_TYPE                    *toEnd,
                             bslmf::MovableRef<TARGET_TYPE>  value,
                             bslma::Allocator               *basicAllocator)
{
    insert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                         toEnd,
                                         bslmf::MovableRefUtil::move(value),
                                         basicAllocator);
}

template <class ALLOCATOR>
void ArrayPrimitives::insert(
      typename bsl::allocator_traits<ALLOCATOR>::pointer           toBegin,
      typename bsl::allocator_traits<ALLOCATOR>::pointer           toEnd,
      const typename bsl::allocator_traits<ALLOCATOR>::value_type& value,
      size_type                                                    numElements,
      ALLOCATOR                                                    allocator)
{
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    if (0 == numElements) {
        return;                                                       // RETURN
    }

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : bslmf::IsBitwiseMoveable<TargetType>::value
                  ? Imp::e_BITWISE_MOVEABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::insert(toBegin,
                                toEnd,
                                value,
                                numElements,
                                allocator,
                                (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::insert(TARGET_TYPE        *toBegin,
                             TARGET_TYPE        *toEnd,
                             const TARGET_TYPE&  value,
                             size_type           numElements,
                             bslma::Allocator   *basicAllocator)
{
    insert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                         toEnd,
                                         value,
                                         numElements,
                                         basicAllocator);
}

template <class ALLOCATOR, class FWD_ITER>
void ArrayPrimitives::insert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
               FWD_ITER                                            fromBegin,
               FWD_ITER                                            fromEnd,
               size_type                                           numElements,
               ALLOCATOR                                           allocator)
{
    if (0 == numElements) {
        return;                                                       // RETURN
    }

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    BSLMF_ASSERT(!bsl::is_pointer<FWD_ITER>::value);

    typedef typename FWD_ITER::value_type FwdTarget;
        // Overload resolution will handle the case where 'FWD_ITER' is a raw
        // pointer, so we need handle only user-defined iterators.  As 'bslalg'
        // is levelized below 'bslstl' we cannot use 'iterator_traits', but
        // rely on the same property as 'iterator_traits' that this typedef
        // must be defined for any standard-conforming iterator, unless the
        // iterator explicitly specialized the 'std::iterator_traits' template.
        // In practice, iterators always prefer to provide the member typedef
        // than specialize the traits as it is a much simpler implementation,
        // so this assumption is good enough.
        //
        // Also note that as we know that 'FWD_ITER' is not a pointer, then we
        // cannot take advantage of bitwise copying as we do not have pointers
        // to pass to the 'memcpy' describing the whole range.  It is not worth
        // the effort to try to bitwise copy one element at a time.

    typedef typename bsl::remove_pointer<TargetType>::type RemovePtrTarget;
        // We want to detect the special case of copying function pointers to
        // 'void *' or 'const void *' pointers.

    enum {
        k_ITER_TO_FUNC_PTRS  = bslmf::IsFunctionPointer<FwdTarget>::value,
        k_TARGET_IS_VOID_PTR = bsl::is_pointer<TargetType>::value &&
                               bsl::is_void<RemovePtrTarget>::value,

        k_VALUE = k_ITER_TO_FUNC_PTRS && k_TARGET_IS_VOID_PTR
                ? Imp::e_IS_ITERATOR_TO_FUNCTION_POINTER
                : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::insert(toBegin,
                                toEnd,
                                fromBegin,
                                fromEnd,
                                numElements,
                                allocator,
                                (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE, class FWD_ITER>
inline
void ArrayPrimitives::insert(TARGET_TYPE      *toBegin,
                             TARGET_TYPE      *toEnd,
                             FWD_ITER          fromBegin,
                             FWD_ITER          fromEnd,
                             size_type         numElements,
                             bslma::Allocator *basicAllocator)
{
    insert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                         toEnd,
                                         fromBegin,
                                         fromEnd,
                                         numElements,
                                         basicAllocator);
}

template <class ALLOCATOR, class SOURCE_TYPE>
void ArrayPrimitives::insert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
               SOURCE_TYPE                                        *fromBegin,
               SOURCE_TYPE                                        *fromEnd,
               size_type                                           numElements,
               ALLOCATOR                                           allocator)
{
    if (0 == numElements) {
        return;                                                       // RETURN
    }

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_ARE_PTRS_TO_PTRS   = bsl::is_pointer<TargetType>::value &&
                               bsl::is_pointer<SOURCE_TYPE>::value,
        k_IS_BITWISEMOVEABLE = bslmf::IsBitwiseMoveable<TargetType>::value,
        k_IS_BITWISECOPYABLE =
               ArrayPrimitives_CanBitwiseCopy<SOURCE_TYPE, TargetType>::value,
        k_VALUE = k_ARE_PTRS_TO_PTRS   ? Imp::e_IS_POINTER_TO_POINTER
                : k_IS_BITWISECOPYABLE ? Imp::e_BITWISE_COPYABLE_TRAITS
                : k_IS_BITWISEMOVEABLE ? Imp::e_BITWISE_MOVEABLE_TRAITS
                : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::insert(toBegin,
                                toEnd,
                                fromBegin,
                                fromEnd,
                                numElements,
                                allocator,
                                (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE, class SOURCE_TYPE>
inline
void ArrayPrimitives::insert(TARGET_TYPE      *toBegin,
                             TARGET_TYPE      *toEnd,
                             SOURCE_TYPE      *fromBegin,
                             SOURCE_TYPE      *fromEnd,
                             size_type         numElements,
                             bslma::Allocator *basicAllocator)
{
    insert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                         toEnd,
                                         fromBegin,
                                         fromEnd,
                                         numElements,
                                         basicAllocator);
}

template <class ALLOCATOR>
inline
void ArrayPrimitives::moveConstruct(
                  typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin,
                  typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin,
                  typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd,
                  ALLOCATOR                                          allocator)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bsl::is_trivially_copyable<TargetType>::value
                  ? Imp::e_BITWISE_COPYABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };

    ArrayPrimitives_Imp::moveConstruct(toBegin,
                                       fromBegin,
                                       fromEnd,
                                       allocator,
                                       (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::moveConstruct(TARGET_TYPE      *toBegin,
                                    TARGET_TYPE      *fromBegin,
                                    TARGET_TYPE      *fromEnd,
                                    bslma::Allocator *basicAllocator)
{
    moveConstruct<bsl::allocator<TARGET_TYPE> >(toBegin,
                                                fromBegin,
                                                fromEnd,
                                                basicAllocator);
}

template <class ALLOCATOR>
inline
void ArrayPrimitives::moveInsert(
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  toEnd,
               typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromBegin,
               typename bsl::allocator_traits<ALLOCATOR>::pointer  fromEnd,
               size_type                                           numElements,
               ALLOCATOR                                           allocator)
{
    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType;

    enum {
        k_VALUE = bslmf::IsBitwiseMoveable<TargetType>::value
              ? Imp::e_BITWISE_MOVEABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::moveInsert(toBegin,
                                    toEnd,
                                    fromEndPtr,
                                    fromBegin,
                                    fromEnd,
                                    numElements,
                                    allocator,
                                    (bslmf::MetaInt<k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::moveInsert(TARGET_TYPE       *toBegin,
                                 TARGET_TYPE       *toEnd,
                                 TARGET_TYPE      **fromEndPtr,
                                 TARGET_TYPE       *fromBegin,
                                 TARGET_TYPE       *fromEnd,
                                 size_type          numElements,
                                 bslma::Allocator  *basicAllocator)
{
    moveInsert<bsl::allocator<TARGET_TYPE> >(toBegin,
                                             toEnd,
                                             fromEndPtr,
                                             fromBegin,
                                             fromEnd,
                                             numElements,
                                             basicAllocator);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives::rotate(TARGET_TYPE *first,
                             TARGET_TYPE *middle,
                             TARGET_TYPE *last)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first,
                                                          middle));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle,
                                                          last));

    enum {
        k_VALUE = bslmf::IsBitwiseMoveable<TARGET_TYPE>::value
              ? Imp::e_BITWISE_MOVEABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    ArrayPrimitives_Imp::rotate(first,
                                middle,
                                last,
                                (bslmf::MetaInt<k_VALUE>*)0);
}

                     // --------------------------
                     // struct ArrayPrimitives_Imp
                     // --------------------------

// CLASS METHODS
template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::assign(TARGET_TYPE *srcStart,
                                 TARGET_TYPE *srcEnd,
                                 TARGET_TYPE& value)
{
    for ( ; srcStart != srcEnd; ++srcStart) {
        *srcStart = value;
    }
}

template <class FORWARD_ITERATOR>
inline
bool ArrayPrimitives_Imp::isInvalidRange(FORWARD_ITERATOR,
                                         FORWARD_ITERATOR)
{
    // Ideally would dispatch on random_access_iterator_tag to support
    // generalized random access iterators, but we are constrained by 'bsl'
    // levelization to not depend on 'bsl_iterator.h'.  As the intent is to
    // detect invalid ranges in assertions, the conservative choice is to
    // return 'false' always.  Note that this differs from the pointers case
    // below, which also disallows empty ranges.

    return false;
}

template <class TARGET_TYPE>
inline
bool ArrayPrimitives_Imp::isInvalidRange(TARGET_TYPE *begin,
                                         TARGET_TYPE *end)
{
    return !begin != !end || begin > end;
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::reverseAssign(TARGET_TYPE *dest,
                                        TARGET_TYPE *srcStart,
                                        TARGET_TYPE *srcEnd)
{
    TARGET_TYPE *destEnd = srcEnd - srcStart + dest;
    while (srcStart != srcEnd) {
        *--destEnd = *--srcEnd;
    }
}


                   // *** 'uninitializedFillN' overloads: ***

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      bool                                        *begin,
                      bool                                         value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLMF_ASSERT(sizeof(bool) == 1);

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::memset(reinterpret_cast<char *>(begin),  // odd, why not 'void *'?
                    static_cast<char>(value),
                    numElements);
    }
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      char                                        *begin,
                      char                                         value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::memset(begin, value, numElements);
    }
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      unsigned char                               *begin,
                      unsigned char                                value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::memset(begin, value, numElements);
    }
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      signed char                                 *begin,
                      signed char                                  value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::memset(begin, value, numElements);
    }
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      wchar_t                                     *begin,
                      wchar_t                                      value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::wmemset(begin, value, numElements);
    }
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      unsigned short                              *begin,
                      unsigned short                               value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    uninitializedFillN(reinterpret_cast<short *>(begin),
                       static_cast<short>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      unsigned int                                *begin,
                      unsigned int                                 value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    uninitializedFillN(reinterpret_cast<int *>(begin),
                       static_cast<int>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      long                                        *begin,
                      long                                         value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

#if defined(BSLS_PLATFORM_CPU_64_BIT) && !defined(BSLS_PLATFORM_OS_WINDOWS)
    uninitializedFillN(reinterpret_cast<bsls::Types::Int64 *>(begin),
                       static_cast<bsls::Types::Int64>(value),
                       numElements);
#else
    uninitializedFillN(reinterpret_cast<int *>(begin),
                       static_cast<int>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
#endif
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      unsigned long                               *begin,
                      unsigned long                                value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

#if defined(BSLS_PLATFORM_CPU_64_BIT) && !defined(BSLS_PLATFORM_OS_WINDOWS)
    uninitializedFillN(reinterpret_cast<bsls::Types::Int64 *>(begin),
                       static_cast<bsls::Types::Int64>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>*)0);
#else
    uninitializedFillN(reinterpret_cast<int *>(begin),
                       static_cast<int>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
#endif
}

inline
void ArrayPrimitives_Imp::uninitializedFillN(
                      bsls::Types::Uint64                         *begin,
                      bsls::Types::Uint64                          value,
                      size_type                                    numElements,
                      void                                        *,
                      bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    uninitializedFillN(reinterpret_cast<bsls::Types::Int64 *>(begin),
                       value,
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::uninitializedFillN(
                     TARGET_TYPE                                 **begin,
                     TARGET_TYPE                                  *value,
                     size_type                                     numElements,
                     void                                         *,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // Note: 'const'-correctness is respected because the next overload picks
    // up the 'const TARGET_TYPE' and will be a better match.  Note that we
    // cannot cast to 'const void **' (one would have to add 'const' at every
    // level, not just the innermost; i.e., 'const void *const *' would be
    // correct, 'const void **' is not [C++ Standard, 4.4 Qualification
    // conversions]).

    uninitializedFillN(reinterpret_cast<void **>(begin),
                       static_cast<void *>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::uninitializedFillN(
                     const TARGET_TYPE                           **begin,
                     const TARGET_TYPE                            *value,
                     size_type                                     numElements,
                     void                                         *,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // While it seems that this overload is subsumed by the previous template,
    // SunPro does not detect it.

    uninitializedFillN(reinterpret_cast<const void **>(begin),
                       static_cast<const void *>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::uninitializedFillN(
                     volatile TARGET_TYPE                        **begin,
                     volatile TARGET_TYPE                         *value,
                     size_type                                     numElements,
                     void                                         *,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // While it seems that this overload is subsumed by the previous template,
    // SunPro does not detect it.

    uninitializedFillN(reinterpret_cast<volatile void **>(begin),
                       static_cast<volatile void *>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::uninitializedFillN(
                     const volatile TARGET_TYPE                  **begin,
                     const volatile TARGET_TYPE                   *value,
                     size_type                                     numElements,
                     void                                         *,
                     bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>  *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // While it seems that this overload is subsumed by the previous template,
    // SunPro does not detect it.

    uninitializedFillN(reinterpret_cast<const volatile void **>(begin),
                       static_cast<const volatile void *>(value),
                       numElements,
                       (void *)0,
                       (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0);
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::uninitializedFillN(
                        TARGET_TYPE                               *begin,
                        const TARGET_TYPE&                         value,
                        size_type                                  numElements,
                        ALLOCATOR                                 *,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (0 == numElements) {
        return;                                                       // RETURN
    }

    const char *valueBuffer =
                    reinterpret_cast<const char *>(BSLS_UTIL_ADDRESSOF(value));

    std::memcpy((void *)begin, valueBuffer, sizeof(TARGET_TYPE));
    bitwiseFillN(reinterpret_cast<char *>(begin),
                 sizeof(TARGET_TYPE),
                 sizeof(TARGET_TYPE) * numElements);
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::uninitializedFillN(
                                     TARGET_TYPE                  *begin,
                                     const TARGET_TYPE&            value,
                                     size_type                     numElements,
                                     ALLOCATOR                    *allocator,
                                     bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLS_ASSERT_SAFE(allocator);

    if (0 == numElements) {
        return;                                                       // RETURN
    }
    AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(begin,
                                                      begin,
                                                      *allocator);

    TARGET_TYPE *end = begin + numElements;
    do {
        bsl::allocator_traits<ALLOCATOR>::construct(*allocator, begin, value);
        begin = guard.moveEnd(1);
    } while (begin != end);
    guard.release();
}

                    // *** 'copyConstruct' overloads: ***

template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::copyConstruct(
                            TARGET_TYPE                             *toBegin,
                            FWD_ITER                                 fromBegin,
                            FWD_ITER                                 fromEnd,
                            ALLOCATOR                                allocator,
                            bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *)
{
    // We may be casting a function pointer to a 'void *' here, so this won't
    // work if we port to an architecture where the two are of different sizes.

    BSLMF_ASSERT(sizeof(void *) == sizeof(void (*)()));

    typedef typename bsl::remove_cv<
            typename bsl::remove_pointer<TARGET_TYPE>::type>::type NcPtrType;

    typedef typename bsl::remove_cv<
            typename bsl::remove_pointer<
            typename bsl::remove_pointer<FWD_ITER>::type>::type>::type NcIter;

#if defined(BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER)
    // fall back on traditional C-style casts.
    copyConstruct((void *       *)toBegin,
                  (void * const *)fromBegin,
                  (void * const *)fromEnd,
                  allocator,
                  (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) 0);
#else
    copyConstruct(
     reinterpret_cast<void *       *>(const_cast<NcPtrType **>(toBegin)),
     reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromBegin)),
     reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromEnd)),
     allocator,
     (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)0);
#endif
}

template <class FWD_ITER, class ALLOCATOR>
void ArrayPrimitives_Imp::copyConstruct(
                           void                                    **toBegin,
                           FWD_ITER                                  fromBegin,
                           FWD_ITER                                  fromEnd,
                           ALLOCATOR                                 ,
                           bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *)
{
    BSLMF_ASSERT(sizeof(void *) == sizeof(void (*)()));
        // We will be casting a function pointer to a 'void *', so this won't
        // work if we port to an architecture where the two are of different
        // sizes.

    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd));

    while (fromBegin != fromEnd) {
        // 'fromBegin' iterates over pointers to functions, which must be
        // 'reinterpret_cast' to 'void *'.

        *toBegin = reinterpret_cast<void *>(*fromBegin);
        ++fromBegin;
        ++toBegin;
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::copyConstruct(
                          TARGET_TYPE                               *toBegin,
                          const TARGET_TYPE                         *fromBegin,
                          const TARGET_TYPE                         *fromEnd,
                          ALLOCATOR                                  ,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    const size_type numBytes = reinterpret_cast<const char*>(fromEnd)
                             - reinterpret_cast<const char*>(fromBegin);
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) {
        std::memcpy((void *)toBegin, fromBegin, numBytes);
    }
}

template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
void ArrayPrimitives_Imp::copyConstruct(
                                       TARGET_TYPE                  *toBegin,
                                       FWD_ITER                      fromBegin,
                                       FWD_ITER                      fromEnd,
                                       ALLOCATOR                     allocator,
                                       bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, toBegin,
                                                      allocator);

    while (fromBegin != fromEnd) {
        // Note: We are not sure the value type of 'FWD_ITER' is convertible to
        // 'TARGET_TYPE'.  Use 'construct' instead.

        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    toBegin,
                                                    *fromBegin);
        ++fromBegin;
        toBegin = guard.moveEnd(1);
    }
    guard.release();
}

              // *** 'moveConstruct' overloads: ***
template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::moveConstruct(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *fromBegin,
                          TARGET_TYPE                               *fromEnd,
                          ALLOCATOR                                  ,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    const size_type numBytes = reinterpret_cast<const char*>(fromEnd)
                             - reinterpret_cast<const char*>(fromBegin);
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) {
        std::memcpy((void *)toBegin, fromBegin, numBytes);
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::moveConstruct(
                                       TARGET_TYPE                  *toBegin,
                                       TARGET_TYPE                  *fromBegin,
                                       TARGET_TYPE                  *fromEnd,
                                       ALLOCATOR                     allocator,
                                       bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, toBegin,
                                                      allocator);

    while (fromBegin != fromEnd) {
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toBegin,
            bslmf::MovableRefUtil::move(*fromBegin));
        ++fromBegin;
        toBegin = guard.moveEnd(1);
    }
    guard.release();
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::moveIfNoexcept(
                                       TARGET_TYPE                  *toBegin,
                                       TARGET_TYPE                  *fromBegin,
                                       TARGET_TYPE                  *fromEnd,
                                       ALLOCATOR                     allocator,
                                       bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, toBegin,
                                                      allocator);

    while (fromBegin != fromEnd) {
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toBegin,
            bslmf::MovableRefUtil::move_if_noexcept(*fromBegin));
        ++fromBegin;
        toBegin = guard.moveEnd(1);
    }
    guard.release();
}


              // *** 'defaultConstruct' overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::defaultConstruct(
                TARGET_TYPE                                       *begin,
                size_type                                          numElements,
                ALLOCATOR                                          ,
                bslmf::MetaInt<e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::memset(static_cast<void *>(begin),
                    0,
                    sizeof(TARGET_TYPE) * numElements);
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::defaultConstruct(
                        TARGET_TYPE                               *begin,
                        size_type                                  numElements,
                        ALLOCATOR                                  allocator,
                        bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (0 < numElements) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator, begin);
        bitwiseFillN(reinterpret_cast<char *>(begin),
                     sizeof(TARGET_TYPE),
                     numElements * sizeof(TARGET_TYPE));
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::defaultConstruct(
                                     TARGET_TYPE                  *begin,
                                     size_type                     numElements,
                                     ALLOCATOR                     allocator,
                                     bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(begin || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(begin, begin, allocator);

    const TARGET_TYPE *end = begin + numElements;
    while (begin != end) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator, begin);
        begin = guard.moveEnd(1);
    }
    guard.release();
}

                     // *** 'destructiveMove' overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::destructiveMove(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *fromBegin,
                          TARGET_TYPE                               *fromEnd,
                          ALLOCATOR                                  ,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    const size_type numBytes = reinterpret_cast<const char*>(fromEnd)
                             - reinterpret_cast<const char*>(fromBegin);
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) {
        std::memcpy((void *)toBegin, fromBegin, numBytes);
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::destructiveMove(
                                       TARGET_TYPE                  *toBegin,
                                       TARGET_TYPE                  *fromBegin,
                                       TARGET_TYPE                  *fromEnd,
                                       ALLOCATOR                     allocator,
                                       bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd);
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin,
                                                          fromEnd));

    // 'TARGET_TYPE' certainly cannot be bit-wise copyable, so we can save the
    // compiler some work.

    moveIfNoexcept(toBegin, fromBegin, fromEnd, allocator,
                   (bslmf::MetaInt<e_NIL_TRAITS>*)0);
    ArrayDestructionPrimitives::destroy(fromBegin, fromEnd, allocator);
}

                  // *** 'emplace' with 'args' overloads: ***

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10
#endif
#ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F
#define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT
#endif
#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0
template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0);
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05,
                                              class ARGS_06>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05,
                                              class ARGS_06,
                                              class ARGS_07>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8
template <class TARGET_TYPE, class ALLOCATOR, 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
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9
template <class TARGET_TYPE, class ALLOCATOR, 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
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10
template <class TARGET_TYPE, class ALLOCATOR, 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
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          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)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                              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));
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10


#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0
template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination());
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin);

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05,
                                              class ARGS_06>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05,
                                              class ARGS_06,
                                              class ARGS_07>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8
template <class TARGET_TYPE, class ALLOCATOR, 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 ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9
template <class TARGET_TYPE, class ALLOCATOR, 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 ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10
template <class TARGET_TYPE, class ALLOCATOR, 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 ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                              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));
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                               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));

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10


#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0
template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd);
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
            BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
            BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
            BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
                              BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05,
                                              class ARGS_06>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7
template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01,
                                              class ARGS_02,
                                              class ARGS_03,
                                              class ARGS_04,
                                              class ARGS_05,
                                              class ARGS_06,
                                              class ARGS_07>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8
template <class TARGET_TYPE, class ALLOCATOR, 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 ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9
template <class TARGET_TYPE, class ALLOCATOR, 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 ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9

#if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10
template <class TARGET_TYPE, class ALLOCATOR, 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 ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                            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_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            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));
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, 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));
    }
}
#endif  // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class TARGET_TYPE, class ALLOCATOR, class... ARGS>
inline
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{

    ArrayPrimitives_Imp::emplace(toBegin,
                                 toEnd,
                                 allocator,
                                 (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0,
                                 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
}

template <class TARGET_TYPE, class ALLOCATOR, class... ARGS>
void ArrayPrimitives_Imp::emplace(
                          TARGET_TYPE                               *toBegin,
                          TARGET_TYPE                               *toEnd,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *,
                          BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    size_type numElements = 1;


    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;


    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }


    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                                 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
        guard.advance();
    }


    if (tailLen < numElements) {

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);


        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                                  BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...);

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}

template <class TARGET_TYPE, class ALLOCATOR, class... ARGS>
void ArrayPrimitives_Imp::emplace(TARGET_TYPE                  *toBegin,
                                  TARGET_TYPE                  *toEnd,
                                  ALLOCATOR                     allocator,
                                  bslmf::MetaInt<e_NIL_TRAITS> *,
                               BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin,
                                                          toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));


    if (toEnd > toBegin) {

        bsls::ObjectBuffer<TARGET_TYPE> space;
        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            BSLS_UTIL_ADDRESSOF(space.object()),
            BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
        bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));


        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator,
            toEnd,
            bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1)));

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + 1,
                                                          allocator);


        TARGET_TYPE *destEnd = toEnd;
        TARGET_TYPE *srcEnd  = toEnd - 1;
        while (toBegin != srcEnd) {
            *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd);
        }


        *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object());

        guard.release();
    }
    else {

        bsl::allocator_traits<ALLOCATOR>::construct(
            allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
    }
}
// }}} END GENERATED CODE
#endif

                          // *** 'erase' overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::erase(
                          TARGET_TYPE                               *first,
                          TARGET_TYPE                               *middle,
                          TARGET_TYPE                               *last,
                          ALLOCATOR                                  allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last));

    // Key to the transformation diagrams:
    //..
    //  t...z   Original contents of '[first, middle)'
    //  A...G   Original contents of '[middle, last)'
    //  _       Destroyed array element
    //..

    //..
    //  Transformation: tuvABCDEFG => ___ABCDEFG (no throw)
    //..
    ArrayDestructionPrimitives::destroy(first, middle, allocator);

    //..
    //  Transformation: ___ABCDEFG => ABCDEFG___  (might overlap, but no throw)
    //..
    size_type numBytes = reinterpret_cast<const char *>(last)
                       - reinterpret_cast<const char *>(middle);
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) {
        std::memmove((void *)first, middle, numBytes);
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::erase(TARGET_TYPE                  *first,
                                TARGET_TYPE                  *middle,
                                TARGET_TYPE                  *last,
                                ALLOCATOR                     allocator,
                                bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last));

    // Key to the transformation diagrams:
    //..
    //  t...z   Original contents of '[first, middle)'
    //  A...G   Original contents of '[middle, last)'
    //  _       Destructed array element
    //..

    //..
    //  Transformation: tuvABCDEFG => ABCDEFGEFG.
    //..

    while (middle != last) {
        *first++ = bslmf::MovableRefUtil::move_if_noexcept(*middle++);
    }

    //..
    //  Transformation: ABCDEFGEFG => ABCDEFG___.
    //..

    ArrayDestructionPrimitives::destroy(first, middle, allocator);
}

                   // *** 'insert' with 'value' overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::insert(
                          TARGET_TYPE                             *toBegin,
                          TARGET_TYPE                             *toEnd,
                          const TARGET_TYPE&                       value,
                          size_type                                numElements,
                          ALLOCATOR                                allocator,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  v...v   contents of '[fromBegin, fromEnd)'       ("input")
    //  _____   uninitialized array element
    //..

    // ALIASING: If 'value' is a reference into the array 'toBegin..toEnd',
    // then moving the array first might introduce a change in 'value'.  Since
    // type is bitwise copyable, then no memory changes outside the array, so
    // the test below is sufficient to discover all the possible aliasing.
    // Note that we never make a copy.

    const TARGET_TYPE *tempValuePtr = BSLS_UTIL_ADDRESSOF(value);
    if (toBegin <= tempValuePtr && tempValuePtr < toEnd ) {
        // Adjust pointer for shifting after the move.

        tempValuePtr += numElements;
    }

    //..
    //  Transformation: ABCDE___ => ___ABCDE  (might overlap).
    //..

    const size_type numBytes = reinterpret_cast<const char*>(toEnd)
                             - reinterpret_cast<const char*>(toBegin);
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) {
        std::memmove((void *)(toBegin + numElements), toBegin, numBytes);
    }

    //..
    //  Transformation: ___ABCDE => v__ABCDE (no overlap).
    //..

    // Use 'copyConstruct' instead of 'memcpy' because the former optimizes for
    // fundamental types using 'operator=' instead, which avoid the 'memcpy'
    // function call.

    bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                toBegin,
                                                *tempValuePtr);
    //..
    //  Transformation: v__ABCDE => vvvABCDE.
    //..

    bitwiseFillN(reinterpret_cast<char *>(toBegin),
                 sizeof value,
                 numElements * sizeof value);
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::insert(
                          TARGET_TYPE                             *toBegin,
                          TARGET_TYPE                             *toEnd,
                          const TARGET_TYPE&                       value,
                          size_type                                numElements,
                          ALLOCATOR                                allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  v...v   contents of '[fromBegin, fromEnd)'       ("input")
    //  _____   uninitialized array element
    //  [...]   part of an array guarded by an exception guard object
    //  |.(.,.) part of array guarded by move guard
    //          (middle indicated by ',' and dest by '|')
    //..

    const TARGET_TYPE *tempValuePtr = BSLS_UTIL_ADDRESSOF(value);
    if (toBegin <= tempValuePtr && tempValuePtr < toEnd + numElements) {
        // Adjust pointer for shifting after the move.

        tempValuePtr += numElements;
    }

    size_type tailLen    = toEnd - toBegin;
    size_type numGuarded = tailLen < numElements ? tailLen : numElements;

    //..
    //  Transformation: ABCDE_______ => _______ABCDE (might overlap)
    //..

    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }

    //..
    //  Transformation: |_______(,ABCDE) => vvvvv|__(ABCDE,)
    //..

    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    while (guard.middle() != guard.end()) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                                                    *tempValuePtr);
        guard.advance();
    }

    // The bitwise 'guard' is now inactive, since 'middle() == end()' and
    // 'guard.destination()' is the smaller of 'destBegin' or 'toEnd'.

    if (tailLen < numElements) {
        // There still is a gap of 'numElements - tailLen' to fill in between
        // 'toEnd' and 'destBegin'.  The elements that have been 'memmove'-ed
        // need to be guarded, we fill the gap backward from there to keep
        // guarded portion in one piece.

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin,
                                                             destEnd,
                                                             allocator);

        //..
        //  Transformation: vvvvv__[ABCDE] => vvvvv[vvABCDE]
        //..

        while (toEnd != destBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        --destBegin,
                                                        *tempValuePtr);

            endGuard.moveBegin(-1);
        }
        endGuard.release();
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
void ArrayPrimitives_Imp::insert(TARGET_TYPE                *toBegin,
                                 TARGET_TYPE                *toEnd,
                                 const TARGET_TYPE&          value,
                                 size_type                   numElements,
                                 ALLOCATOR                   allocator,
                                 bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // Aliasing: Make a temp copy of 'value' (always).  The reason is that
    // 'value' could be a reference inside the input range, or even outside
    // but with lifetime controlled by one of these values, and so the next
    // transformation could invalidate 'value'.  Note: One cannot rely on
    // 'TARGET_TYPE' to have a single-argument copy constructor (i.e.,
    // default allocator argument to 0) if it takes an allocator; hence the
    // constructor proxy.

    bsls::ObjectBuffer<TARGET_TYPE> space;
    bslma::ConstructionUtil::construct(BSLS_UTIL_ADDRESSOF(space.object()),
                                       bslma::Default::allocator(),
                                       value);
    bslma::DestructorProctor<TARGET_TYPE> temp(
                                          BSLS_UTIL_ADDRESSOF(space.object()));

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  v...v   copies of 'value'                        ("input")
    //  _____   uninitialized array elements
    //  [...]   part of array protected by an exception guard object
    //..

    const size_type tailLen = toEnd - toBegin;
    if (tailLen >= numElements) {
        // Tail is not shorter than input.

        //..
        //  Transformation: ABCDEFG___[] => ABCDEFG[EFG].
        //..

        moveIfNoexcept(toEnd,                // destination
                       toEnd - numElements,  // source
                       toEnd,                // end source
                       allocator,
                       (bslmf::MetaInt<e_NIL_TRAITS> *)0);

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + numElements,
                                                          allocator);

        // TBD: this does the same thing as the old code - don't like that we
        // circumvent the whole allocator thing, but for now, let's keep it
        // consistent.
        //     ConstructorProxy<TARGET_TYPE>
        //                       tempValue(value, bslma::Default::allocator());

        //..
        //  Transformation: ABCDEFG[EFG] => ABCABCD[EFG].
        //..

        TARGET_TYPE *src  = toEnd - numElements;
        TARGET_TYPE *dest = toEnd;
        while (toBegin != src) {
            *--dest = bslmf::MovableRefUtil::move_if_noexcept(*--src);
        }

        //..
        //  Transformation: ABCABCD[EFG] => vvvABCD[EFG].
        //..

        for ( ; toBegin != dest; ++toBegin) {
            *toBegin = space.object();
        }
        // TBD: this can't be good
        guard.release();
    }
    else {
        // Tail is shorter than input.  We can avoid the temp copy of value
        // since there will be space to make a first copy after the tail, and
        // use that to make the subsequent copies.
        //
        // TBD: Update comment now that the assumption is no longer true, and
        // we make a copy at the top of the call, regardless.  We could
        // restore this optimization if we use metaprogramming to check if
        // 'moveIfNoexcept' will move or copy, but not convinced it is worth
        // the complexity.

        difference_type remElements = numElements - tailLen;

        //..
        //  Transformation: ABC_______[] => ABC____[ABC].
        //..

        moveIfNoexcept(toBegin + numElements,  // destination
                       toBegin,                // source
                       toEnd,                  // end source
                       allocator,
                       (bslmf::MetaInt<e_NIL_TRAITS>*)0);

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd + remElements,
                                                          toEnd + numElements,
                                                          allocator);

        //..
        //  Transformation: ABC____[ABC] => ABC[vvvvABC].
        //..

        uninitializedFillN(toEnd,
                           space.object(),
                           remElements,
                           &allocator,
                           (bslmf::MetaInt<e_NIL_TRAITS>*)0);
        guard.moveBegin(-remElements);

        //..
        //  Transformation: ABC[vvvvABC] => vvv[vvvvABC].
        //..

        for ( ; toBegin != toEnd; ++toBegin) {
            *toBegin = space.object();
        }

        guard.release();
    }
}

                  // *** 'insert' with 'FWD_ITER' overloads: ***


template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::insert(
                          TARGET_TYPE                             *toBegin,
                          TARGET_TYPE                             *toEnd,
                          FWD_ITER                                 fromBegin,
                          FWD_ITER                                 fromEnd,
                          size_type                                numElements,
                          ALLOCATOR                                allocator,
                          bslmf::MetaInt<e_IS_POINTER_TO_POINTER>   *)
{
    // We may be casting a function pointer to a 'void *' here, so this won't
    // work if we port to an architecture where the two are of different sizes.

    BSLMF_ASSERT(sizeof(void *) == sizeof(void (*)()));

#if defined(BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER)
    // fall back on traditional C-style casts.
    insert((void *       *)toBegin,
           (void *       *)toEnd,
           (void * const *)fromBegin,
           (void * const *)fromEnd,
           numElements,
           allocator,
           (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) 0);
#else
    typedef typename bsl::remove_cv<
            typename bsl::remove_pointer<TARGET_TYPE>::type>::type NcPtrType;

    typedef typename bsl::remove_cv<
            typename bsl::remove_pointer<
            typename bsl::remove_pointer<FWD_ITER>::type>::type>::type NcIter;

    insert(
     reinterpret_cast<void *       *>(const_cast<NcPtrType **>(toBegin)),
     reinterpret_cast<void *       *>(const_cast<NcPtrType **>(toEnd)),
     reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromBegin)),
     reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromEnd)),
     numElements,
     allocator,
     (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) 0);
#endif
}

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::insert(
                          TARGET_TYPE                             *toBegin,
                          TARGET_TYPE                             *toEnd,
                          const TARGET_TYPE                       *fromBegin,
                          const TARGET_TYPE                       *fromEnd,
                          size_type                                numElements,
                          ALLOCATOR                                ,
                          bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)
{
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    // 'FWD_ITER' has been converted to a 'const TARGET_TYPE *' and
    // 'TARGET_TYPE' is bit-wise copyable.
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd));
    BSLS_ASSERT_SAFE(fromBegin || 0 == numElements);

    BSLS_ASSERT_SAFE(fromBegin + numElements == fromEnd);
    BSLS_ASSERT_SAFE(fromEnd <= toBegin || toEnd + numElements <= fromBegin);

    (void) fromEnd;  // quell warning when 'BSLS_ASSERT_SAFE' is compiled out

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  t...z   contents of '[fromBegin, fromEnd)'       ("input")
    //  _____   uninitialized array element
    //..

    //..
    //  Transformation: ABCDE_______ => _______ABCDE (might overlap).
    //..

    const size_type numBytes = reinterpret_cast<const char*>(toEnd)
                             - reinterpret_cast<const char*>(toBegin);
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) {
        std::memmove((void *)(toBegin + numElements), toBegin, numBytes);
    }

    //..
    //  Transformation: _______ABCDE => tuvwxyzABCDE (no overlap).
    //..

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) {
        std::memcpy((void *)toBegin,
                    fromBegin,
                    numElements * sizeof(TARGET_TYPE));
    }
}

template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
void ArrayPrimitives_Imp::insert(
                          TARGET_TYPE                             *toBegin,
                          TARGET_TYPE                             *toEnd,
                          FWD_ITER                                 fromBegin,
                          FWD_ITER,
                          size_type                                numElements,
                          ALLOCATOR                                allocator,
                          bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *)
{
    // 'TARGET_TYPE' is bit-wise moveable.
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (0 == numElements) {
        return;                                                       // RETURN
    }

    // The following assertions make sense only if 'FWD_ITER' is a pointer to a
    // possibly cv-qualified 'TARGET_TYPE', and are tested in that overload
    // (see above).
    //..
    //  BSLS_ASSERT(fromBegin + numElements == fromEnd);
    //  BSLS_ASSERT(fromEnd <= toBegin || toEnd + numElements <= fromBegin);
    //..

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  t...z   contents of '[fromBegin, fromEnd)'       ("input")
    //  _____   uninitialized array element
    //  [...]   part of array guarded by exception guard
    //  |.(.,.) part of array guarded by move guard
    //          (middle indicated by ',' and dest by '|')
    //..

    const size_type tailLen  = toEnd - toBegin;
    const size_type numGuarded = tailLen < numElements ? tailLen : numElements;

    //..
    //  Transformation: ABCDE____ => ____ABCDE (might overlap).
    //..

    TARGET_TYPE *destBegin = toBegin + numElements;
    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove((void *)destBegin,
                     toBegin,
                     tailLen * sizeof(TARGET_TYPE));
    }

    //..
    //  Transformation: |_______(,ABCDE) => tuvwx|__(ABCDE,).
    //..

    TARGET_TYPE *destEnd = toEnd + numElements;

    AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin,
                                                          destEnd - numGuarded,
                                                          destEnd - numGuarded,
                                                          destEnd,
                                                          allocator);

    for (; guard.middle() != guard.end(); ++fromBegin) {
        bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                    guard.destination(),
                                                    *fromBegin);
        guard.advance();
    }

    // The bitwise 'guard' is now inactive, since 'middle() == end()', and
    // 'guard.destination()' is the smaller of 'destBegin' or 'toEnd'.

    if (tailLen < numElements) {
        // There still is a gap of 'numElements - tailLen' to fill in between
        // 'toEnd' and 'destBegin'.  The elements that have been 'memmove'-ed
        // need to be guarded, and we need to continue to fill the hole at the
        // same guarding the copied elements as well.

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard1(toEnd,
                                                              toEnd,
                                                              allocator);
        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard2(destBegin,
                                                              destEnd,
                                                              allocator);

        //..
        //  Transformation: tuvwx[]__[ABCDE] => tuvwx[yz][ABCDE].
        //..

        for (; toEnd != destBegin; ++fromBegin) {
            bsl::allocator_traits<ALLOCATOR>::construct(allocator,
                                                        toEnd,
                                                        *fromBegin);
            toEnd = endGuard1.moveEnd(1);
        }
        endGuard1.release();
        endGuard2.release();
    }
}

template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR>
void ArrayPrimitives_Imp::insert(TARGET_TYPE                *toBegin,
                                 TARGET_TYPE                *toEnd,
                                 FWD_ITER                    fromBegin,
                                 FWD_ITER                    fromEnd,
                                 size_type                   numElements,
                                 ALLOCATOR                   allocator,
                                 bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (0 == numElements) {
        return;                                                       // RETURN
    }

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  t...z   contents of '[fromBegin, fromEnd)'       ("input")
    //  _____   uninitialized array elements
    //  [...]   part of array protected by a guard object
    //..

    const size_type tailLen = toEnd - toBegin;
    if (tailLen > numElements) {
        // Tail is longer than input.

        //..
        //  Transformation: ABCDEFG___[] => ABCDEFG[EFG].
        //..

        moveIfNoexcept(toEnd,                // destination
                       toEnd - numElements,  // source
                       toEnd,                // end source
                       allocator,
                       (bslmf::MetaInt<e_NIL_TRAITS>*)0);

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd,
                                                          toEnd + numElements,
                                                          allocator);

        //..
        //  Transformation: ABCDEFG[EFG] => ABCABCD[EFG].
        //..

        TARGET_TYPE *src  = toEnd - numElements;
        TARGET_TYPE *dest = toEnd;
        while (toBegin != src) {
            *--dest = bslmf::MovableRefUtil::move_if_noexcept(*--src);
        }

        //..
        //  Transformation: ABCABCD[EFG] => tuvABCD[EFG].
        //..

        for (; toBegin != dest; ++toBegin, ++fromBegin) {
            *toBegin = *fromBegin;
        }

        guard.release();
    }
    else {
        // Tail is not longer than input (numElements).

        difference_type remElements = numElements - tailLen;

        //..
        //  Transformation: ABC_______[] => ABC____[ABC]
        //..

        moveIfNoexcept(toBegin + numElements,  // destination
                       toBegin,                // source
                       toEnd,                  // end source
                       allocator,
                       (bslmf::MetaInt<e_NIL_TRAITS>*)0);

        AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd + remElements,
                                                          toEnd + numElements,
                                                          allocator);

        //..
        //  Transformation: ABC____[ABC] => tuv____[ABC].
        //..

        for (; toBegin != toEnd; ++fromBegin, ++toBegin) {
            *toBegin = *fromBegin;
        }

        //..
        //  Transformation: tuv____[ABC] => tuvwxyzABC[].
        //..
        copyConstruct(toBegin,
                      fromBegin,
                      fromEnd,
                      allocator,
                      (bslmf::MetaInt<e_NIL_TRAITS>*)0);

        guard.release();
    }
}

template <class FWD_ITER, class ALLOCATOR>
void ArrayPrimitives_Imp::insert(
                           void                                  **toBegin,
                           void                                  **toEnd,
                           FWD_ITER                                fromBegin,
                           FWD_ITER,
                           size_type                               numElements,
                           ALLOCATOR                               ,
                           bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *)
{
    // This very specific overload is required for the case that 'FWD_ITER' is
    // an iterator that is not a pointer, iterating over a sequence of function
    // pointers.  The implementation relies on the conditionally-supported
    // behavior that any function pointer can be 'reinterpret_cast' to
    // 'void *'.

    // 'TARGET_TYPE' is bit-wise moveable.
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));

    if (0 == numElements) {
        return;                                                       // RETURN
    }

    // The following assertions make sense only if 'FWD_ITER' is a pointer to a
    // possibly cv-qualified 'TARGET_TYPE', and are tested in that overload
    // (see above).
    //..
    //  BSLS_ASSERT(fromBegin + numElements == fromEnd);
    //  BSLS_ASSERT(fromEnd <= toBegin || toEnd + numElements <= fromBegin);
    //..

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  t...z   contents of '[fromBegin, fromEnd)'       ("input")
    //  _____   uninitialized array element
    //  [...]   part of array guarded by exception guard
    //  |.(.,.) part of array guarded by move guard
    //          (middle indicated by ',' and dest by '|')
    //..

    const size_type tailLen  = toEnd - toBegin;

    //..
    //  Transformation: ABCDE____ => ____ABCDE (might overlap).
    //..

    void **destBegin = toBegin + numElements;

    if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) {
        std::memmove(destBegin, toBegin, tailLen * sizeof(void **));
    }

    for (size_type i = 0; i < numElements; ++i) {
        *toBegin = reinterpret_cast<void *>(*fromBegin);

        ++fromBegin;
        ++toBegin;
    }
}

                       // *** 'moveInsert' overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::moveInsert(
                         TARGET_TYPE                              *toBegin,
                         TARGET_TYPE                              *toEnd,
                         TARGET_TYPE                             **lastPtr,
                         TARGET_TYPE                              *first,
                         TARGET_TYPE                              *last,
                         size_type                                 numElements,
                         ALLOCATOR                                 allocator,
                         bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>  *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, last));
    BSLS_ASSERT_SAFE(first || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLS_ASSERT_SAFE(lastPtr);

    // Functionally indistinguishable from this:

    *lastPtr = last;
    insert(toBegin, toEnd, first, last, numElements, allocator,
           (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS>*)0);
    *lastPtr = first;
}

template <class TARGET_TYPE, class ALLOCATOR>
inline
void ArrayPrimitives_Imp::moveInsert(TARGET_TYPE                 *toBegin,
                                     TARGET_TYPE                 *toEnd,
                                     TARGET_TYPE                **lastPtr,
                                     TARGET_TYPE                 *first,
                                     TARGET_TYPE                 *last,
                                     size_type                    numElements,
                                     ALLOCATOR                    allocator,
                                     bslmf::MetaInt<e_NIL_TRAITS>  *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, last));
    BSLS_ASSERT_SAFE(first || 0 == numElements);
    BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value));
    BSLS_ASSERT_SAFE(lastPtr);

    // There isn't any advantage at destroying [first,last) one by one as we're
    // moving it, except perhaps for slightly better memory usage.

    *lastPtr = last;
    insert(toBegin, toEnd, first, last, numElements, allocator,
           (bslmf::MetaInt<e_NIL_TRAITS>*)0);
    ArrayDestructionPrimitives::destroy(first, last, allocator);
    *lastPtr = first;
}

                         // *** 'rotate' overloads: ***

template <class TARGET_TYPE>
inline
void ArrayPrimitives_Imp::rotate(
                               TARGET_TYPE                             *begin,
                               TARGET_TYPE                             *middle,
                               TARGET_TYPE                             *end,
                               bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(begin, middle));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, end));

    bitwiseRotate(reinterpret_cast<char *>(begin),
                  reinterpret_cast<char *>(middle),
                  reinterpret_cast<char *>(end));
}

template <class TARGET_TYPE>
void ArrayPrimitives_Imp::rotate(TARGET_TYPE                *begin,
                                 TARGET_TYPE                *middle,
                                 TARGET_TYPE                *end,
                                 bslmf::MetaInt<e_NIL_TRAITS> *)
{
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(begin, middle));
    BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, end));

    if (begin == middle || middle == end) {
        // This test changes into O(1) what would otherwise be O(N): Do not
        // remove!

        return;                                                       // RETURN
    }

    // This case is simple enough, it should be taken care of on its own.

    const std::size_t numElements = middle - begin;
    const std::size_t remElements = end - middle;

    if (numElements == remElements) {
        for (; middle != end; ++begin, ++middle) {
            TARGET_TYPE tmp(*middle);
            *middle = *begin;
            *begin = tmp;
        }
        return;                                                       // RETURN
    }

    // This algorithm proceeds by decomposing the rotation into cycles, which
    // can then be rotated using a single element buffer.  First we compute the
    // 'gcd(end - begin, numElements)' which is the number of cycles in the
    // rotation.

    std::size_t numCycles = end - begin;
    std::size_t remainder = numElements;
    while (remainder != 0) {
        std::size_t t = numCycles % remainder;
        numCycles = remainder;
        remainder = t;
    }

    // Key to the transformation diagrams:
    //..
    //  A...D   Contents of the current cycle
    //  W...Z   Contents of another cycle
    //  _       Elements not in the current cycle
    //..

    for (std::size_t i = 0; i < numCycles; ++i) {
        // Let the current cycle be initially 'A__B__C__D__', (note that its
        // stride is 'length / numCycles') and let (*) denote the current
        // position of 'ptr'.

        TARGET_TYPE *ptr = begin; // seed for current cycle:  A(*)__B__C__D__
        TARGET_TYPE  tmp = *ptr;  // value held at the seed:  tmp == A

        if (numElements < remElements) {
            // Rotate the cycle forward by numElements positions (or backward
            // by -(length-numElements)=-remElements positions if crossing the
            // boundary forward).  The transformation is:
            //..
            //  A(*)__B__C__D__ => B__B(*)__C__D__
            //                  => B__C__C(*)__D__
            //                  => B__C__D__D(*)__
            //..
            // The length of the cycle is always 'length / numCycles', but it
            // crosses the range boundaries 'numElements / numCycles' times,
            // each triggering an extra assignment in the 'if' clause below, so
            // the loop must only be executed:
            //..
            //  (length - numElements) / numCycles = remElements / numCycles
            //..
            // times.

            std::size_t cycleSize = remElements / numCycles;

            for (std::size_t j = 0; j < cycleSize; ++j) {
                if (ptr > begin + remElements) {
                    // Wrap around the range boundaries.  (Note that
                    // '-remElements == numElements - (end - begin)'.)

                    *ptr = *(ptr - remElements);
                    ptr -= remElements;
                }

                *ptr = *(ptr + numElements);
                ptr += numElements;
            }
        }
        else {
            // Rotate the cycle backward by '-remElements' positions (or
            // forward by 'numElements' positions if crossing the boundary
            // backward).  The transformation is:
            //..
            //  A(*)__B__C__D__ => D__B__C__D(*)__
            //                  => D__B__C(*)__C__
            //                  => D__B(*)__B__C__
            //..
            // The length of the cycle is always 'length/numCycles', but going
            // backward (which adds an initial extra crossing) crosses the
            // range boundaries 'remElements/numCycles+1' times each of which
            // trigger an extra assignment in the 'if' clause below, so the
            // loop must only be executed:
            //..
            //  (length - remElements) / numCycles - 1 =
            //                                      numElements / numCycles - 1
            //..
            // times.

            std::size_t cycleSize = numElements / numCycles - 1;

            for (std::size_t j = 0; j < cycleSize; ++j) {
                if (ptr < end - numElements) {
                    *ptr = *(ptr + numElements);
                    ptr += numElements;
                }

                *ptr = *(ptr - remElements);
                ptr -= remElements;
            }
        }

        *ptr = tmp; // Close the cycle, e.g.:
                    //..
                    //  (first case):  B__C__D__D(*)__ => B__C__D__A__
                    //  (second case): D__D(*)__B__C__ => D__A__B__C__
                    //..
        ++begin;    // and move on to the next cycle:
                    //..
                    //                                 => _W__X__Y__Z_
                    //..
    }
}

                         // *** 'shiftAndInsert' overloads: ***

template <class ALLOCATOR>
inline
void ArrayPrimitives_Imp::shiftAndInsert(
             typename bsl::allocator_traits<ALLOCATOR>::pointer      begin,
             typename bsl::allocator_traits<ALLOCATOR>::pointer      end,
             bslmf::MovableRef<
             typename bsl::allocator_traits<ALLOCATOR>::value_type>  value,
             ALLOCATOR                                               allocator,
             bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS>              *)
{
    BSLS_ASSERT_SAFE(begin != end); // the range is non-empty

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type ValueType;

    // ALIASING: If 'value' is a reference into the array '[begin, end)',
    // then moving the array first might introduce a change in 'value'.
    // Fortunately we can easily predict its new position after the shift.

    ValueType *valuePtr =
                     BSLS_UTIL_ADDRESSOF(bslmf::MovableRefUtil::access(value));
    if (begin <= valuePtr && valuePtr < end) {
        valuePtr += 1; // new address after the shift
    }

#if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC)
// clang does not support this pragma
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif

    // shift
    std::memmove(begin + 1, begin, (end - begin) * sizeof(ValueType));

    // insert
    bsl::allocator_traits<ALLOCATOR>::construct(
                           allocator,
                           begin,
                           bslmf::MovableRefUtil::move_if_noexcept(*valuePtr));

#if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC)
#pragma GCC diagnostic pop
#endif
}

template <class ALLOCATOR>
inline
void ArrayPrimitives_Imp::shiftAndInsert(
             typename bsl::allocator_traits<ALLOCATOR>::pointer      begin,
             typename bsl::allocator_traits<ALLOCATOR>::pointer      end,
             bslmf::MovableRef<
             typename bsl::allocator_traits<ALLOCATOR>::value_type>  value,
             ALLOCATOR                                               allocator,
             bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>              *)
{
    BSLS_ASSERT_SAFE(begin != end); // the range is non-empty

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type ValueType;

    // ALIASING: If 'value' is a reference into the array '[begin, end)',
    // then moving the array first might introduce a change in 'value'.
    // Fortunately we can easily predict its new position after the shift.

    ValueType *valuePtr =
                     BSLS_UTIL_ADDRESSOF(bslmf::MovableRefUtil::access(value));
    if (begin <= valuePtr && valuePtr < end) {
        valuePtr += 1; // new address after the shift
    }

    // shift
    size_t bytesNum = (end - begin) * sizeof(ValueType);


#if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC)
// clang does not support this pragma
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
    std::memmove(begin + 1, begin, bytesNum);


    class ElementsProctor {
        // Moves the elements back if 'construct' throws.

        // DATA
        ValueType *d_begin;
        size_t     d_bytesNum;
      public:
        // CREATORS
        ElementsProctor(ValueType *p, size_t n) : d_begin(p), d_bytesNum(n) {}
        ~ElementsProctor()
        {
            if(d_bytesNum) std::memmove(d_begin, d_begin + 1, d_bytesNum);
        }
        // MANIPULATORS
        void release() { d_bytesNum = 0; }
    } proctor(begin, bytesNum);


    // insert
    bsl::allocator_traits<ALLOCATOR>::construct(
                           allocator,
                           begin,
                           bslmf::MovableRefUtil::move_if_noexcept(*valuePtr));
    proctor.release();
#if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC)
#pragma GCC diagnostic pop
#endif
}

template <class ALLOCATOR>
inline
void ArrayPrimitives_Imp::shiftAndInsert(
             typename bsl::allocator_traits<ALLOCATOR>::pointer      begin,
             typename bsl::allocator_traits<ALLOCATOR>::pointer      end,
             bslmf::MovableRef<
             typename bsl::allocator_traits<ALLOCATOR>::value_type>  value,
             ALLOCATOR                                               allocator,
             bslmf::MetaInt<e_NIL_TRAITS>                           *)
{
    BSLS_ASSERT_SAFE(begin != end); // the range is non-empty

    typedef typename bsl::allocator_traits<ALLOCATOR>::value_type ValueType;

    // ALIASING: If 'value' is a reference into the array '[begin, end)',
    // then moving the array first might introduce a change in 'value'.
    // Fortunately we can easily predict its new position after the shift.

    ValueType *valuePtr =
                     BSLS_UTIL_ADDRESSOF(bslmf::MovableRefUtil::access(value));
    if (begin <= valuePtr && valuePtr < end) {
        valuePtr += 1; // new address after the shift
    }

    // Key to the transformation diagrams:
    //..
    //  A...G   original contents of '[toBegin, toEnd)'  ("tail")
    //  a...g   moved-from or copied values
    //  v       moved 'value'                            ("input")
    //  _____   uninitialized array elements
    //  [...]   part of array protected by an exception guard object
    //..

    //..
    //  Transformation: ABCDEFG_[] => ABCDEFg[G].
    //..

    bsl::allocator_traits<ALLOCATOR>::construct(
                          allocator,
                          end,
                          bslmf::MovableRefUtil::move_if_noexcept(*(end - 1)));

    bslalg::AutoArrayDestructor<ValueType, ALLOCATOR> guard(
                                                      end, end + 1, allocator);

    //..
    //  Transformation: ABCDEFg[G] => aABCDEF[G].
    //..

    ValueType *dst = end;
    ValueType *src = end - 1;
    while (src != begin) {
        *--dst = bslmf::MovableRefUtil::move_if_noexcept(*--src);
    }

    //..
    //  Transformation: aABCDEFG[G] => vABCDEF[G].
    //..

    *begin = bslmf::MovableRefUtil::move_if_noexcept(*valuePtr);

    guard.release();
}

}  // close package namespace

#ifndef BDE_OPENSOURCE_PUBLICATION  // BACKWARD_COMPATIBILITY
// ============================================================================
//                           BACKWARD COMPATIBILITY
// ============================================================================

typedef bslalg::ArrayPrimitives bslalg_ArrayPrimitives;
    // This alias is defined for backward compatibility.
#endif  // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY

}  // close enterprise namespace

#if defined(BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER)
# undef BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER
#endif

#else // if ! defined(DEFINED_BSLALG_ARRAYPRIMITIVES_H)
# error Not valid except when included from bslalg_arrayprimitives.h
#endif // ! defined(COMPILING_BSLALG_ARRAYPRIMITIVES_H)

#endif // ! defined(INCLUDED_BSLALG_ARRAYPRIMITIVES_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 ----------------------------------