// bslstl_bidirectionalnodepool_cpp03.h                               -*-C++-*-

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

#ifndef INCLUDED_BSLSTL_BIDIRECTIONALNODEPOOL_CPP03
#define INCLUDED_BSLSTL_BIDIRECTIONALNODEPOOL_CPP03

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

#ifdef COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H

namespace BloombergLP {
namespace bslstl {

                       // ===========================
                       // class BidirectionalNodePool
                       // ===========================

/// This class provides methods for creating and destroying nodes using the
/// appropriate allocator-traits of the (template parameter) type
/// `ALLOCATOR`.
template <class VALUE, class ALLOCATOR>
class BidirectionalNodePool {

    // PRIVATE TYPES

    /// This `typedef` is an alias for the memory pool allocator.
    typedef SimplePool<bslalg::BidirectionalNode<VALUE>, ALLOCATOR> Pool;

    /// This `typedef` is an alias for the allocator traits defined by
    /// `SimplePool`.
    typedef typename Pool::AllocatorTraits                     AllocatorTraits;

    /// This typedef is a convenient alias for the utility associated with
    /// movable references.
    typedef bslmf::MovableRefUtil                              MoveUtil;

    // DATA
    Pool d_pool;  // pool for allocating memory

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

  public:
    // PUBLIC TYPE

    /// Alias for the allocator type defined by `SimplePool`.
    typedef typename Pool::AllocatorType AllocatorType;

    /// Alias for the `size_type` of the allocator defined by `SimplePool`.
    typedef typename AllocatorTraits::size_type size_type;

  public:
    // CREATORS

    /// Create a `BidirectionalNodePool` object that will use the specified
    /// `allocator` to supply memory for allocated node objects.  If the
    /// (template parameter) `ALLOCATOR` is `bsl::allocator`, then
    /// `allocator` shall be convertible to `bslma::Allocator *`.
    explicit BidirectionalNodePool(const ALLOCATOR& allocator);

    /// Create a bidirectional node-pool, adopting all outstanding memory
    /// allocations associated with the specified `original` node-pool, that
    /// will use the allocator associated with `original` to supply memory
    /// for allocated node objects.  `original` is left in a valid but
    /// unspecified state.
    BidirectionalNodePool(bslmf::MovableRef<BidirectionalNodePool> original);

    /// Destroy the memory pool maintained by this object, releasing all
    /// memory used by the nodes of the type `BidirectionalNode<VALUE>` in
    /// the pool.  Any memory allocated for the nodes` `value` attribute of
    /// the (template parameter) type `VALUE` will be leaked unless the
    /// nodes are explicitly destroyed via the `destroyNode` method.
    //! ~BidirectionalNodePool() = default;

    // MANIPULATORS

    /// Adopt all outstanding memory allocations associated with the
    /// specified node `pool`.  The behavior is undefined unless this pool
    /// uses the same allocator as that associated with `pool`.  The
    /// behavior is also undefined unless this pool is in the
    /// default-constructed state.
    void adopt(bslmf::MovableRef<BidirectionalNodePool> pool);

    /// Return a reference providing modifiable access to the allocator
    /// supplying memory for the memory pool maintained by this object.  The
    /// behavior is undefined if the allocator used by this object is
    /// changed with this method.  Note that this method provides modifiable
    /// access to enable a client to call non-`const` methods on the
    /// allocator.
    AllocatorType& allocator();

    /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
    /// copy-construct an object of the (template parameter) type `VALUE`
    /// having the same value as the specified `original` at the `value`
    /// attribute of the node.  Return the address of the node.  Note that
    /// the `next` and `prev` attributes of the returned node will be
    /// uninitialized.
    bslalg::BidirectionalLink *cloneNode(
                                    const bslalg::BidirectionalLink& original);

    /// Destroy the `VALUE` attribute of the specified `linkNode` and return
    /// the memory footprint of `linkNode` to this pool for potential reuse.
    /// The behavior is undefined unless `node` refers to a
    /// `bslalg::BidirectionalNode<VALUE>` that was allocated by this pool.
    void deleteNode(bslalg::BidirectionalLink *linkNode);

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_bidirectionalnodepool.h
#ifndef BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT
#define BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A
#define BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT
#endif
#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 0
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                         );
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 0

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 1
    template <class Args_01>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 1

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 2
    template <class Args_01,
              class Args_02>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 2

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 3
    template <class Args_01,
              class Args_02,
              class Args_03>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 3

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 4
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 4

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 5
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 5

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 6
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05,
              class Args_06>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 6

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 7
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05,
              class Args_06,
              class Args_07>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 7

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 8
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05,
              class Args_06,
              class Args_07,
              class Args_08>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 8

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 9
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05,
              class Args_06,
              class Args_07,
              class Args_08,
              class Args_09>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 9

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 10
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05,
              class Args_06,
              class Args_07,
              class Args_08,
              class Args_09,
              class Args_10>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09,
                      BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) arguments_10);
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_A >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
    template <class... Args>
    bslalg::BidirectionalLink *emplaceIntoNewNode(
                         BSLS_COMPILERFEATURES_FORWARD_REF(Args)... arguments);
// }}} END GENERATED CODE
#endif

    /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
    /// move-construct an object of the (template parameter) type `VALUE`
    /// with the (explicitly moved) value indicated by the `value` attribute
    /// of the specified `original` link.  Return the address of the node.
    /// Note that the `next` and `prev` attributes of the returned node will
    /// be uninitialized.  Also note that the `value` attribute of
    /// `original` is left in a valid but unspecified state.
    bslalg::BidirectionalLink *moveIntoNewNode(
                                          bslalg::BidirectionalLink *original);

    /// Relinquish all memory currently allocated with the memory pool
    /// maintained by this object.
    void release();

    /// Add to this pool sufficient memory to satisfy memory requests for at
    /// least the specified `numNodes` before the pool replenishes.  The
    /// additional memory is added irrespective of the amount of free memory
    /// when called.  The behavior is undefined unless `0 < numNodes`.
    void reserveNodes(size_type numNodes);

    /// Efficiently exchange the nodes of this object with those of the
    /// specified `other` object.  This method provides the no-throw
    /// exception-safety guarantee.  The behavior is undefined unless
    /// `allocator() == other.allocator()`.
    void swapRetainAllocators(BidirectionalNodePool& other);

    /// Efficiently exchange the nodes and the allocator of this object with
    /// those of the specified `other` object.  This method provides the
    /// no-throw exception-safety guarantee.
    void swapExchangeAllocators(BidirectionalNodePool& other);

    // ACCESSORS

    /// Return a reference providing non-modifiable access to the allocator
    /// supplying memory for the memory pool maintained by this object.
    const AllocatorType& allocator() const;
};

// FREE FUNCTIONS

/// Efficiently exchange the nodes of the specified `a` object with those of
/// the specified `b` object.  This method provides the no-throw
/// exception-safety guarantee.  The behavior is undefined unless
/// `a.allocator() == b.allocator()`.
template <class VALUE, class ALLOCATOR>
void swap(BidirectionalNodePool<VALUE, ALLOCATOR>& a,
          BidirectionalNodePool<VALUE, ALLOCATOR>& b);

}  // close package namespace


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

// Type traits for HashTable:
//: o A HashTable is bitwise moveable if the allocator is bitwise moveable.

namespace bslmf {

template <class VALUE, class ALLOCATOR>
struct IsBitwiseMoveable<bslstl::BidirectionalNodePool<VALUE, ALLOCATOR> >
: bsl::integral_constant<bool, bslmf::IsBitwiseMoveable<ALLOCATOR>::value>
{};

}  // close namespace bslmf

// ============================================================================
//                  TEMPLATE AND INLINE FUNCTION DEFINITIONS
// ============================================================================

namespace bslstl {

// CREATORS
template <class VALUE, class ALLOCATOR>
inline
BidirectionalNodePool<VALUE, ALLOCATOR>::BidirectionalNodePool(
                                                    const ALLOCATOR& allocator)
: d_pool(allocator)
{
}

template <class VALUE, class ALLOCATOR>
inline
BidirectionalNodePool<VALUE, ALLOCATOR>::BidirectionalNodePool(
                             bslmf::MovableRef<BidirectionalNodePool> original)
: d_pool(MoveUtil::move(MoveUtil::access(original).d_pool))
{
}

// MANIPULATORS
template <class VALUE, class ALLOCATOR>
inline
void BidirectionalNodePool<VALUE, ALLOCATOR>::adopt(
                                 bslmf::MovableRef<BidirectionalNodePool> pool)
{
    BidirectionalNodePool& lvalue = pool;
    d_pool.adopt(MoveUtil::move(lvalue.d_pool));
}

template <class VALUE, class ALLOCATOR>
inline
typename
SimplePool<bslalg::BidirectionalNode<VALUE>, ALLOCATOR>::AllocatorType&
BidirectionalNodePool<VALUE, ALLOCATOR>::allocator()
{
    return d_pool.allocator();
}

template <class VALUE, class ALLOCATOR>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::cloneNode(
                                     const bslalg::BidirectionalLink& original)
{
    return emplaceIntoNewNode(
       static_cast<const bslalg::BidirectionalNode<VALUE>&>(original).value());
}

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_bidirectionalnodepool.h
#ifndef BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT
#define BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B
#define BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT
#endif
#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 0
template <class VALUE, class ALLOCATOR>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                          )
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 0

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 1
template <class VALUE, class ALLOCATOR>
template <class Args_01>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 1

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 2
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 2

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 3
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 3

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 4
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 4

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 5
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04,
          class Args_05>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(Args_05,arguments_05));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 5

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 6
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04,
          class Args_05,
          class Args_06>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(Args_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(Args_06,arguments_06));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 6

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 7
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04,
          class Args_05,
          class Args_06,
          class Args_07>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(Args_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(Args_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(Args_07,arguments_07));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 7

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 8
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04,
          class Args_05,
          class Args_06,
          class Args_07,
          class Args_08>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(Args_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(Args_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(Args_07,arguments_07),
                          BSLS_COMPILERFEATURES_FORWARD(Args_08,arguments_08));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 8

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 9
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04,
          class Args_05,
          class Args_06,
          class Args_07,
          class Args_08,
          class Args_09>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(Args_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(Args_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(Args_07,arguments_07),
                          BSLS_COMPILERFEATURES_FORWARD(Args_08,arguments_08),
                          BSLS_COMPILERFEATURES_FORWARD(Args_09,arguments_09));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 9

#if BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 10
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04,
          class Args_05,
          class Args_06,
          class Args_07,
          class Args_08,
          class Args_09,
          class Args_10>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09,
                       BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) arguments_10)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                          BSLS_COMPILERFEATURES_FORWARD(Args_01,arguments_01),
                          BSLS_COMPILERFEATURES_FORWARD(Args_02,arguments_02),
                          BSLS_COMPILERFEATURES_FORWARD(Args_03,arguments_03),
                          BSLS_COMPILERFEATURES_FORWARD(Args_04,arguments_04),
                          BSLS_COMPILERFEATURES_FORWARD(Args_05,arguments_05),
                          BSLS_COMPILERFEATURES_FORWARD(Args_06,arguments_06),
                          BSLS_COMPILERFEATURES_FORWARD(Args_07,arguments_07),
                          BSLS_COMPILERFEATURES_FORWARD(Args_08,arguments_08),
                          BSLS_COMPILERFEATURES_FORWARD(Args_09,arguments_09),
                          BSLS_COMPILERFEATURES_FORWARD(Args_10,arguments_10));
    proctor.release();
    return node;
}
#endif  // BSLSTL_BIDIRECTIONALNODEPOOL_VARIADIC_LIMIT_B >= 10

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class VALUE, class ALLOCATOR>
template <class... Args>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                          BSLS_COMPILERFEATURES_FORWARD_REF(Args)... arguments)
{
    bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

    AllocatorTraits::construct(
                             allocator(),
                             bsls::Util::addressOf(node->value()),
                             BSLS_COMPILERFEATURES_FORWARD(Args,arguments)...);
    proctor.release();
    return node;
}
// }}} END GENERATED CODE
#endif

template <class VALUE, class ALLOCATOR>
inline
bslalg::BidirectionalLink *
BidirectionalNodePool<VALUE, ALLOCATOR>::moveIntoNewNode(
                                           bslalg::BidirectionalLink *original)
{
    return emplaceIntoNewNode(MoveUtil::move(
        static_cast<bslalg::BidirectionalNode<VALUE> *>(original)->value()));
}

template <class VALUE, class ALLOCATOR>
void BidirectionalNodePool<VALUE, ALLOCATOR>::deleteNode(
                                           bslalg::BidirectionalLink *linkNode)
{
    BSLS_ASSERT(linkNode);

    bslalg::BidirectionalNode<VALUE> *node =
                     static_cast<bslalg::BidirectionalNode<VALUE> *>(linkNode);
    AllocatorTraits::destroy(allocator(),
                             bsls::Util::addressOf(node->value()));
    d_pool.deallocate(node);
}

template <class VALUE, class ALLOCATOR>
inline
void BidirectionalNodePool<VALUE, ALLOCATOR>::release()
{
    d_pool.release();
}

template <class VALUE, class ALLOCATOR>
inline
void BidirectionalNodePool<VALUE, ALLOCATOR>::reserveNodes(size_type numNodes)
{
    BSLS_ASSERT_SAFE(0 < numNodes);

    d_pool.reserve(numNodes);
}

template <class VALUE, class ALLOCATOR>
inline
void BidirectionalNodePool<VALUE, ALLOCATOR>::swapRetainAllocators(
                                BidirectionalNodePool<VALUE, ALLOCATOR>& other)
{
    BSLS_ASSERT_SAFE(allocator() == other.allocator());

    d_pool.quickSwapRetainAllocators(other.d_pool);
}

template <class VALUE, class ALLOCATOR>
inline
void BidirectionalNodePool<VALUE, ALLOCATOR>::swapExchangeAllocators(
                                BidirectionalNodePool<VALUE, ALLOCATOR>& other)
{
    d_pool.quickSwapExchangeAllocators(other.d_pool);
}

// ACCESSORS
template <class VALUE, class ALLOCATOR>
inline
const typename
              SimplePool<bslalg::BidirectionalNode<VALUE>, ALLOCATOR>::
                                                                 AllocatorType&
BidirectionalNodePool<VALUE, ALLOCATOR>::allocator() const
{
    return d_pool.allocator();
}

}  // close package namespace

template <class VALUE, class ALLOCATOR>
inline
void bslstl::swap(bslstl::BidirectionalNodePool<VALUE, ALLOCATOR>& a,
                  bslstl::BidirectionalNodePool<VALUE, ALLOCATOR>& b)
{
    a.swapRetainAllocators(b);
}

}  // close enterprise namespace

#else // if ! defined(DEFINED_BSLSTL_BIDIRECTIONALNODEPOOL_H)
# error Not valid except when included from bslstl_bidirectionalnodepool.h
#endif // ! defined(COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H)

#endif // ! defined(INCLUDED_BSLSTL_BIDIRECTIONALNODEPOOL_CPP03)

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