// bslstl_treenodepool_cpp03.h                                        -*-C++-*-

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

#ifndef INCLUDED_BSLSTL_TREENODEPOOL_CPP03
#define INCLUDED_BSLSTL_TREENODEPOOL_CPP03

//@PURPOSE: Provide C++03 implementation for bslstl_treenodepool.h
//
//@CLASSES: See bslstl_treenodepool.h for list of classes
//
//@SEE_ALSO: bslstl_treenodepool
//
//@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_treenodepool.h

#ifdef COMPILING_BSLSTL_TREENODEPOOL_H

namespace BloombergLP {
namespace bslstl {

                       // ==================
                       // class TreeNodePool
                       // ==================

template <class VALUE, class ALLOCATOR>
class TreeNodePool {
    // This class provides methods for creating and deleting nodes using the
    // appropriate allocator traits of the (template parameter) type
    // 'ALLOCATOR'.  This type is intended to be used as a private base-class
    // for a node-based container, in order to take advantage of the
    // empty-base-class optimization in the case where the base class has 0
    // size (as may be the case if the (template parameter) type 'ALLOCATOR' is
    // not a 'bslma::Allocator').

    typedef SimplePool<TreeNode<VALUE>, ALLOCATOR> Pool;
        // Alias for the memory pool allocator.

    typedef typename Pool::AllocatorTraits         AllocatorTraits;
        // 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
    TreeNodePool(const TreeNodePool&);
    TreeNodePool& operator=(const TreeNodePool&);
    TreeNodePool& operator=(bslmf::MovableRef<TreeNodePool>);

  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 TreeNodePool(const ALLOCATOR& allocator);
        // Create a node-pool that will use the specified 'allocator' to supply
        // memory for allocated node objects.

    TreeNodePool(bslmf::MovableRef<TreeNodePool> original);
        // Create a 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.

    // MANIPULATORS
    void adopt(bslmf::MovableRef<TreeNodePool> 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 rebound
        // allocator traits for the node-type.  Note that this operation
        // returns a base-class ('NodeAlloc') reference to this object.

    bslalg::RbTreeNode *cloneNode(const bslalg::RbTreeNode& original);
        // Allocate a node object 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 newly allocated node.  The behavior is undefined unless
        // 'original' refers to a 'TreeNode<VALUE>' object holding a valid
        // (initialized) value.

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_treenodepool.h
#ifndef BSLSTL_TREENODEPOOL_VARIADIC_LIMIT
#define BSLSTL_TREENODEPOOL_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A
#define BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A BSLSTL_TREENODEPOOL_VARIADIC_LIMIT
#endif
#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 0
    bslalg::RbTreeNode *emplaceIntoNewNode(
                              );
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 0

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 1
    template <class Args_01>
    bslalg::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 1

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 2
    template <class Args_01,
              class Args_02>
    bslalg::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 2

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 3
    template <class Args_01,
              class Args_02,
              class Args_03>
    bslalg::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 3

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 4
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04>
    bslalg::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 4

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 5
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05>
    bslalg::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 5

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 6
    template <class Args_01,
              class Args_02,
              class Args_03,
              class Args_04,
              class Args_05,
              class Args_06>
    bslalg::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 6

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 7

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 8

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09);
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_A >= 9

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *emplaceIntoNewNode(
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09,
                           BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) args_10);
#endif  // BSLSTL_TREENODEPOOL_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::RbTreeNode *emplaceIntoNewNode(
                              BSLS_COMPILERFEATURES_FORWARD_REF(Args)... args);
// }}} END GENERATED CODE
#endif

    void deleteNode(bslalg::RbTreeNode *node);
        // Destroy the 'VALUE' value of the specified 'node' and return the
        // memory footprint of 'node' to this pool for potential reuse.  The
        // behavior is undefined unless 'node' refers to a 'TreeNode<VALUE>'.

    bslalg::RbTreeNode *moveIntoNewNode(bslalg::RbTreeNode *original);
        // Allocate a node of the type 'TreeNode<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' node.  Return the address of the newly allocated node.
        // The object referred to by the 'value' attribute of 'original' is
        // left in a valid but unspecified state.  The behavior is undefined
        // unless 'original' refers to a 'TreeNode<VALUE>' object holding a
        // valid (initialized) value.

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

    void swap(TreeNodePool& 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(TreeNodePool& other);
        // Efficiently exchange the nodes and allocator of this object with
        // those of the specified 'other' object.  This method provides the
        // no-throw exception-safety guarantee, *unless* swapping the
        // (user-supplied) allocator objects can throw.

    void swapRetainAllocators(TreeNodePool& 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()'.

    // ACCESSORS
    const AllocatorType& allocator() const;
        // Return a reference providing non-modifiable access to the rebound
        // allocator traits for the node-type.  Note that this operation
        // returns a base-class ('NodeAlloc') reference to this object.

    bool hasFreeNodes() const;
        // Return 'true' if this object holds free (currently unused) nodes,
        // and 'false' otherwise.
};

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

                       // ------------------
                       // class TreeNodePool
                       // ------------------

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

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

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

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

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

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl bslstl_treenodepool.h
#ifndef BSLSTL_TREENODEPOOL_VARIADIC_LIMIT
#define BSLSTL_TREENODEPOOL_VARIADIC_LIMIT 10
#endif
#ifndef BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B
#define BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B BSLSTL_TREENODEPOOL_VARIADIC_LIMIT
#endif
#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 0
template <class VALUE, class ALLOCATOR>
inline
bslalg::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                               )
{
    TreeNode<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_TREENODEPOOL_VARIADIC_LIMIT_B >= 0

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 1
template <class VALUE, class ALLOCATOR>
template <class Args_01>
inline
bslalg::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01)
{
    TreeNode<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,args_01));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 1

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 2
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02>
inline
bslalg::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 2

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 3
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03>
inline
bslalg::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 3

#if BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 4
template <class VALUE, class ALLOCATOR>
template <class Args_01,
          class Args_02,
          class Args_03,
          class Args_04>
inline
bslalg::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 4

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 5

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 6

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 7

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 8

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(Args_09,args_09));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_VARIADIC_LIMIT_B >= 9

#if BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) args_01,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) args_02,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) args_03,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) args_04,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) args_05,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) args_06,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) args_07,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) args_08,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) args_09,
                            BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) args_10)
{
    TreeNode<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,args_01),
                               BSLS_COMPILERFEATURES_FORWARD(Args_02,args_02),
                               BSLS_COMPILERFEATURES_FORWARD(Args_03,args_03),
                               BSLS_COMPILERFEATURES_FORWARD(Args_04,args_04),
                               BSLS_COMPILERFEATURES_FORWARD(Args_05,args_05),
                               BSLS_COMPILERFEATURES_FORWARD(Args_06,args_06),
                               BSLS_COMPILERFEATURES_FORWARD(Args_07,args_07),
                               BSLS_COMPILERFEATURES_FORWARD(Args_08,args_08),
                               BSLS_COMPILERFEATURES_FORWARD(Args_09,args_09),
                               BSLS_COMPILERFEATURES_FORWARD(Args_10,args_10));
    proctor.release();
    return node;
}
#endif  // BSLSTL_TREENODEPOOL_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::RbTreeNode *
TreeNodePool<VALUE, ALLOCATOR>::emplaceIntoNewNode(
                               BSLS_COMPILERFEATURES_FORWARD_REF(Args)... args)
{
    TreeNode<VALUE> *node = d_pool.allocate();
    bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);

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

template <class VALUE, class ALLOCATOR>
inline
void TreeNodePool<VALUE, ALLOCATOR>::deleteNode(bslalg::RbTreeNode *node)
{
    BSLS_ASSERT(node);

    TreeNode<VALUE> *treeNode = static_cast<TreeNode<VALUE> *>(node);
    AllocatorTraits::destroy(allocator(),
                             BSLS_UTIL_ADDRESSOF(treeNode->value()));
    d_pool.deallocate(treeNode);
}

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

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

    d_pool.reserve(numNodes);
}

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

    d_pool.swap(other.d_pool);
}

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

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

    d_pool.quickSwapRetainAllocators(other.d_pool);
}

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

template <class VALUE, class ALLOCATOR>
inline
bool TreeNodePool<VALUE, ALLOCATOR>::hasFreeNodes() const
{
    return d_pool.hasFreeBlocks();
}

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

#else // if ! defined(DEFINED_BSLSTL_TREENODEPOOL_H)
# error Not valid except when included from bslstl_treenodepool.h
#endif // ! defined(COMPILING_BSLSTL_TREENODEPOOL_H)

#endif // ! defined(INCLUDED_BSLSTL_TREENODEPOOL_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 ----------------------------------