native_std::size_t HashTableBucket::countElements() const
{
    native_std::size_t result = 0;
    for (BidirectionalLink *cursor     = d_first_p,
                           * endBucket = end();
                            endBucket != cursor; cursor = cursor->nextLink()) {
        ++result;
    }

    return result;
}
void BidirectionalLinkListUtil::spliceListBeforeTarget
                                                   (BidirectionalLink *first,
                                                    BidirectionalLink *last,
                                                    BidirectionalLink *target)
{
    BSLS_ASSERT_SAFE(first);
    BSLS_ASSERT_SAFE(last);
#ifdef BDE_BUILD_TARGET_SAFE_2
    // Test to avoid creating loops is O(N) expensive, so check only in SAFE_2

    BidirectionalLink *cursor = first;
    while(cursor != last->nextLink()) {
        BSLS_ASSERT_SAFE(cursor != target);
        cursor = cursor->nextLink();
    }
    BSLS_ASSERT_SAFE(isWellFormed(first, last));
#endif

    // unlink from existing list

    if (BidirectionalLink* prev = first->previousLink()) {
        prev->setNextLink(last->nextLink());
    }
    if (BidirectionalLink* next = last->nextLink()) {
        next->setPreviousLink(first->previousLink());
    }

    // update into spliced location:

    if (!target) {
        // Prepending target an empty list is *explicitly* *allowed*
        // The "spliced" segment is still extracted from the original list

        first->setPreviousLink(0);  // redundant with pre-condition
        last->setNextLink(0);
    }
    else {
        if (BidirectionalLink *prev = target->previousLink()) {
            first->setPreviousLink(prev);
            prev->setNextLink(first);
        }
        else {
            first->setPreviousLink(0);
        }

        last->setNextLink(target);
        target->setPreviousLink(last);
    }
}
void BidirectionalLinkListUtil::insertLinkAfterTarget(
                                                    BidirectionalLink *newNode,
                                                    BidirectionalLink *target)
{
    BSLS_ASSERT_SAFE(newNode);
    BSLS_ASSERT_SAFE(target);

    BidirectionalLink *next = target->nextLink();

#ifdef BDE_BUILD_TARGET_SAFE_2
    BSLS_ASSERT_SAFE(!next || isWellFormed(target, next));
#endif

    target->setNextLink(newNode);
    if (next) {
        next->setPreviousLink(newNode);
    }

    newNode->setPreviousLink(target);
    newNode->setNextLink(next);
}
void BidirectionalLinkListUtil::unlink(BidirectionalLink *node)
{
    BSLS_ASSERT_SAFE(node);

    BidirectionalLink *prev = node->previousLink(), *next = node->nextLink();

    if (prev) {
        if (next) {
            BSLS_ASSERT_SAFE(isWellFormed(prev, next));

            next->setPreviousLink(prev);
            prev->setNextLink(next);
        }
        else {
            prev->setNextLink(0);
        }
    }
    else if (next) {
        next->setPreviousLink(0);
    }
}