// bslalg_scalarprimitives.h                                          -*-C++-*-
#ifndef INCLUDED_BSLALG_SCALARPRIMITIVES
#define INCLUDED_BSLALG_SCALARPRIMITIVES

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide primitive algorithms that operate on single elements.
//
//@CLASSES:
//  bslalg::ScalarPrimitives: namespace for algorithms
//
//@SEE_ALSO: bslalg_constructorproxy
//
//@DESCRIPTION: This component provides primitive algorithms that operate on
// single elements with a uniform interface but select a different
// implementation according to the various type traits possessed by the
// underlying type.  Such primitives are exceptionally useful for implementing
// generic components such as containers.  There are six families of
// algorithms, each with a collection of overloads:
// ```
// Algorithm           Forwards to (depending on traits)
// ----------------    ------------------------------------------------
// defaultConstruct    Default constructor, with or without allocator
//
// copyConstruct       Copy constructor, with or without allocator,
//                       or bitwise copy if appropriate
//
// moveConstruct       Move constructor, with or without allocator,
//                       or bitwise copy if appropriate.  In C++03 mode,
//                       behavior is the same as 'copyConstruct'.
//
// destructiveMove     Move construction followed by destruction of the
//                       original, with or without allocator,
//                       or bitwise copy if appropriate
//
// construct           In-place construction (using variadic template
//                       arguments, simulated by overloads), with
//                       or without allocator
//
// swap                Three way assignment, or bitwise swap
// ```
// The traits under consideration by this component are:
// ```
// Trait                                         Description
// --------------------------------------------  -----------------------------
// bsl::is_trivially_default_constructible       "TYPE has the trivial default
//                                               constructor trait", or
//                                               "TYPE has a trivial default
//                                               constructor"
//
// bslmf::IsBitwiseCopyable                      "TYPE has the bit-wise
//                                               copyable trait", or
//                                               "TYPE is bit-wise copyable"
//                                               (implies that it has a
//                                               trivial destructor too)
//
// bslmf::IsBitwiseMoveable                      "TYPE has the bit-wise
//                                               moveable trait", or
//                                               "TYPE is bit-wise moveable"
//
// bslma::UsesBslmaAllocator                     "the 'TYPE' constructor takes
//                                               an allocator argument", or
//                                               "'TYPE' supports 'bslma'
//                                               allocators"
//
// bslmf::UsesAllocatorArgT                      "the 'TYPE' constructor takes
//                                               an allocator argument", and
//                                               optionally passes allocators
//                                               as the first two arguments to
//                                               each constructor, where the
//                                               tag type 'allocator_arg_t' is
//                                               first, and the allocator type
//                                               is second.
// ```
//
///Usage
///-----
// This component is for use primarily by the `bslstl` package.  Other clients
// should use the STL algorithms provided in `<algorithm>` and `<memory>`.

#include <bslscm_version.h>

#include <bslalg_autoscalardestructor.h>

#include <bslma_allocator.h>
#include <bslma_destructionutil.h>
#include <bslma_usesbslmaallocator.h>

#include <bslmf_allocatorargt.h>
#include <bslmf_integralconstant.h>
#include <bslmf_isbitwisecopyable.h>
#include <bslmf_isbitwisemoveable.h>
#include <bslmf_isfundamental.h>
#include <bslmf_ispointer.h>
#include <bslmf_issame.h>
#include <bslmf_istriviallycopyable.h>
#include <bslmf_istriviallydefaultconstructible.h>
#include <bslmf_movableref.h>
#include <bslmf_usesallocatorargt.h>
#include <bslmf_util.h>

#include <bsls_assert.h>
#include <bsls_compilerfeatures.h>
#include <bsls_keyword.h>
#include <bsls_platform.h>
#include <bsls_util.h>

#include <stddef.h>
#include <string.h>

#include <new>          // placement 'new'

#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
#include <bslmf_removecvq.h>
#endif

namespace BloombergLP {

namespace bslalg {

struct ScalarPrimitives_Imp;

                       // =======================
                       // struct ScalarPrimitives
                       // =======================

/// This `struct` provides a namespace for a suite of utility functions that
/// operate on elements of a parameterized type `TARGET_TYPE`.  If any of
/// the `...Construct` methods throws, then its target `address` is left
/// uninitialized and there are no effects, unless otherwise mentioned in
/// the documentation.
struct ScalarPrimitives {

  private:
    // PRIVATE TYPES
    typedef ScalarPrimitives_Imp Imp;

  public:
    // CLASS METHODS

    /// Build a default-initialized object of the parameterized
    /// `TARGET_TYPE` in the uninitialized memory at the specified
    /// `address`, as if by using the `TARGET_TYPE` default constructor.  If
    /// the specified `allocator` is based on `bslma::Allocator` and
    /// `TARGET_TYPE` takes an allocator constructor argument, then
    /// `allocator` is passed to the default constructor.  If the
    /// constructor throws, the `address` is left in an uninitialized state.
    /// Note that this operation may bypass the constructor and simply fill
    /// memory with 0 if `TARGET_TYPE` has the trivial default constructor
    /// trait and does not use `bslma::Allocator`.
    template <class TARGET_TYPE>
    static void defaultConstruct(TARGET_TYPE      *address,
                                 bslma::Allocator *allocator);
    template <class TARGET_TYPE>
    static void defaultConstruct(TARGET_TYPE *address,
                                 void        *allocator);

    /// Build an object of the parameterized `TARGET_TYPE` from the
    /// specified `original` object of the same `TARGET_TYPE` in the
    /// uninitialized memory at the specified `address`, as if by using the
    /// copy constructor of `TARGET_TYPE`.  If the specified `allocator` is
    /// based on `bslma::Allocator` and `TARGET_TYPE` takes an allocator
    /// constructor argument, then `allocator` is passed to the copy
    /// constructor.  If the constructor throws, the `address` is left in an
    /// uninitialized state.  Note that bit-wise copy will be used if
    /// `TARGET_TYPE` has the bit-wise copyable trait.
    template <class TARGET_TYPE>
    static void copyConstruct(TARGET_TYPE        *address,
                              const TARGET_TYPE&  original,
                              bslma::Allocator   *allocator);
    template <class TARGET_TYPE>
    static void copyConstruct(TARGET_TYPE        *address,
                              const TARGET_TYPE&  original,
                              void               *allocator);

    /// Build an object of the parameterized `TARGET_TYPE` from the
    /// specified `original` object of the same `TARGET_TYPE` in the
    /// uninitialized memory at the specified `address`, as if by using the
    /// move constructor of `TARGET_TYPE`.  If the specified `allocator` is
    /// based on `bslma::Allocator` and `TARGET_TYPE` takes an allocator
    /// constructor argument, then `allocator` is passed to the move
    /// constructor.  If the constructor throws, the `address` is left in
    /// an uninitialized state.  Note that bit-wise copy will be used if
    /// `TARGET_TYPE` has the bit-wise copyable trait (not the bit-wise
    /// moveable trait, which indicates a destructive bit-wise move).  In
    /// C++03 mode, `moveConstruct` has the same effect as `copyConstruct`.
    template <class TARGET_TYPE>
    static void moveConstruct(TARGET_TYPE        *address,
                              TARGET_TYPE&        original,
                              bslma::Allocator   *allocator);
    template <class TARGET_TYPE>
    static void moveConstruct(TARGET_TYPE        *address,
                              TARGET_TYPE&        original,
                              void               *allocator);

    /// Move the state of the object of the parameterized `TARGET_TYPE` from
    /// the object at the specified `original` address to the uninitialized
    /// memory at the specified `address`, as if by move constructing and
    /// then destroying the original.  If the parameterized `ALLOCATOR` is
    /// based on `bslma::Allocator` and `TARGET_TYPE` takes an allocator
    /// constructor argument, then the moved object uses the specified
    /// `allocator` to supply memory.  If the move constructor throws, the
    /// `address` is left in an uninitialized state and the `original` is
    /// left unchanged.  The behavior is undefined unless the `original`
    /// object also uses the `allocator`.  Note that bit-wise copy will be
    /// used and `allocator` will be ignored if TARGET_TYPE' has the
    /// bit-wise moveable trait.  Note that, if `ALLOCATOR` is not based on
    /// `bslma::Allocator`, then the `allocator` argument is ignored; the
    /// allocator used by the resulting object at `address` might or might
    /// not be the same as the allocator used by `original`, depending on
    /// whether `TARGET_TYPE` has a move constructor (C++11).
    template <class TARGET_TYPE, class ALLOCATOR>
    static void destructiveMove(TARGET_TYPE *address,
                                TARGET_TYPE *original,
                                ALLOCATOR   *allocator);

    /// Build an object of the parameterized `TARGET_TYPE` in the
    /// uninitialized memory at the specified `address`.  Use the
    /// `TARGET_TYPE` constructor `TARGET_TYPE(ARG1 const&, ...)` taking the
    /// specified `a1` up to `a14` arguments of the respective parameterized
    /// `ARG1` up to `ARG14` types.  If the specified `allocator` is based
    /// on `bslma::Allocator` and `TARGET_TYPE` takes an allocator
    /// constructor argument, then `allocator` is passed to the
    /// `TARGET_TYPE` constructor in the manner appropriate to the traits
    /// `bslmf::UsesAllocatorArgT` and `blsma::UsesBslmaAllocator`.
    template <class TARGET_TYPE>
    static void construct(TARGET_TYPE      *address,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE>
    static void construct(TARGET_TYPE *address,
                          void        *allocator);
    template <class TARGET_TYPE, class ARG1>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE, class ARG1>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          void        *allocator);
    template <class TARGET_TYPE, class ARG1, class ARG2>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE, class ARG1, class ARG2>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          const ARG4&  a4,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          const ARG4&  a4,
                          const ARG5&  a5,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          const ARG4&  a4,
                          const ARG5&  a5,
                          const ARG6&  a6,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          const ARG4&  a4,
                          const ARG5&  a5,
                          const ARG6&  a6,
                          const ARG7&  a7,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7, class ARG8>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          const ARG4&  a4,
                          const ARG5&  a5,
                          const ARG6&  a6,
                          const ARG7&  a7,
                          const ARG8&  a8,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          const ARG9&       a9,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9>
    static void construct(TARGET_TYPE *address,
                          const ARG1&  a1,
                          const ARG2&  a2,
                          const ARG3&  a3,
                          const ARG4&  a4,
                          const ARG5&  a5,
                          const ARG6&  a6,
                          const ARG7&  a7,
                          const ARG8&  a8,
                          const ARG9&  a9,
                          void        *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7, class ARG8,
              class ARG9, class ARG10>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          const ARG9&       a9,
                          const ARG10&      a10,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7, class ARG8,
              class ARG9, class ARG10>
    static void construct(TARGET_TYPE  *address,
                          const ARG1&   a1,
                          const ARG2&   a2,
                          const ARG3&   a3,
                          const ARG4&   a4,
                          const ARG5&   a5,
                          const ARG6&   a6,
                          const ARG7&   a7,
                          const ARG8&   a8,
                          const ARG9&   a9,
                          const ARG10&  a10,
                          void         *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10, class ARG11>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          const ARG9&       a9,
                          const ARG10&      a10,
                          const ARG11&      a11,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10, class ARG11>
    static void construct(TARGET_TYPE  *address,
                          const ARG1&   a1,
                          const ARG2&   a2,
                          const ARG3&   a3,
                          const ARG4&   a4,
                          const ARG5&   a5,
                          const ARG6&   a6,
                          const ARG7&   a7,
                          const ARG8&   a8,
                          const ARG9&   a9,
                          const ARG10&  a10,
                          const ARG11&  a11,
                          void         *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          const ARG9&       a9,
                          const ARG10&      a10,
                          const ARG11&      a11,
                          const ARG12&      a12,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12>
    static void construct(TARGET_TYPE  *address,
                          const ARG1&   a1,
                          const ARG2&   a2,
                          const ARG3&   a3,
                          const ARG4&   a4,
                          const ARG5&   a5,
                          const ARG6&   a6,
                          const ARG7&   a7,
                          const ARG8&   a8,
                          const ARG9&   a9,
                          const ARG10&  a10,
                          const ARG11&  a11,
                          const ARG12&  a12,
                          void         *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12,
              class ARG13>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          const ARG9&       a9,
                          const ARG10&      a10,
                          const ARG11&      a11,
                          const ARG12&      a12,
                          const ARG13&      a13,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12,
              class ARG13>
    static void construct(TARGET_TYPE  *address,
                          const ARG1&   a1,
                          const ARG2&   a2,
                          const ARG3&   a3,
                          const ARG4&   a4,
                          const ARG5&   a5,
                          const ARG6&   a6,
                          const ARG7&   a7,
                          const ARG8&   a8,
                          const ARG9&   a9,
                          const ARG10&  a10,
                          const ARG11&  a11,
                          const ARG12&  a12,
                          const ARG13&  a13,
                          void         *allocator);
    template <class TARGET_TYPE,
              class ARG1,  class ARG2,  class ARG3,  class ARG4,
              class ARG5,  class ARG6,  class ARG7,  class ARG8,
              class ARG9,  class ARG10, class ARG11, class ARG12,
              class ARG13, class ARG14>
    static void construct(TARGET_TYPE      *address,
                          const ARG1&       a1,
                          const ARG2&       a2,
                          const ARG3&       a3,
                          const ARG4&       a4,
                          const ARG5&       a5,
                          const ARG6&       a6,
                          const ARG7&       a7,
                          const ARG8&       a8,
                          const ARG9&       a9,
                          const ARG10&      a10,
                          const ARG11&      a11,
                          const ARG12&      a12,
                          const ARG13&      a13,
                          const ARG14&      a14,
                          bslma::Allocator *allocator);
    template <class TARGET_TYPE,
              class ARG1,  class ARG2,  class ARG3,  class ARG4,
              class ARG5,  class ARG6,  class ARG7,  class ARG8,
              class ARG9,  class ARG10, class ARG11, class ARG12,
              class ARG13, class ARG14>
    static void construct(TARGET_TYPE  *address,
                          const ARG1&   a1,
                          const ARG2&   a2,
                          const ARG3&   a3,
                          const ARG4&   a4,
                          const ARG5&   a5,
                          const ARG6&   a6,
                          const ARG7&   a7,
                          const ARG8&   a8,
                          const ARG9&   a9,
                          const ARG10&  a10,
                          const ARG11&  a11,
                          const ARG12&  a12,
                          const ARG13&  a13,
                          const ARG14&  a14,
                          void         *allocator);

#ifndef BDE_OMIT_INTERNAL_DEPRECATED
    /// Destroy the specified `object` of the parameterized `TARGET_TYPE`, as
    /// if by calling the `TARGET_TYPE` destructor, but do not deallocate the
    /// memory occupied by `object`.  Note that the destructor may deallocate
    /// other memory owned by `object`.  Also note that this function is a
    /// no-op if the `TARGET_TYPE` has the trivial destructor trait.  Further
    /// note that the specified `allocator` is not used.
    ///
    /// @DEPRECATED: Use `bslma::DestructionUtil::destroy` without an
    /// allocator argument instead.
    template <class TARGET_TYPE>
    static void destruct(TARGET_TYPE *object,
                         void        *allocator);

    /// Destroy the specified `object` of the parameterized `TARGET_TYPE`, as
    /// if by calling the `TARGET_TYPE` destructor, but do not deallocate the
    /// memory occupied by `object`.  Note that the destructor may deallocate
    /// other memory owned by `object`.  Also note that this function is a
    /// no-op if the `TARGET_TYPE` has the trivial destructor trait.
    ///
    /// @DEPRECATED: Use `bslma::DestructionUtil::destroy` instead.
    template <class TARGET_TYPE>
    static void destruct(TARGET_TYPE *object);
#endif // BDE_OMIT_INTERNAL_DEPRECATED

    /// Swap the contents of the specified `lhs` of the parameterized
    /// `LHS_TYPE` with those of the specified `rhs` of the parameterized
    /// `RHS_TYPE`.  Note that, if `LHS_TYPE` and `RHS_TYPE` are the same
    /// type and that type has the bit-wise moveable trait but does not use
    /// `bslma` allocators, the swap can be performed using a three-way
    /// bit-wise move.
    template <class LHS_TYPE, class RHS_TYPE>
    static void swap(LHS_TYPE& lhs, RHS_TYPE& rhs);
};

                     // ===========================
                     // struct ScalarPrimitives_Imp
                     // ===========================

/// This `struct` provides a namespace for a suite of utility functions that
/// operate on arrays of elements of a parameterized type `TARGET_TYPE`.
/// These utility functions are only for the purpose of implementing those
/// in the `ScalarPrimitives` utility, and should not be used outside this
/// component.
struct ScalarPrimitives_Imp {

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

        e_USES_ALLOCATOR_ARG_T_TRAITS     = 5, // Implies USES_BSLMA_ALLOCATOR
        e_USES_BSLMA_ALLOCATOR_TRAITS     = 4,
        e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS = 3,
        e_BITWISE_COPYABLE_TRAITS         = 2,
        e_BITWISE_MOVEABLE_TRAITS         = 1,
        e_NIL_TRAITS                      = 0
    };

    // CLASS METHODS

    /// Return the `const`-unqualified value of the specified `pointer`.
    /// This function resolves into a `const_cast` and therefore has no
    /// runtime cost, it exists only for template argument deduction.
    template <class TARGET_TYPE>
    static TARGET_TYPE *unconst(const TARGET_TYPE *pointer);

    /// Build a `TARGET_TYPE` object in a default state in the uninitialized
    /// memory at the specified `address`, using the specified `allocator`
    /// to supply memory if `TARGET_TYPE` uses `bslma` allocators.  Use the
    /// default constructor of the parameterized `TARGET_TYPE`, or `memset`
    /// to 0 if `TARGET_TYPE` has a trivial default constructor.  The last
    /// argument is for traits overloading resolution only and its value is
    /// ignored.
    template <class TARGET_TYPE>
    static void defaultConstruct(
                 TARGET_TYPE                                        *address,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE>
    static void defaultConstruct(
                 TARGET_TYPE                                        *address,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE>
    static void defaultConstruct(
             TARGET_TYPE                                            *address,
             bslma::Allocator                                       *allocator,
             bsl::integral_constant<int, e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *);
    template <class TARGET_TYPE>
    static void defaultConstruct(TARGET_TYPE                        *address,
                                 bslma::Allocator                   *allocator,
                                 bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build a `TARGET_TYPE` object in a default state in the uninitialized
    /// memory at the specified `address`.  Use the default constructor of
    /// the parameterized `TARGET_TYPE`, or `memset` to 0 if `TARGET_TYPE`
    /// has a trivial default constructor.  The last argument is for traits
    /// overloading resolution only and its value is ignored.
    template <class TARGET_TYPE>
    static void defaultConstruct(
             TARGET_TYPE                                              *address,
             bsl::integral_constant<int, e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *);
    template <class TARGET_TYPE>
    static void defaultConstruct(TARGET_TYPE                          *address,
                                 bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build in the uninitialized memory at the specified `address` an
    /// object of the parameterized `TARGET_TYPE` that is a copy of the
    /// specified `original` object of the same `TARGET_TYPE`, using the
    /// specified `allocator` to supply memory.  Use the copy constructor of
    /// the `TARGET_TYPE`, or a bit-wise copy if `TARGET_TYPE` is a bit-wise
    /// copyable type.  The last argument is for traits overloading
    /// resolution only and its value is ignored.  Note that a bit-wise copy
    /// is appropriate only if `TARGET_TYPE` does not take allocators.
    template <class TARGET_TYPE>
    static void copyConstruct(
                 TARGET_TYPE                                        *address,
                 const TARGET_TYPE&                                  original,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE>
    static void copyConstruct(
                 TARGET_TYPE                                        *address,
                 const TARGET_TYPE&                                  original,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE>
    static void copyConstruct(
                     TARGET_TYPE                                    *address,
                     const TARGET_TYPE&                              original,
                     bslma::Allocator                               *allocator,
                     bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE>
    static void copyConstruct(TARGET_TYPE                           *address,
                              const TARGET_TYPE&                     original,
                              bslma::Allocator                      *allocator,
                              bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build in the uninitialized memory at the specified `address` an
    /// object of the parameterized `TARGET_TYPE` that is a copy of the
    /// specified `original` object of the same `TARGET_TYPE`.  Use the copy
    /// constructor of the `TARGET_TYPE`, or a bit-wise copy if
    /// `TARGET_TYPE` is a bit-wise copyable type.  The last argument is for
    /// traits overloading resolution only and its value is ignored.  Note
    /// that a bit-wise copy is appropriate only if `TARGET_TYPE` does not
    /// take allocators.
    template <class TARGET_TYPE>
    static void copyConstruct(
                     TARGET_TYPE                                     *address,
                     const TARGET_TYPE&                               original,
                     bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE>
    static void copyConstruct(TARGET_TYPE                            *address,
                              const TARGET_TYPE&                      original,
                              bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build in the uninitialized memory at the specified `address` an
    /// object of the parameterized `TARGET_TYPE` that is a move of the
    /// specified `original` object of the same `TARGET_TYPE`, using the
    /// specified `allocator` to supply memory.  Use the move constructor
    /// of the `TARGET_TYPE`, or a bit-wise copy if `TARGET_TYPE` is a
    /// bit-wise copyable type (not a bit-wise moveable type, which
    /// indicates a destructive bit-wise move).  The last argument is for
    /// traits overloading resolution only and its value is ignored.  Note
    /// that a bit-wise copy is used only if `TARGET_TYPE` does not take
    /// allocators.  In C++03 mode, `moveConstruct` has the same effect as
    /// `copyConstruct`.
    template <class TARGET_TYPE>
    static void moveConstruct(
                 TARGET_TYPE                                        *address,
                 TARGET_TYPE&                                        original,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE>
    static void moveConstruct(
                 TARGET_TYPE                                        *address,
                 TARGET_TYPE&                                        original,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE>
    static void moveConstruct(
                     TARGET_TYPE                                    *address,
                     TARGET_TYPE&                                    original,
                     bslma::Allocator                               *allocator,
                     bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE>
    static void moveConstruct(TARGET_TYPE                           *address,
                              TARGET_TYPE&                           original,
                              bslma::Allocator                      *allocator,
                              bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build in the uninitialized memory at the specified `address` an
    /// object of the parameterized `TARGET_TYPE` that is a move of the
    /// specified `original` object of the same `TARGET_TYPE`.  Use the move
    /// constructor of the `TARGET_TYPE`, or a bit-wise copy if
    /// `TARGET_TYPE` is a bit-wise copyable type (bit-wise copyable, NOT
    /// bit-wise moveable, which relates to destructive bit-wise move).  The
    /// last argument is for traits overloading resolution only and its
    /// value is ignored.  In C++03 mode, `moveConstruct` has the same
    /// effect as `copyConstruct`.
    template <class TARGET_TYPE>
    static void moveConstruct(
                     TARGET_TYPE                                     *address,
                     TARGET_TYPE&                                     original,
                     bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *);
    template <class TARGET_TYPE>
    static void moveConstruct(TARGET_TYPE                            *address,
                              TARGET_TYPE&                            original,
                              bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build a copy of the specified `original` in the uninitialized memory
    /// at the specified `address`.  Use the copy constructor of the
    /// parameterized `TARGET_TYPE` (or a bit-wise copy if `TARGET_TYPE` is
    /// bit-wise moveable).  If `TARGET_TYPE` is not bit-wise moveable, also
    /// destroy the `original`.  The last argument is for traits overloading
    /// resolution only and its value is ignored.  Note that the specified
    /// `allocator` is not used.
    template <class TARGET_TYPE, class ALLOCATOR>
    static void destructiveMove(
                     TARGET_TYPE                                    *address,
                     TARGET_TYPE                                    *original,
                     ALLOCATOR                                      *allocator,
                     bsl::integral_constant<int, e_BITWISE_MOVEABLE_TRAITS> *);
    template <class TARGET_TYPE, class ALLOCATOR>
    static void destructiveMove(TARGET_TYPE                         *address,
                                TARGET_TYPE                         *original,
                                ALLOCATOR                           *allocator,
                                bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Build an object from the specified `a1` in the uninitialized memory
    /// at the specified `address`.  The specified `allocator` is ignored.
    /// Use the parameterized `TARGET_TYPE` constructor with the signature
    /// `TARGET_TYPE(ARG1 const&)` or bitwise copy for non-fundamental
    /// types.  The traits argument is for overloading resolution only and
    /// is ignored.  Note that this function is called only when `ARG1` is
    /// the same as `TARGET_TYPE`.
    template <class TARGET_TYPE, class ARG1>
    static void construct(
                     TARGET_TYPE                                    *address,
                     const ARG1&                                     a1,
                     bslma::Allocator                               *allocator,
                     bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *);

    /// Build an object of the parameterized `TARGET_TYPE` in the
    /// uninitialized memory at the specified `address`, passing the
    /// specified `a1` up to `a14` arguments of the corresponding
    /// parameterized `ARG1` up to `ARG14` types to the `TARGET_TYPE`
    /// constructor with the signature 'TARGET_TYPE(bsl::allocator_arg_t,
    /// bslma::Allocator *, const ARG1&, ...)', and pass the specified
    /// `allocator` as the second argument.  The last argument is for
    /// overloading resolution only and its value is ignored.
    template <class TARGET_TYPE>
    static void construct(
                 TARGET_TYPE                                        *address,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE, class ARG1>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE, class ARG1, class ARG2>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10, class ARG11>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 const ARG12&                                        a12,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12,
              class ARG13>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 const ARG12&                                        a12,
                 const ARG13&                                        a13,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1,  class ARG2,  class ARG3,  class ARG4,
              class ARG5,  class ARG6,  class ARG7,  class ARG8,
              class ARG9,  class ARG10, class ARG11, class ARG12,
              class ARG13, class ARG14>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 const ARG12&                                        a12,
                 const ARG13&                                        a13,
                 const ARG14&                                        a14,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *);

    /// Build an object of the parameterized `TARGET_TYPE` in the
    /// uninitialized memory at the specified `address`, passing the
    /// specified `a1` up to `a14` arguments of the corresponding
    /// parameterized `ARG1` up to `ARG14` types to the `TARGET_TYPE`
    /// constructor with the signature
    /// `TARGET_TYPE(ARG1 const&, ..., bslma::Allocator *)`, and pass the
    /// specified `allocator` in the last position.  The last argument is
    /// for overloading resolution only and its value is ignored.
    template <class TARGET_TYPE>
    static void construct(
                 TARGET_TYPE                                        *address,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE, class ARG1>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE, class ARG1, class ARG2>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10, class ARG11>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 const ARG12&                                        a12,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12,
              class ARG13>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 const ARG12&                                        a12,
                 const ARG13&                                        a13,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1,  class ARG2,  class ARG3,  class ARG4,
              class ARG5,  class ARG6,  class ARG7,  class ARG8,
              class ARG9,  class ARG10, class ARG11, class ARG12,
              class ARG13, class ARG14>
    static void construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 const ARG4&                                         a4,
                 const ARG5&                                         a5,
                 const ARG6&                                         a6,
                 const ARG7&                                         a7,
                 const ARG8&                                         a8,
                 const ARG9&                                         a9,
                 const ARG10&                                        a10,
                 const ARG11&                                        a11,
                 const ARG12&                                        a12,
                 const ARG13&                                        a13,
                 const ARG14&                                        a14,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *);

    /// Build an object of the parameterized `TARGET_TYPE` in the
    /// uninitialized memory at the specified `address`, passing the
    /// specified `a1` up to `a14` arguments of the corresponding
    /// parameterized `ARG1` up to `ARG14` types to the `TARGET_TYPE`
    /// constructor with the signature `TARGET_TYPE(ARG1 const&, ...)`.  The
    /// specified `allocator` is *not* passed through to the `TARGET_TYPE`
    /// constructor.  The last argument is for overloading resolution only
    /// and is ignored.
    template <class TARGET_TYPE>
    static void construct(TARGET_TYPE                               *address,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE, class ARG1>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE, class ARG1, class ARG2>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2, class ARG3, class ARG4,
              class ARG5, class ARG6, class ARG7>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          const ARG9&                                a9,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          const ARG9&                                a9,
                          const ARG10&                               a10,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3, class ARG4,
              class ARG5, class ARG6,  class ARG7, class ARG8,
              class ARG9, class ARG10, class ARG11>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          const ARG9&                                a9,
                          const ARG10&                               a10,
                          const ARG11&                               a11,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          const ARG9&                                a9,
                          const ARG10&                               a10,
                          const ARG11&                               a11,
                          const ARG12&                               a12,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1, class ARG2,  class ARG3,  class ARG4,
              class ARG5, class ARG6,  class ARG7,  class ARG8,
              class ARG9, class ARG10, class ARG11, class ARG12,
              class ARG13>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          const ARG9&                                a9,
                          const ARG10&                               a10,
                          const ARG11&                               a11,
                          const ARG12&                               a12,
                          const ARG13&                               a13,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);
    template <class TARGET_TYPE,
              class ARG1,  class ARG2,  class ARG3,  class ARG4,
              class ARG5,  class ARG6,  class ARG7,  class ARG8,
              class ARG9,  class ARG10, class ARG11, class ARG12,
              class ARG13, class ARG14>
    static void construct(TARGET_TYPE                               *address,
                          const ARG1&                                a1,
                          const ARG2&                                a2,
                          const ARG3&                                a3,
                          const ARG4&                                a4,
                          const ARG5&                                a5,
                          const ARG6&                                a6,
                          const ARG7&                                a7,
                          const ARG8&                                a8,
                          const ARG9&                                a9,
                          const ARG10&                               a10,
                          const ARG11&                               a11,
                          const ARG12&                               a12,
                          const ARG13&                               a13,
                          const ARG14&                               a14,
                          bslma::Allocator                          *allocator,
                          bsl::integral_constant<int, e_NIL_TRAITS> *);

    /// Swap the contents of the specified `lhs` object of the parameterized
    /// `LHS_TYPE` with the specified `rhs` object of the parameterized
    /// `RHS_TYPE`.  Use a three-way bit-wise copy (with a temporary
    /// uninitialized buffer), if `LHS_TYPE` and `RHS_TYPE` are the same
    /// bit-wise moveable type, and a three-way assignment with a temporary
    /// if not.  The last argument is for overloading resolution only and is
    /// ignored.
    template <class LHS_TYPE, class RHS_TYPE>
    static void swap(LHS_TYPE&                                             lhs,
                     RHS_TYPE&                                             rhs,
                     bsl::integral_constant<int, e_BITWISE_MOVEABLE_TRAITS> *);
    template <class LHS_TYPE, class RHS_TYPE>
    static void swap(LHS_TYPE&                                  lhs,
                     RHS_TYPE&                                  rhs,
                     bsl::integral_constant<int, e_NIL_TRAITS> *);
};

// ============================================================================
//                      TEMPLATE FUNCTION DEFINITIONS
// ============================================================================


// Workaround for optimization issue in xlC that mishandles pointer aliasing.
//   IV56864: ALIASING BEHAVIOUR FOR PLACEMENT NEW
//   http://www-01.ibm.com/support/docview.wss?uid=swg1IV56864
// Place this macro following each use of placement new.  Alternatively,
// compile with xlC_r -qalias=noansi, which reduces optimization opportunities
// across entire translation unit instead of simply across optimization fence.
// Update: issue is fixed in xlC 13.1 (__xlC__ >= 0x0d01).

#if defined(BSLS_PLATFORM_CMP_IBM) && BSLS_PLATFORM_CMP_VERSION < 0x0d01
    #define BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX                     \
                             BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE
#else
    #define BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX
#endif

                       // -----------------------
                       // struct ScalarPrimitives
                       // -----------------------

                    // *** defaultConstruct overloads: ***

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::defaultConstruct(TARGET_TYPE      *address,
                                   bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : bsl::is_trivially_default_constructible<TARGET_TYPE>::value
                  ? Imp::e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS
                  : Imp::e_NIL_TRAITS
    };
    Imp::defaultConstruct(address,
                          allocator,
                          (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::defaultConstruct(TARGET_TYPE *address,
                                   void        *)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bsl::is_trivially_default_constructible<TARGET_TYPE>::value
              ? Imp::e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS
              : Imp::e_NIL_TRAITS
    };
    Imp::defaultConstruct(address, (bsl::integral_constant<int, k_VALUE>*)0);
}

                      // *** copyConstruct overloads: ***

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::copyConstruct(TARGET_TYPE        *address,
                                const TARGET_TYPE&  original,
                                bslma::Allocator   *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : bslmf::IsBitwiseCopyable<TARGET_TYPE>::value
                  ? Imp::e_BITWISE_COPYABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };
    Imp::copyConstruct(address, original, allocator,
                       (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::copyConstruct(TARGET_TYPE        *address,
                                const TARGET_TYPE&  original,
                                void               *)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslmf::IsBitwiseCopyable<TARGET_TYPE>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    Imp::copyConstruct(address,
                       original,
                       (bsl::integral_constant<int, k_VALUE>*)0);
}

                      // *** moveConstruct overloads: ***

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::moveConstruct(TARGET_TYPE        *address,
                                TARGET_TYPE&        original,
                                bslma::Allocator   *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : bslmf::IsBitwiseCopyable<TARGET_TYPE>::value
                  ? Imp::e_BITWISE_COPYABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };
    Imp::moveConstruct(address, original, allocator,
                       (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::moveConstruct(TARGET_TYPE        *address,
                                TARGET_TYPE&        original,
                                void               *)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslmf::IsBitwiseCopyable<TARGET_TYPE>::value
              ? Imp::e_BITWISE_COPYABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    Imp::moveConstruct(address, original,
                       (bsl::integral_constant<int, k_VALUE>*)0);
}


                     // *** destructiveMove overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
inline
void
ScalarPrimitives::destructiveMove(TARGET_TYPE *address,
                                  TARGET_TYPE *original,
                                  ALLOCATOR   *allocator)
{
    BSLS_ASSERT_SAFE(address);
    BSLS_ASSERT_SAFE(original);

    enum {
        k_VALUE = bslmf::IsBitwiseMoveable<TARGET_TYPE>::value
              ? Imp::e_BITWISE_MOVEABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    Imp::destructiveMove(address,
                         original,
                         allocator,
                         (bsl::integral_constant<int, k_VALUE>*)0);
}

                       // *** construct overloads: ****

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address, allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE();
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : bsl::is_same<ARG1, TARGET_TYPE>::value
                && bslmf::IsBitwiseCopyable<TARGET_TYPE>::value
                  ? Imp::e_BITWISE_COPYABLE_TRAITS
                  : Imp::e_NIL_TRAITS
    };
    Imp::construct(address, a1, allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address, a1, a2, allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            const ARG4&  a4,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            const ARG4&  a4,
                            const ARG5&  a5,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            const ARG4&  a4,
                            const ARG5&  a5,
                            const ARG6&  a6,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6, class ARG7>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6, class ARG7>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            const ARG4&  a4,
                            const ARG5&  a5,
                            const ARG6&  a6,
                            const ARG7&  a7,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            const ARG4&  a4,
                            const ARG5&  a5,
                            const ARG6&  a6,
                            const ARG7&  a7,
                            const ARG8&  a8,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            const ARG9&       a9,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8, a9,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9>
inline
void
ScalarPrimitives::construct(TARGET_TYPE *address,
                            const ARG1&  a1,
                            const ARG2&  a2,
                            const ARG3&  a3,
                            const ARG4&  a4,
                            const ARG5&  a5,
                            const ARG6&  a6,
                            const ARG7&  a7,
                            const ARG8&  a8,
                            const ARG9&  a9,
                            void        *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            const ARG9&       a9,
                            const ARG10&      a10,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10>
inline
void
ScalarPrimitives::construct(TARGET_TYPE  *address,
                            const ARG1&   a1,
                            const ARG2&   a2,
                            const ARG3&   a3,
                            const ARG4&   a4,
                            const ARG5&   a5,
                            const ARG6&   a6,
                            const ARG7&   a7,
                            const ARG8&   a8,
                            const ARG9&   a9,
                            const ARG10&  a10,
                            void         *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            const ARG9&       a9,
                            const ARG10&      a10,
                            const ARG11&      a11,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11>
inline
void
ScalarPrimitives::construct(TARGET_TYPE  *address,
                            const ARG1&   a1,
                            const ARG2&   a2,
                            const ARG3&   a3,
                            const ARG4&   a4,
                            const ARG5&   a5,
                            const ARG6&   a6,
                            const ARG7&   a7,
                            const ARG8&   a8,
                            const ARG9&   a9,
                            const ARG10&  a10,
                            const ARG11&  a11,
                            void         *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11,
          class ARG12>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            const ARG9&       a9,
                            const ARG10&      a10,
                            const ARG11&      a11,
                            const ARG12&      a12,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11,
          class ARG12>
inline
void
ScalarPrimitives::construct(TARGET_TYPE  *address,
                            const ARG1&   a1,
                            const ARG2&   a2,
                            const ARG3&   a3,
                            const ARG4&   a4,
                            const ARG5&   a5,
                            const ARG6&   a6,
                            const ARG7&   a7,
                            const ARG8&   a8,
                            const ARG9&   a9,
                            const ARG10&  a10,
                            const ARG11&  a11,
                            const ARG12&  a12,
                            void         *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(a1,  a2,  a3, a4, a5, a6, a7, a8, a9,
                                a10, a11, a12);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1, class ARG2,  class ARG3,
          class ARG4,  class ARG5, class ARG6,  class ARG7,
          class ARG8,  class ARG9, class ARG10, class ARG11,
          class ARG12, class ARG13>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            const ARG9&       a9,
                            const ARG10&      a10,
                            const ARG11&      a11,
                            const ARG12&      a12,
                            const ARG13&      a13,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE,  class ARG1, class ARG2,  class ARG3,
          class ARG4,  class ARG5, class ARG6,  class ARG7,
          class ARG8,  class ARG9, class ARG10, class ARG11,
          class ARG12, class ARG13>
inline
void
ScalarPrimitives::construct(TARGET_TYPE  *address,
                            const ARG1&   a1,
                            const ARG2&   a2,
                            const ARG3&   a3,
                            const ARG4&   a4,
                            const ARG5&   a5,
                            const ARG6&   a6,
                            const ARG7&   a7,
                            const ARG8&   a8,
                            const ARG9&   a9,
                            const ARG10&  a10,
                            const ARG11&  a11,
                            const ARG12&  a12,
                            const ARG13&  a13,
                            void         *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(
                       a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1,  class ARG2,  class ARG3,
          class ARG4,  class ARG5,  class ARG6,  class ARG7,
          class ARG8,  class ARG9,  class ARG10, class ARG11,
          class ARG12, class ARG13, class ARG14>
inline
void
ScalarPrimitives::construct(TARGET_TYPE      *address,
                            const ARG1&       a1,
                            const ARG2&       a2,
                            const ARG3&       a3,
                            const ARG4&       a4,
                            const ARG5&       a5,
                            const ARG6&       a6,
                            const ARG7&       a7,
                            const ARG8&       a8,
                            const ARG9&       a9,
                            const ARG10&      a10,
                            const ARG11&      a11,
                            const ARG12&      a12,
                            const ARG13&      a13,
                            const ARG14&      a14,
                            bslma::Allocator *allocator)
{
    BSLS_ASSERT_SAFE(address);

    enum {
        k_VALUE = bslma::UsesBslmaAllocator<TARGET_TYPE>::value
              ? (bslmf::UsesAllocatorArgT<TARGET_TYPE>::value
                 ? Imp::e_USES_ALLOCATOR_ARG_T_TRAITS
                 : Imp::e_USES_BSLMA_ALLOCATOR_TRAITS)
              : Imp::e_NIL_TRAITS
    };
    Imp::construct(address,
                   a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
                   allocator,
                   (bsl::integral_constant<int, k_VALUE>*)0);
}

template <class TARGET_TYPE,  class ARG1,  class ARG2,  class ARG3,
          class ARG4,  class ARG5,  class ARG6,  class ARG7,
          class ARG8,  class ARG9,  class ARG10, class ARG11,
          class ARG12, class ARG13, class ARG14>
inline
void
ScalarPrimitives::construct(TARGET_TYPE  *address,
                            const ARG1&   a1,
                            const ARG2&   a2,
                            const ARG3&   a3,
                            const ARG4&   a4,
                            const ARG5&   a5,
                            const ARG6&   a6,
                            const ARG7&   a7,
                            const ARG8&   a8,
                            const ARG9&   a9,
                            const ARG10&  a10,
                            const ARG11&  a11,
                            const ARG12&  a12,
                            const ARG13&  a13,
                            const ARG14&  a14,
                            void         *)
{
    BSLS_ASSERT_SAFE(address);

    ::new (address) TARGET_TYPE(
                  a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

}  // close package namespace

                          // *** destruct overloads: ***

#ifndef BDE_OMIT_INTERNAL_DEPRECATED

namespace bslalg {

template <class TARGET_TYPE>
inline
void ScalarPrimitives::destruct(TARGET_TYPE *address, void *)
{
    bslma::DestructionUtil::destroy(address);
}

template <class TARGET_TYPE>
inline
void ScalarPrimitives::destruct(TARGET_TYPE *address)
{
    bslma::DestructionUtil::destroy(address);
}

}  // close package namespace

#endif // BDE_OMIT_INTERNAL_DEPRECATED

namespace bslalg {

                          // *** swap overloads: ***

template <class LHS_TYPE, class RHS_TYPE>
void ScalarPrimitives::swap(LHS_TYPE& lhs, RHS_TYPE& rhs)
{
    enum {
        k_VALUE = bsl::is_same<LHS_TYPE, RHS_TYPE>::value
                && bslmf::IsBitwiseMoveable<LHS_TYPE>::value
              ? Imp::e_BITWISE_MOVEABLE_TRAITS
              : Imp::e_NIL_TRAITS
    };
    Imp::swap(lhs, rhs, (bsl::integral_constant<int, k_VALUE>*)0);
}

                     // ---------------------------
                     // struct ScalarPrimitives_Imp
                     // ---------------------------

// CLASS METHODS
template <class TARGET_TYPE>
inline
TARGET_TYPE *ScalarPrimitives_Imp::unconst(const TARGET_TYPE *pointer)
{
    return const_cast<TARGET_TYPE *>(pointer);
}

                    // *** defaultConstruct overloads: ***

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::defaultConstruct(
                  TARGET_TYPE                                       *address,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::defaultConstruct(
                  TARGET_TYPE                                       *address,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::defaultConstruct(
              TARGET_TYPE                                             *address,
              bslma::Allocator                                        *,
              bsl::integral_constant<int, e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *)
{
    defaultConstruct(
           address,
           (bsl::integral_constant<int, e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS>*)0);
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::defaultConstruct(
                                   TARGET_TYPE                        *address,
                                   bslma::Allocator                   *,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE();
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::defaultConstruct(
              TARGET_TYPE                                             *address,
              bsl::integral_constant<int, e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // assignment can't throw.

        ::new (address) TARGET_TYPE();
        BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
    } else {
        memset(reinterpret_cast<char *>(address), 0, sizeof *address);
    }
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::defaultConstruct(
                                   TARGET_TYPE                        *address,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE();
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

                      // *** copyConstruct overloads: ***

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::copyConstruct(
                  TARGET_TYPE                                       *address,
                  const TARGET_TYPE&                                 original,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, original);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::copyConstruct(
                  TARGET_TYPE                                       *address,
                  const TARGET_TYPE&                                 original,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(original, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::copyConstruct(
                      TARGET_TYPE                                    *address,
                      const TARGET_TYPE&                              original,
                      bslma::Allocator                               *,
                      bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // copy-constructor can't throw, and that assignment (although would
        // likely produce equivalent code) can't be used, in case 'TARGET_TYPE'
        // is 'const'-qualified.

        ::new (address) TARGET_TYPE(original);
        BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
    } else {
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
        memcpy((void *)address,
               BSLS_UTIL_ADDRESSOF(original),
               sizeof original);
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic pop
#endif
    }
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::copyConstruct(
                                   TARGET_TYPE                       *address,
                                   const TARGET_TYPE&                 original,
                                   bslma::Allocator                  *,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(original);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::copyConstruct(
                      TARGET_TYPE                                    *address,
                      const TARGET_TYPE&                              original,
                      bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // copy-constructor can't throw, and that assignment (although would
        // likely produce equivalent code) can't be used, in case 'TARGET_TYPE'
        // is 'const'-qualified.

        ::new (address) TARGET_TYPE(original);
        BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
    } else {
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
        memcpy((void *)address,
               BSLS_UTIL_ADDRESSOF(original),
               sizeof original);
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic pop
#endif
    }
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::copyConstruct(
                                   TARGET_TYPE                       *address,
                                   const TARGET_TYPE&                 original,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(original);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

                      // *** moveConstruct overloads: ***

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::moveConstruct(
                  TARGET_TYPE                                       *address,
                  TARGET_TYPE&                                       original,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator,
                                bslmf::MovableRefUtil::move(original));
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::moveConstruct(
                  TARGET_TYPE                                       *address,
                  TARGET_TYPE&                                       original,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bslmf::MovableRefUtil::move(original),
                                allocator);
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::moveConstruct(
                      TARGET_TYPE                                    *address,
                      TARGET_TYPE&                                    original,
                      bslma::Allocator                               *,
                      bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // copy-constructor can't throw, and that assignment (although would
        // likely produce equivalent code) can't be used, in case 'TARGET_TYPE'
        // is 'const'-qualified.

        ::new (address) TARGET_TYPE(original);
    } else {
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
        memcpy(address, BSLS_UTIL_ADDRESSOF(original), sizeof original);
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic pop
#endif
    }
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::moveConstruct(
                                   TARGET_TYPE                       *address,
                                   TARGET_TYPE&                       original,
                                   bslma::Allocator                  *,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bslmf::MovableRefUtil::move(original));
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::moveConstruct(
                      TARGET_TYPE                                    *address,
                      TARGET_TYPE&                                    original,
                      bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // move-constructor can't throw, and that assignment (although would
        // likely produce equivalent code) can't be used, in case 'TARGET_TYPE'
        // is 'const'-qualified.

        ::new (address) TARGET_TYPE(original);
    } else {
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
        memcpy((void *)address,
               BSLS_UTIL_ADDRESSOF(original),
               sizeof original);
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic pop
#endif
    }
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::moveConstruct(
                                   TARGET_TYPE                       *address,
                                   TARGET_TYPE&                       original,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bslmf::MovableRefUtil::move(original));
}

                     // *** destructiveMove overloads: ***

template <class TARGET_TYPE, class ALLOCATOR>
inline
void
ScalarPrimitives_Imp::destructiveMove(
                      TARGET_TYPE                                    *address,
                      TARGET_TYPE                                    *original,
                      ALLOCATOR                                      *,
                      bsl::integral_constant<int, e_BITWISE_MOVEABLE_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // copy-constructor can't throw, and that assignment (although would
        // likely produce equivalent code) can't be used, in case 'TARGET_TYPE'
        // is 'const'-qualified.

        ::new (address) TARGET_TYPE(*original);
        BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
    } else {
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
        memcpy((void *)address, original, sizeof *original);   // no overlap
#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 50000
#pragma GCC diagnostic pop
#endif
    }
}

template <class TARGET_TYPE, class ALLOCATOR>
inline
void
ScalarPrimitives_Imp::destructiveMove(
                                   TARGET_TYPE                      *address,
                                   TARGET_TYPE                      *original,
                                   ALLOCATOR                        *allocator,
                                   bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ScalarPrimitives::moveConstruct(address, *original, allocator);
    bslma::DestructionUtil::destroy(original);
}

                        // *** construct overloads: ***

template <class TARGET_TYPE, class ARG1>
inline
void
ScalarPrimitives_Imp::construct(
                      TARGET_TYPE                                     *address,
                      const ARG1&                                      a1,
                      bslma::Allocator                                *,
                      bsl::integral_constant<int, e_BITWISE_COPYABLE_TRAITS> *)
{
    if (bsl::is_fundamental<TARGET_TYPE>::value
     || bsl::is_pointer<TARGET_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental or pointer types.  Note that
        // copy-constructor can't throw, and that assignment (although would
        // likely produce equivalent code) can't be used, in case 'TARGET_TYPE'
        // is 'const'-qualified.

        ::new (address) TARGET_TYPE(a1);
        BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
    } else {
        BSLMF_ASSERT(sizeof (TARGET_TYPE) == sizeof(a1));
        memcpy((void *)address, BSLS_UTIL_ADDRESSOF(a1), sizeof a1);
                                                                  // no overlap
    }
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE();
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3>
inline
void
ScalarPrimitives_Imp::construct(
                 TARGET_TYPE                                        *address,
                 const ARG1&                                         a1,
                 const ARG2&                                         a2,
                 const ARG3&                                         a3,
                 bslma::Allocator                                   *allocator,
                 bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6, class ARG7>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6, a7);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6, class ARG7>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2, class ARG3,
          class ARG4, class ARG5, class ARG6, class ARG7>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6, a7, a8);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6, a7, a8, a9);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                const ARG9&                            a9,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
     ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                 a5, a6, a7, a8, a9, a10);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
                                allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                const ARG9&                            a9,
                                const ARG10&                           a10,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
     ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                 a5, a6, a7, a8, a9, a10, a11);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
                                allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                const ARG9&                            a9,
                                const ARG10&                           a10,
                                const ARG11&                           a11,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11,
          class ARG12>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  const ARG12&                                       a12,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6, a7, a8, a9, a10, a11, a12);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11,
          class ARG12>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  const ARG12&                                       a12,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(
                             a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
                             allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE, class ARG1, class ARG2,  class ARG3,
          class ARG4, class ARG5, class ARG6,  class ARG7,
          class ARG8, class ARG9, class ARG10, class ARG11,
          class ARG12>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                const ARG9&                            a9,
                                const ARG10&                           a10,
                                const ARG11&                           a11,
                                const ARG12&                           a12,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(
                            a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1, class ARG2,  class ARG3,
          class ARG4,  class ARG5, class ARG6,  class ARG7,
          class ARG8,  class ARG9, class ARG10, class ARG11,
          class ARG12, class ARG13>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  const ARG12&                                       a12,
                  const ARG13&                                       a13,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6, a7, a8, a9, a10, a11, a12, a13);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1, class ARG2,  class ARG3,
          class ARG4,  class ARG5, class ARG6,  class ARG7,
          class ARG8,  class ARG9, class ARG10, class ARG11,
          class ARG12, class ARG13>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  const ARG12&                                       a12,
                  const ARG13&                                       a13,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(
                        a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13,
                        allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1, class ARG2,  class ARG3,
          class ARG4,  class ARG5, class ARG6,  class ARG7,
          class ARG8,  class ARG9, class ARG10, class ARG11,
          class ARG12, class ARG13>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                const ARG9&                            a9,
                                const ARG10&                           a10,
                                const ARG11&                           a11,
                                const ARG12&                           a12,
                                const ARG13&                           a13,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(
                       a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1,  class ARG2,  class ARG3,
          class ARG4,  class ARG5,  class ARG6,  class ARG7,
          class ARG8,  class ARG9,  class ARG10, class ARG11,
          class ARG12, class ARG13, class ARG14>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  const ARG12&                                       a12,
                  const ARG13&                                       a13,
                  const ARG14&                                       a14,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_ALLOCATOR_ARG_T_TRAITS> *)
{
    ::new (address) TARGET_TYPE(bsl::allocator_arg, allocator, a1, a2, a3, a4,
                                a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1,  class ARG2,  class ARG3,
          class ARG4,  class ARG5,  class ARG6,  class ARG7,
          class ARG8,  class ARG9,  class ARG10, class ARG11,
          class ARG12, class ARG13, class ARG14>
inline
void
ScalarPrimitives_Imp::construct(
                  TARGET_TYPE                                       *address,
                  const ARG1&                                        a1,
                  const ARG2&                                        a2,
                  const ARG3&                                        a3,
                  const ARG4&                                        a4,
                  const ARG5&                                        a5,
                  const ARG6&                                        a6,
                  const ARG7&                                        a7,
                  const ARG8&                                        a8,
                  const ARG9&                                        a9,
                  const ARG10&                                       a10,
                  const ARG11&                                       a11,
                  const ARG12&                                       a12,
                  const ARG13&                                       a13,
                  const ARG14&                                       a14,
                  bslma::Allocator                                  *allocator,
                  bsl::integral_constant<int, e_USES_BSLMA_ALLOCATOR_TRAITS> *)
{
    ::new (address) TARGET_TYPE(
                   a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
                   allocator);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

template <class TARGET_TYPE,  class ARG1,  class ARG2,  class ARG3,
          class ARG4,  class ARG5,  class ARG6,  class ARG7,
          class ARG8,  class ARG9,  class ARG10, class ARG11,
          class ARG12, class ARG13, class ARG14>
inline
void
ScalarPrimitives_Imp::construct(TARGET_TYPE                           *address,
                                const ARG1&                            a1,
                                const ARG2&                            a2,
                                const ARG3&                            a3,
                                const ARG4&                            a4,
                                const ARG5&                            a5,
                                const ARG6&                            a6,
                                const ARG7&                            a7,
                                const ARG8&                            a8,
                                const ARG9&                            a9,
                                const ARG10&                           a10,
                                const ARG11&                           a11,
                                const ARG12&                           a12,
                                const ARG13&                           a13,
                                const ARG14&                           a14,
                                bslma::Allocator                      *,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    ::new (address) TARGET_TYPE(
                  a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
    BSLALG_SCALARPRIMITIVES_XLC_PLACEMENT_NEW_FIX;
}

                          // *** swap overloads: ***

template <class LHS_TYPE, class RHS_TYPE>
void ScalarPrimitives_Imp::swap(
                      LHS_TYPE&                                            lhs,
                      RHS_TYPE&                                            rhs,
                      bsl::integral_constant<int, e_BITWISE_MOVEABLE_TRAITS> *)
{
    if BSLS_KEYWORD_CONSTEXPR_CPP17 (bsl::is_same<LHS_TYPE, RHS_TYPE>::value
     && !bsl::is_fundamental<LHS_TYPE>::value
     && !bsl::is_pointer<LHS_TYPE>::value
     && !bslmf::UsesAllocatorArgT<LHS_TYPE>::value
     && !bslma::UsesBslmaAllocator<LHS_TYPE>::value) {
        // Detectable at compile-time, this condition ensures that we don't
        // call library functions for fundamental types.  It also ensures we
        // don't bitwise swap types that use allocators, as there is no easy
        // way to confirm allocators are the same for an arbitrary 'LHS_TYPE'.
        // Note that assignment can throw only for types that use allocators.

        char arena[sizeof lhs];
        memcpy(arena, BSLS_UTIL_ADDRESSOF(lhs), sizeof lhs);
        memcpy((void *)BSLS_UTIL_ADDRESSOF(lhs),
               BSLS_UTIL_ADDRESSOF(rhs),
               sizeof lhs);                         // no overlap, or identical
        memcpy((void *)BSLS_UTIL_ADDRESSOF(rhs), arena, sizeof lhs);
    } else {
        LHS_TYPE temp(lhs);
        lhs = rhs;
        rhs = temp;
    }
}

template <class LHS_TYPE, class RHS_TYPE>
void ScalarPrimitives_Imp::swap(LHS_TYPE&                   lhs,
                                RHS_TYPE&                   rhs,
                                bsl::integral_constant<int, e_NIL_TRAITS> *)
{
    LHS_TYPE temp(lhs);
    lhs = rhs;
    rhs = temp;
}

}  // close package namespace

#ifndef BDE_OPENSOURCE_PUBLICATION  // BACKWARD_COMPATIBILITY
// ============================================================================
//                           BACKWARD COMPATIBILITY
// ============================================================================

/// This alias is defined for backward compatibility.
typedef bslalg::ScalarPrimitives bslalg_ScalarPrimitives;
#endif  // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY

}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2013 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 ----------------------------------
