// 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 Thu Oct 21 10:11:37 2021
// Command line: sim_cpp11_features.pl bslstl_bidirectionalnodepool.h

#ifdef COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H

namespace BloombergLP {
namespace bslstl {

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

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

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

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

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

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

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

  public:
    // PUBLIC TYPE
    typedef typename Pool::AllocatorType AllocatorType;
        // Alias for the allocator type defined by 'SimplePool'.

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

  public:
    // CREATORS
    explicit BidirectionalNodePool(const ALLOCATOR& allocator);
        // 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 *'.

    BidirectionalNodePool(bslmf::MovableRef<BidirectionalNodePool> original);
        // 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() = default;
        // 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.

    // MANIPULATORS
    void adopt(bslmf::MovableRef<BidirectionalNodePool> pool);
        // 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.

    AllocatorType& allocator();
        // 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.

    bslalg::BidirectionalLink *cloneNode(
                                    const bslalg::BidirectionalLink& original);
        // 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.

    void deleteNode(bslalg::BidirectionalLink *linkNode);
        // 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.

#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

    bslalg::BidirectionalLink *moveIntoNewNode(
                                          bslalg::BidirectionalLink *original);
        // 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.

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

    void reserveNodes(size_type numNodes);
        // 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 swapRetainAllocators(BidirectionalNodePool& other);
        // 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 swapExchangeAllocators(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.

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

// FREE FUNCTIONS
template <class VALUE, class ALLOCATOR>
void swap(BidirectionalNodePool<VALUE, ALLOCATOR>& a,
          BidirectionalNodePool<VALUE, ALLOCATOR>& b);
    // 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()'.

}  // 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 2021 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 ----------------------------------