// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <unittest/unittest.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/tests/intrusive_containers/objects.h>
#include <fbl/tests/intrusive_containers/test_environment_utils.h>
#include <fbl/unique_ptr.h>

#include <utility>

namespace fbl {
namespace tests {
namespace intrusive_containers {

// TestEnvironmentBase<>
//
// The base class for all tests environments.  TestEnvironmentBase handles
// creating and tracking raw pointers to test objects so they can be cleaned up
// without leaking, even while testing unmanaged pointer types.
// TestEnvironmentBase is also where the default container storage lives.
template <typename TestEnvTraits>
class TestEnvironmentBase {
public:
    using ObjType       = typename TestEnvTraits::ObjType;
    using PtrType       = typename TestEnvTraits::PtrType;
    using ContainerType = typename TestEnvTraits::ContainerType;
    using PtrTraits     = typename ContainerType::PtrTraits;

protected:
    PtrType CreateTrackedObject(size_t ndx, size_t value, bool ref_held) {
        if ((ndx >= OBJ_COUNT) ||objects_[ndx])
            return PtrType(nullptr);

        PtrType ret = TestEnvTraits::CreateObject(value);
        if (ret == nullptr)
            return PtrType(nullptr);

        objects_[ndx] = PtrTraits::GetRaw(ret);

        if (ref_held)
            refs_held_++;

        return std::move(ret);
    }

    static constexpr size_t OBJ_COUNT = 17;

    ContainerType container_;
    ObjType*      objects_[OBJ_COUNT] = { nullptr };
    size_t        refs_held_ = 0;
};

// TestEnvironmentSpecialized<>
//
// Specializations of the base test environment which handle the specific
// details of testing the various pointer types.
template <typename TestEnvTraits>
class TestEnvironmentSpecialized;

template <typename T>
class TestEnvironmentSpecialized<UnmanagedTestTraits<T>> :
    public TestEnvironmentBase<UnmanagedTestTraits<T>> {
protected:
    using Base = TestEnvironmentBase<UnmanagedTestTraits<T>>;
    using PtrType = typename Base::PtrType;
    static constexpr auto OBJ_COUNT = Base::OBJ_COUNT;

    void ReleaseObject(size_t ndx) {
        if (HoldingObject(ndx)) {
            delete this->objects_[ndx];
            this->objects_[ndx] = nullptr;
            this->refs_held_--;
        }
    }

    bool HoldingObject(size_t ndx) const {
        return ((ndx < OBJ_COUNT) && this->objects_[ndx]);
    }

    PtrType CreateTrackedObject(size_t ndx, size_t value, bool hold_ref = false) {
        return Base::CreateTrackedObject(ndx, value, true);
    }
};

template <typename T>
class TestEnvironmentSpecialized<UniquePtrTestTraits<T>> :
    public TestEnvironmentBase<UniquePtrTestTraits<T>> {
protected:
    using Base = TestEnvironmentBase<UniquePtrTestTraits<T>>;
    using PtrType = typename Base::PtrType;
    static constexpr auto OBJ_COUNT = Base::OBJ_COUNT;

    void ReleaseObject(size_t ndx) {
        if (ndx < OBJ_COUNT)
            this->objects_[ndx] = nullptr;
    }

    bool HoldingObject(size_t ndx) const {
        return false;
    }

    PtrType CreateTrackedObject(size_t ndx, size_t value, bool hold_ref = false) {
        return Base::CreateTrackedObject(ndx, value, false);
    }
};

template <typename T>
class TestEnvironmentSpecialized<StdUniquePtrDefaultDeleterTestTraits<T>> :
    public TestEnvironmentBase<StdUniquePtrDefaultDeleterTestTraits<T>> {
protected:
    using Base = TestEnvironmentBase<StdUniquePtrDefaultDeleterTestTraits<T>>;
    using PtrType = typename Base::PtrType;
    static constexpr auto OBJ_COUNT = Base::OBJ_COUNT;

    void ReleaseObject(size_t ndx) {
        if (ndx < OBJ_COUNT)
            this->objects_[ndx] = nullptr;
    }

    bool HoldingObject(size_t ndx) const {
        return false;
    }

    PtrType CreateTrackedObject(size_t ndx, size_t value, bool hold_ref = false) {
        return Base::CreateTrackedObject(ndx, value, false);
    }
};

template <typename T>
class TestEnvironmentSpecialized<StdUniquePtrCustomDeleterTestTraits<T>> :
    public TestEnvironmentBase<StdUniquePtrCustomDeleterTestTraits<T>> {
protected:
    using Base = TestEnvironmentBase<StdUniquePtrCustomDeleterTestTraits<T>>;
    using PtrType = typename Base::PtrType;
    static constexpr auto OBJ_COUNT = Base::OBJ_COUNT;

    void ReleaseObject(size_t ndx) {
        if (ndx < OBJ_COUNT)
            this->objects_[ndx] = nullptr;
    }

    bool HoldingObject(size_t ndx) const {
        return false;
    }

    PtrType CreateTrackedObject(size_t ndx, size_t value, bool hold_ref = false) {
        return Base::CreateTrackedObject(ndx, value, false);
    }
};

template <typename T>
class TestEnvironmentSpecialized<RefPtrTestTraits<T>> :
    public TestEnvironmentBase<RefPtrTestTraits<T>> {
protected:
    using Base = TestEnvironmentBase<RefPtrTestTraits<T>>;
    using PtrType = typename Base::PtrType;
    static constexpr auto OBJ_COUNT = Base::OBJ_COUNT;

    PtrType CreateTrackedObject(size_t ndx, size_t value, bool hold_ref = false) {
        PtrType ret = Base::CreateTrackedObject(ndx, value, hold_ref);

        if (hold_ref)
            refed_objects_[ndx] = ret;

        return std::move(ret);
    }

    void ReleaseObject(size_t ndx) {
        if (ndx < OBJ_COUNT) {
            this->objects_[ndx] = nullptr;
            if (refed_objects_[ndx]) {
                refed_objects_[ndx] = nullptr;
                this->refs_held_--;
            }
        }
    }

    bool HoldingObject(size_t ndx) const {
        return ((ndx < OBJ_COUNT) && (refed_objects_[ndx] != nullptr));
    }

private:
    PtrType refed_objects_[OBJ_COUNT];
};

// TestEnvironment<>
//
// Test environment which defines and implements tests and test utilities which
// are applicable to all containers.
template <typename TestEnvTraits>
class TestEnvironment : public TestEnvironmentSpecialized<TestEnvTraits> {
public:
    using ObjType            = typename TestEnvTraits::ObjType;
    using PtrType            = typename TestEnvTraits::PtrType;
    using ContainerTraits    = typename ObjType::ContainerTraits;
    using ContainerType      = typename ContainerTraits::ContainerType;
    using ContainerChecker   = typename ContainerType::CheckerType;
    using OtherContainerType = typename ContainerTraits::OtherContainerType;
    using PtrTraits          = typename ContainerType::PtrTraits;
    using NodeTraits         = typename ContainerType::NodeTraits;

    enum class RefAction {
        HoldNone,
        HoldSome,
        HoldAll,
    };

    TestEnvironment() { TestEnvTraits::ResetCustomDeleter(); }
    ~TestEnvironment() { Reset(); }

    // Utility methods used to check if the target of an Erase operation is
    // valid, whether the target of the operation is expressed as an iterator, a
    // key or as an object pointer.
    bool ValidEraseTarget(size_t key)      { return container().find(key).IsValid(); }
    bool ValidEraseTarget(ObjType& target) { return NodeTraits::node_state(target).InContainer(); }
    bool ValidEraseTarget(typename ContainerType::iterator& target) {
        return target.IsValid() && NodeTraits::node_state(*target).InContainer();
    }

    // Utility method for checking the size of the container via either size()
    // or size_slow(), depending on whether or not the container supports a
    // constant order size operation.
    template <typename CType>
    static size_t Size(const CType& container) {
        return SizeUtils<CType>::size(container);
    }

    // The default method for populating a container will depend on whether this
    // is a sequence container or an associative container.  Sequenced
    // containers will use an implementation of push_front while associative
    // containers will assign a key to the objects which get created and then
    // use an implementation of insert.
    virtual bool Populate(ContainerType& container, RefAction ref_action = RefAction::HoldSome) = 0;

    bool Reset() {
        BEGIN_TEST;

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
        container().clear();
        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");

        for (size_t i = 0; i < OBJ_COUNT; ++i)
            ReleaseObject(i);

        EXPECT_EQ(0u, refs_held(), "");
        refs_held() = 0;

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        ObjType::ResetLiveObjCount();

        END_TEST;
    }

    bool Clear() {
        BEGIN_TEST;

        // Start by making some objects.
        ASSERT_TRUE(Populate(container()), "");

        // Clear the container.  Afterwards, the number of live objects we have
        // should be equal to the number of references being held by the test
        // environment.
        container().clear();
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_EQ(refs_held(), ObjType::live_obj_count(), "");

        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_NONNULL(objects()[i], "");

            // If our underlying object it still being kept alive by the test
            // environment, make sure that its internal pointer state has been
            // properly cleared out.
            if (HoldingObject(i)) {
                auto& ns = ContainerType::NodeTraits::node_state(*objects()[i]);
                EXPECT_FALSE(ns.InContainer(), "");
            }
        }

        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
        END_TEST;
    }

    bool ClearUnsafe() {
        BEGIN_TEST;

        // Start by making some objects.
        ASSERT_TRUE(Populate(container()), "");

        // Perform an unsafe clear of the container.  Afterwards, the number of
        // live objects we have should be equal to the number of elements
        // initially added to the container, since the unsafe operation should
        // not have released any references to any objects during the unsafe
        // clear operation.
        //
        // Note: This is currently a moot point.  clear_unsafe() operations are
        // only currently allowed on unmanaged pointers, and the test framework
        // (by necessity) always hold references to all internally allocated
        // unmanaged objects.
        container().clear_unsafe();
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");

        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_NONNULL(objects()[i], "");

            // Make sure that the internal pointer states of all of our objects
            // do not know yet that they have been removed from the container.
            // The clear_unsafe operation should not have updated any of the
            // internal object states.
            auto& ns = ContainerType::NodeTraits::node_state(*objects()[i]);
            EXPECT_TRUE(ns.InContainer(), "");
        }

        END_TEST;
    }

    bool IsEmpty() {
        BEGIN_TEST;

        EXPECT_TRUE(container().is_empty(), "");
        ASSERT_TRUE(Populate(container()), "");
        EXPECT_FALSE(container().is_empty(), "");
        EXPECT_TRUE(Reset(), "");
        EXPECT_TRUE(container().is_empty(), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));

        END_TEST;
    }

    template <typename TargetType>
    bool DoErase(TargetType&& target, size_t ndx, size_t remaining, bool check_ndx = true) {
        BEGIN_TEST;

        ASSERT_TRUE(ndx < OBJ_COUNT, "");
        ASSERT_TRUE(remaining <= OBJ_COUNT, "");
        ASSERT_TRUE(!container().is_empty(), "");
        ASSERT_TRUE(ValidEraseTarget(target), "");
        EXPECT_EQ(remaining, ObjType::live_obj_count(), "");
        EXPECT_EQ(remaining, Size(container()), "");
        size_t erased_ndx;

        {
            // Erase the item and sanity check it against our tracking.
            PtrType tmp = container().erase(target);
            ASSERT_NONNULL(tmp, "");
            if (check_ndx) {
                EXPECT_EQ(tmp->value(), ndx, "");
                EXPECT_EQ(objects()[ndx], tmp->raw_ptr(), "");
            }
            erased_ndx = tmp->value();

            // Make sure that the intrusive bookkeeping is up-to-date.
            auto& ns = ContainerType::NodeTraits::node_state(*tmp);
            EXPECT_TRUE(ns.IsValid(), "");
            EXPECT_FALSE(ns.InContainer(), "");

            // The container has shrunk, but the object should still be around.
            EXPECT_EQ(remaining, ObjType::live_obj_count(), "");
            EXPECT_EQ(remaining - 1, Size(container()), "");
        }

        // If we were not holding onto the object using the test
        // environment's tracking, the live object count should have
        // dropped.  Otherwise, it should remain the same.
        if (!HoldingObject(erased_ndx))
            EXPECT_EQ(remaining - 1, ObjType::live_obj_count(), "");
        else
            EXPECT_EQ(remaining, ObjType::live_obj_count(), "");

        // Let go of the object and verify that it has now gone away.
        ReleaseObject(erased_ndx);
        EXPECT_EQ(remaining - 1, ObjType::live_obj_count(), "");

        END_TEST;
    }

    bool IterErase() {
        BEGIN_TEST;

        // Don't perform index sanity checks for the objects we erase unless
        // this is a sequence container type.
        bool check_ndx = ContainerType::IsSequenced;
        size_t erased = 0;

        // Remove all of the elements from the container by erasing from the front.
        ASSERT_TRUE(Populate(container()), "");
        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(erased));
            EXPECT_TRUE(DoErase(container().begin(), i, OBJ_COUNT - i, check_ndx), "");
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(++erased));
        }

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");

        // Remove all but 2 of the elements from the container by erasing from the middle.
        static_assert(2 < OBJ_COUNT, "OBJ_COUNT too small to run Erase test!");
        ASSERT_TRUE(Populate(container()), "");
        auto iter = container().begin();
        iter++;
        for (size_t i = 1; i < OBJ_COUNT - 1; ++i) {
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(erased));
            EXPECT_TRUE(DoErase(iter++, i, OBJ_COUNT - i + 1, check_ndx), "");
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(++erased));
        }

        // Attempting to erase end() from a container with more than one element in
        // it should return nullptr.
        EXPECT_NULL(container().erase(container().end()), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(erased));
        EXPECT_TRUE(DoErase(container().begin(), 0, 2, check_ndx), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(++erased));

        // Attempting to erase end() from a container with just one element in
        // it should return nullptr.
        EXPECT_NULL(container().erase(container().end()), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(erased));
        EXPECT_TRUE(DoErase(container().begin(), OBJ_COUNT - 1, 1, check_ndx), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(++erased));

        // Attempting to erase end() from an empty container should return nullptr.
        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_NULL(container().erase(container().end()), "");
        EXPECT_EQ(erased, OBJ_COUNT * 2);
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT * 2));

        END_TEST;
    }

    bool ReverseIterErase() {
        BEGIN_TEST;

        // Don't perform index sanity checks for the objects we erase unless
        // this is a sequence container type.
        bool check_ndx = ContainerType::IsSequenced;

        // Remove all of the elements from the container by erasing from the back.
        ASSERT_TRUE(Populate(container()), "");
        auto iter = container().end();
        iter--;
        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_TRUE(DoErase(iter--, OBJ_COUNT - i - 1, OBJ_COUNT - i, check_ndx), "");
        }

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");

        END_TEST;
    }

    bool DirectErase() {
        BEGIN_TEST;

        // Remove all of the elements from the container by erasing using direct
        // node pointers which should end up always being at the front of the
        // container.
        ASSERT_TRUE(Populate(container(), RefAction::HoldAll), "");
        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            ASSERT_NONNULL(objects()[i], "");
            EXPECT_TRUE(DoErase(*objects()[i], i, OBJ_COUNT - i), "");
        }

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");

        // Remove all of the elements from the container by erasing using direct
        // node pointers which should end up always being at the back of the
        // container.
        ASSERT_TRUE(Populate(container(), RefAction::HoldAll), "");
        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            size_t ndx = OBJ_COUNT - i - 1;
            ASSERT_NONNULL(objects()[ndx], "");
            EXPECT_TRUE(DoErase(*objects()[ndx], ndx, ndx + 1), "");
        }

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");

        // Remove all of the elements from the container by erasing using direct
        // node pointers which should end up always being somewhere in the
        // middle of the container.
        static_assert(2 < OBJ_COUNT, "OBJ_COUNT too small to run Erase test!");
        ASSERT_TRUE(Populate(container(), RefAction::HoldAll), "");
        for (size_t i = 1; i < OBJ_COUNT - 1; ++i) {
            ASSERT_NONNULL(objects()[i], "");
            EXPECT_TRUE(DoErase(*objects()[i], i, OBJ_COUNT - i + 1), "");
        }

        END_TEST;
    }

    template <typename IterType>
    bool DoIterate(const IterType& begin, const IterType& end) {
        BEGIN_TEST;
        IterType iter;

        // Iterate using begin/end
        size_t i = 0;
        for (iter = begin; iter != end; ) {
            // Exercise both -> and * dereferencing
            ASSERT_TRUE(iter.IsValid(), "");

            EXPECT_EQ(0u, iter->visited_count(), "");
            iter->Visit();
            EXPECT_EQ(1u, (*iter).visited_count(), "");
            (*iter).Visit();
            EXPECT_EQ(2u, (*iter).visited_count(), "");

            // Exercise both pre and postfix increment
            if ((i++) & 1) iter++;
            else           ++iter;
        }
        EXPECT_FALSE(iter.IsValid(), "");

        for (i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_EQ(2u, objects()[i]->visited_count(), "");
            objects()[i]->ResetVisitedCount();
        }

        // Advancing iter past the end of the container should be a no-op.  Check
        // both pre and post-fix.
        iter = end;
        ++iter;
        EXPECT_FALSE(iter.IsValid(), "");
        EXPECT_TRUE(iter == end, "");

        // We know that the iterator  is already at the end of the container, but
        // perform the explicit assignment in order to check that the assignment
        // operator is working (the previous version actually exercises the copy
        // constructor or the explicit rvalue constructor, if supplied)
        iter = end;
        iter++;
        EXPECT_FALSE(iter.IsValid(), "");
        EXPECT_TRUE(iter == end, "");

        END_TEST;
    }

    bool Iterate() {
        BEGIN_TEST;

        // Both begin and cbegin should both be invalid, and to end/cend
        ASSERT_EQ(0u, Size(container()), "");
        EXPECT_FALSE(container().begin().IsValid(), "");
        EXPECT_TRUE (container().begin() == container().end(), "");

        EXPECT_FALSE(container().cbegin().IsValid(), "");
        EXPECT_TRUE (container().cbegin() == container().cend(), "");

        // Attempting to increment begin() for an empty container should result
        // in an invalid iterator which is still equal to end().  Check both
        // prefix and postfix decrement operators.
        auto iter = container().begin();
        ++iter;
        EXPECT_TRUE(container().end() == iter, "");
        EXPECT_FALSE(iter.IsValid(), "");

        iter = container().begin();
        iter++;
        EXPECT_TRUE(container().end() == iter, "");
        EXPECT_FALSE(iter.IsValid(), "");

        // Check const_iterator as well.
        auto const_iter = container().cbegin();
        ++const_iter;
        EXPECT_TRUE(container().cend() == const_iter, "");
        EXPECT_FALSE(const_iter.IsValid(), "");

        const_iter = container().cbegin();
        const_iter++;
        EXPECT_TRUE(container().cend() == const_iter, "");
        EXPECT_FALSE(const_iter.IsValid(), "");

        // Make some objects.
        ASSERT_TRUE(Populate(container()), "");
        EXPECT_EQ(OBJ_COUNT, Size(container()), "");

        // Both begin and cbegin should both be valid, and not equal to end/cend
        EXPECT_TRUE(container().begin().IsValid(), "");
        EXPECT_TRUE(container().begin() != container().end(), "");

        EXPECT_TRUE(container().cbegin().IsValid(), "");
        EXPECT_TRUE(container().cbegin() != container().cend(), "");

        EXPECT_TRUE(DoIterate(container().begin(),  container().end()), "");  // Test iterator
        EXPECT_TRUE(DoIterate(container().cbegin(), container().cend()), ""); // Test const_iterator

        // Iterate using the range-based for loop syntax
        for (auto& obj : container()) {
            EXPECT_EQ(0u, obj.visited_count(), "");
            obj.Visit();
            EXPECT_EQ(1u, obj.visited_count(), "");
        }

        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_EQ(1u, objects()[i]->visited_count(), "");
            objects()[i]->ResetVisitedCount();
        }

        // Iterate using the range-based for loop syntax over const references.
        for (const auto& obj : container()) {
            EXPECT_EQ(0u, obj.visited_count(), "");
            obj.Visit();
            EXPECT_EQ(1u, obj.visited_count(), "");
        }

        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            EXPECT_EQ(1u, objects()[i]->visited_count(), "");
            objects()[i]->ResetVisitedCount();
        }

        // None of the objects should have been destroyed during this test.
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));

        END_TEST;
    }

    template <typename IterType>
    bool DoReverseIterate(const IterType& begin, const IterType& end) {
        BEGIN_TEST;
        IterType iter;

        // Backing up one from end() should give a valid iterator (either prefix
        // or postfix).
        iter = end;
        EXPECT_FALSE(iter.IsValid(), "");
        iter--;
        EXPECT_TRUE(iter.IsValid(), "");

        iter = end;
        EXPECT_FALSE(iter.IsValid(), "");
        --iter;
        EXPECT_TRUE(iter.IsValid(), "");

        // Make sure that backing up an iterator by one points always points
        // to the previous object in the container.
        iter = begin;
        size_t prev_ndx = iter->value();
        while (++iter != end) {
            ASSERT_LT(prev_ndx, OBJ_COUNT, "");
            ASSERT_NONNULL(objects()[prev_ndx], "");

            auto prev_iter = iter;
            --prev_iter;
            ASSERT_TRUE(prev_iter.IsValid(), "");
            EXPECT_FALSE(prev_iter == iter, "");
            EXPECT_TRUE(*prev_iter == *objects()[prev_ndx], "");

            prev_iter = iter;
            prev_iter--;
            ASSERT_TRUE(prev_iter.IsValid(), "");
            EXPECT_FALSE(prev_iter == iter, "");
            EXPECT_TRUE(*prev_iter == *objects()[prev_ndx], "");

            prev_ndx = iter->value();
        }

        // Attempting to back up past the beginning should result in an
        // invalid iterator.
        iter = begin;
        ASSERT_TRUE(iter.IsValid(), "");
        --iter;
        EXPECT_FALSE(iter.IsValid(), "");

        iter = begin;
        ASSERT_TRUE(iter.IsValid(), "");
        iter--;
        EXPECT_FALSE(iter.IsValid(), "");

        END_TEST;
    }

    bool ReverseIterate() {
        BEGIN_TEST;

        // Make sure that backing up from end() for an empty container stays at
        // end.  Check both prefix and postfix decrement operators.
        ASSERT_EQ(0u, Size(container()), "");
        auto iter = container().end();
        --iter;
        EXPECT_TRUE(container().end() == iter, "");
        EXPECT_FALSE(iter.IsValid(), "");

        iter = container().end();
        iter--;
        EXPECT_TRUE(container().end() == iter, "");
        EXPECT_FALSE(iter.IsValid(), "");

        // Check const_iterator as well.
        auto const_iter = container().cend();
        --const_iter;
        EXPECT_TRUE(container().cend() == const_iter, "");
        EXPECT_FALSE(const_iter.IsValid(), "");

        const_iter = container().cend();
        const_iter--;
        EXPECT_TRUE(container().cend() == const_iter, "");
        EXPECT_FALSE(const_iter.IsValid(), "");

        // Making some objects.
        ASSERT_TRUE(Populate(container()), "");
        EXPECT_EQ(OBJ_COUNT, Size(container()), "");

        // Test iterator
        EXPECT_TRUE(DoReverseIterate(container().begin(),  container().end()), "");

        // Test const_iterator
        EXPECT_TRUE(DoReverseIterate(container().cbegin(), container().cend()), "");

        // None of the objects should have been destroyed during this test.
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));

        END_TEST;
    }

    bool MakeIterator() {
        BEGIN_TEST;

        // Populate the container.  Hold internal refs to everything we add to
        // the container.
        ASSERT_TRUE(Populate(container(), RefAction::HoldAll), "");

        // For every member of the container, make an iterator using the
        // internal reference we are holding.  Verify that the iterator is in
        // the position we expect it to be in.
        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            ASSERT_NONNULL(objects()[i], "");
            auto iter = container().make_iterator(*objects()[i]);

            ASSERT_TRUE(iter != container().end(), "");
            EXPECT_EQ(objects()[i]->value(), iter->value(), "");
            EXPECT_EQ(objects()[i], iter->raw_ptr(), "");

            if (ContainerType::IsSequenced) {
                auto other_iter = container().begin();

                for (size_t j = 0; j < i; ++j) {
                    EXPECT_FALSE(other_iter == iter, "");
                    ++other_iter;
                }

                EXPECT_TRUE(other_iter == iter, "");
            }
        }

        END_TEST;
    }

    bool Swap() {
        BEGIN_TEST;

        {
            ContainerType other_container; // Make an empty container.
            ASSERT_TRUE(Populate(container()), ""); // Fill the internal container with stuff.

            // Sanity check, swap, then check again.
            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
            EXPECT_FALSE(container().is_empty(), "");
            EXPECT_EQ(OBJ_COUNT, Size(container()), "");
            EXPECT_TRUE(other_container.is_empty(), "");

            for (auto& obj : container()) {
                ASSERT_EQ(0u, obj.visited_count(), "");
                obj.Visit();
            }

            EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
            EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

            container().swap(other_container);

            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
            EXPECT_FALSE(other_container.is_empty(), "");
            EXPECT_EQ(OBJ_COUNT, Size(other_container), "");
            EXPECT_TRUE(container().is_empty(), "");

            for (auto& obj : other_container) {
                EXPECT_EQ(1u, obj.visited_count(), "");
                obj.Visit();
            }

            EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
            EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

            // Swap back to check the case where container() was empty, but other_container
            // had elements.
            container().swap(other_container);

            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
            EXPECT_FALSE(container().is_empty(), "");
            EXPECT_EQ(OBJ_COUNT, Size(container()), "");
            EXPECT_TRUE(other_container.is_empty(), "");

            for (const auto& obj : container())
                EXPECT_EQ(2u, obj.visited_count(), "");

            EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
            EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

            // Nothing should have been deleted yet.
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));

            // Reset;
            EXPECT_TRUE(Reset(), "");

            // Now all of the objects should be gone.
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
        }

        // Make a new other_container, this time with some stuff in it.
        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        {
            ContainerType other_container; // Make an empty container.
            ASSERT_TRUE(Populate(container()), ""); // Fill the internal container with stuff.

            static constexpr size_t OTHER_COUNT = 5;
            static constexpr size_t OTHER_START = 10000;
            ObjType* raw_ptrs[OTHER_COUNT];

            for (size_t i = 0; i < OTHER_COUNT; ++i) {
                PtrType ptr = TestEnvTraits::CreateObject(OTHER_START + OTHER_COUNT - i - 1);
                raw_ptrs[i] = PtrTraits::GetRaw(ptr);
                ContainerUtils<ContainerType>::MoveInto(other_container, std::move(ptr));
            }

            // Sanity check
            EXPECT_EQ(OBJ_COUNT + OTHER_COUNT, ObjType::live_obj_count(), "");
            EXPECT_EQ(OBJ_COUNT, Size(container()), "");
            EXPECT_EQ(OTHER_COUNT, Size(other_container), "");

            EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
            EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

            // Visit everything in container() once, and everything in
            // other_container twice.
            for (auto& obj : container()) {
                ASSERT_EQ(0u, obj.visited_count(), "");
                obj.Visit();
            }

            for (const auto& obj : other_container) {
                ASSERT_EQ(0u, obj.visited_count(), "");
                obj.Visit();
                obj.Visit();
            }

            for (auto& obj : container())     EXPECT_EQ(1u, obj.visited_count(), "");
            for (auto& obj : other_container) EXPECT_EQ(2u, obj.visited_count(), "");

            // Swap and sanity check again
            container().swap(other_container);

            EXPECT_EQ(OBJ_COUNT + OTHER_COUNT, ObjType::live_obj_count(), "");
            EXPECT_EQ(OBJ_COUNT, Size(other_container), "");
            EXPECT_EQ(OTHER_COUNT, Size(container()), "");

            EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
            EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

            // Everything in container() should have been visited twice so far,
            // while everything in other_container should have been visited
            // once.
            for (auto& obj : container())     EXPECT_EQ(2u, obj.visited_count(), "");
            for (auto& obj : other_container) EXPECT_EQ(1u, obj.visited_count(), "");

            // Swap back and sanity check again
            container().swap(other_container);

            EXPECT_EQ(OBJ_COUNT + OTHER_COUNT, ObjType::live_obj_count(), "");
            EXPECT_EQ(OBJ_COUNT, Size(container()), "");
            EXPECT_EQ(OTHER_COUNT, Size(other_container), "");

            EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
            EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

            for (auto& obj : container())     EXPECT_EQ(1u, obj.visited_count(), "");
            for (auto& obj : other_container) EXPECT_EQ(2u, obj.visited_count(), "");

            // No new objects should have been deleted.
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));

            // If we are testing unmanaged pointers clean them up.
            EXPECT_EQ(OBJ_COUNT + OTHER_COUNT, ObjType::live_obj_count(), "");
            other_container.clear();
            if (!PtrTraits::IsManaged) {
                EXPECT_EQ(OBJ_COUNT + OTHER_COUNT, ObjType::live_obj_count(), "");
                for (size_t i = 0; i < OTHER_COUNT; ++i)
                    delete raw_ptrs[i];
            }
            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");

            // Now, we should have deleted an additional OTHER_COUNT objects
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT + OTHER_COUNT));

            // Reset the internal state
            EXPECT_TRUE(Reset(), "");
            EXPECT_EQ(0u, ObjType::live_obj_count(), "");

            // Now we should have filled and emptied the test environment twice, and
            // created+destroyed an additional OTHER_COUNT objects..
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations((2 * OBJ_COUNT) + OTHER_COUNT));
        }

        END_TEST;
    }

    bool RvalueOps() {
        BEGIN_TEST;

        // Populate the internal container.
        ASSERT_TRUE(Populate(container()), "");
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, Size(container()), "");
        for (auto& obj : container()) {
            ASSERT_GT(OBJ_COUNT, obj.value(), "");
            EXPECT_EQ(0u, obj.visited_count(), "");
            EXPECT_EQ(objects()[obj.value()], &obj, "");
            obj.Visit();
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");

        // Move its contents to a new container by explicitly invoking the Rvalue
        // constructor.
#if TEST_WILL_NOT_COMPILE || 0
        ContainerType other_container(container());
#else
        ContainerType other_container(std::move(container()));
#endif
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, Size(other_container), "");
        EXPECT_TRUE(container().is_empty(), "");
        for (const auto& obj : other_container) {
            ASSERT_GT(OBJ_COUNT, obj.value(), "");
            EXPECT_EQ(1u, obj.visited_count(), "");
            EXPECT_EQ(objects()[obj.value()], &obj, "");
            obj.Visit();
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

        // Move the contents again, this time using move-initialization which implicitly
        // invokes the Rvalue constructor.
#if TEST_WILL_NOT_COMPILE || 0
        ContainerType another_container = other_container;
#else
        ContainerType another_container = std::move(other_container);
#endif
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, Size(another_container), "");
        EXPECT_TRUE(other_container.is_empty(), "");
        for (const auto& obj : another_container) {
            ASSERT_GT(OBJ_COUNT, obj.value(), "");
            EXPECT_EQ(2u, obj.visited_count(), "");
            EXPECT_EQ(objects()[obj.value()], &obj, "");
            obj.Visit();
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(another_container), "");

        // Move the contents of the final container back to the internal container.  If we
        // are testing managed pointer types, put some objects into the internal
        // container first and make sure they get released.  Don't try this with
        // unmanaged pointers as it will trigger an assert if you attempt to
        // blow away a non-empty container via Rvalue assignment.
        static constexpr size_t EXTRA_COUNT = 5;
        size_t extras_added = 0;
        if (PtrTraits::IsManaged) {
            while (extras_added < EXTRA_COUNT) {
                ContainerUtils<ContainerType>::MoveInto(
                        container(),
                        std::move(TestEnvTraits::CreateObject(extras_added++)));
            }
        }

        // Sanity checks before the assignment
        EXPECT_EQ(OBJ_COUNT + extras_added, ObjType::live_obj_count(), "");
        EXPECT_EQ(extras_added, Size(container()), "");
        for (const auto& obj : container()) {
            ASSERT_GT(EXTRA_COUNT, obj.value(), "");
            EXPECT_EQ(0u, obj.visited_count(), "");
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(another_container), "");

        // No objects should have been deleted yet.
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
#if TEST_WILL_NOT_COMPILE || 0
        container() = another_container;
#else
        container() = std::move(another_container);
#endif
        // The extra objects we put into container() should have been released
        // when we moved the contents of another_container into container()
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(extras_added));

        // another_container should now be empty, and we should have returned to our
        // starting, post-populated state.
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, Size(container()), "");
        EXPECT_TRUE(another_container.is_empty(), "");
        for (const auto& obj : container()) {
            ASSERT_GT(OBJ_COUNT, obj.value(), "");
            EXPECT_EQ(3u, obj.visited_count(), "");
            EXPECT_EQ(objects()[obj.value()], &obj, "");
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(another_container), "");

        END_TEST;
    }

    bool Scope() {
        BEGIN_TEST;

        // Make sure that both unique_ptrs and RefPtrs handle being moved
        // properly, and that containers of such pointers automatically clean up
        // when the container goes out of scope and destructs.  Note: Don't try
        // this with an unmanaged pointer.  Lists of unmanaged pointers will
        // ZX_ASSERT if they destruct with elements still in them.
        EXPECT_EQ(0U, ObjType::live_obj_count(), "");

        {  // Begin scope for container
            ContainerType container;

            // Put some stuff into the container.  Don't hold any internal
            // references to anything we add.
            Populate(container, RefAction::HoldNone);
            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
            EXPECT_EQ(OBJ_COUNT, Size(container), "");
            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
        }  // Let the container go out of scope and clean itself up..

        EXPECT_EQ(0U, ObjType::live_obj_count(), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));

        END_TEST;
    }

    bool TwoContainer() {
        BEGIN_TEST;

        // Start by populating the internal container.  We should end up with
        // OBJ_COUNT objects, but we may not be holding internal references to
        // all of them.
        ASSERT_TRUE(Populate(container()), "");

        // Create the other type of container that ObjType can exist on and populate
        // it using the default operation for the container type.
        OtherContainerType other_container;
        for (auto iter = container().begin(); iter != container().end(); ++iter) {
            ContainerUtils<OtherContainerType>::MoveInto(other_container,
                                                         std::move(iter.CopyPointer()));
        }

        // The two containers should be the same length, and nothing should have
        // changed about the live object count.
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, Size(container()), "");
        EXPECT_EQ(OBJ_COUNT, Size(other_container), "");

        // Make sure that none of the members of container() or other_container
        // have been visited.  Then visit every member of other_container, and
        // make sure that all of the members of container() have been visited
        // once.
        for (auto& obj : container()) ASSERT_EQ(0u, obj.visited_count(), "");
        for (auto& obj : other_container) ASSERT_EQ(0u, obj.visited_count(), "");

        for (auto& obj : other_container) {
            obj.Visit();
            EXPECT_EQ(1u, obj.visited_count(), "");
        }

        for (auto& obj : container()) {
            EXPECT_EQ(1u, obj.visited_count(), "");
            obj.Visit();
            EXPECT_EQ(2u, obj.visited_count(), "");
        }

        // If this is a sequenced container, then other_container should be in
        // the reverse order of container()
        if (OtherContainerType::IsSequenced) {
            auto other_iter = other_container.begin();
            for (const auto& obj : container()) {
                ASSERT_FALSE(other_iter == other_container.end(), "");
                EXPECT_EQ(OBJ_COUNT - obj.value() - 1, other_iter->value(), "");
                ++other_iter;
            }
            EXPECT_TRUE(other_iter == other_container.end(), "");
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(other_container), "");

        // Clear the internal container.  No objects should go away and the other
        // container should be un-affected
        container().clear();

        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_EQ(OBJ_COUNT, Size(other_container), "");

        for (auto& obj : other_container)
            EXPECT_EQ(2u, obj.visited_count(), "");

        if (OtherContainerType::IsSequenced) {
            auto other_iter = other_container.begin();
            for (size_t i = 0; i < OBJ_COUNT; ++i) {
                ASSERT_FALSE(other_iter == other_container.end(), "");
                EXPECT_EQ(OBJ_COUNT - i - 1, other_iter->value(), "");
                ++other_iter;
            }
            EXPECT_TRUE(other_iter == other_container.end(), "");
        }

        // If we are testing a container of managed pointers, release our internal
        // references.  Again, no objects should go away (as they are being
        // referenced by other_container.  Note: Don't try this with an unmanaged
        // pointer.  "releasing" and unmanaged pointer in the context of the
        // TestEnvironment class means to return it to the heap, which is a Very
        // Bad thing if we still have a container referring to the objects which were
        // returned to the heap.
        if (PtrTraits::IsManaged) {
            for (size_t i = 0; i < OBJ_COUNT; ++i)
                ReleaseObject(i);

            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
            EXPECT_EQ(0u, refs_held(), "");
            EXPECT_EQ(OBJ_COUNT, Size(other_container), "");
        }
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));

        // Finally, clear() other_container and reset the internal state.  At this
        // point, all objects should have gone away.
        other_container.clear();
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
        EXPECT_TRUE(Reset(), "");

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, refs_held(), "");
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_EQ(0u, Size(other_container), "");

        END_TEST;
    }

    bool ThreeContainerHelper() {
        BEGIN_TEST;
        // Start by populating the internal container.  We should end up with
        // OBJ_COUNT objects, but we may not be holding internal references to
        // all of them.
        ASSERT_TRUE(Populate(container()), "");

        // Create the other types of containers that ObjType can exist on and populate
        // them using the default operation for the container type.
        typename ContainerTraits::TaggedType1 tagged1;
        typename ContainerTraits::TaggedType2 tagged2;
        typename ContainerTraits::TaggedType3 tagged3;
        for (auto iter = container().begin(); iter != container().end(); ++iter) {
            ContainerUtils<typename ContainerTraits::TaggedType1>::MoveInto(tagged1,
                                                  iter.CopyPointer());
            ContainerUtils<typename ContainerTraits::TaggedType2>::MoveInto(tagged2,
                                                  iter.CopyPointer());
            ContainerUtils<typename ContainerTraits::TaggedType3>::MoveInto(tagged3,
                                                  iter.CopyPointer());
        }

        // The three containers should be the same length, and nothing should have
        // changed about the live object count.
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, Size(tagged1), "");
        EXPECT_EQ(OBJ_COUNT, Size(tagged2), "");
        EXPECT_EQ(OBJ_COUNT, Size(tagged3), "");

        // Make sure that none of the members of container() or other_container
        // have been visited.  Then visit every member of the other containers,
        // and make sure that all of the members of container() have been
        // visited once.
        for (auto& obj : tagged1) ASSERT_EQ(0u, obj.visited_count(), "");
        for (auto& obj : tagged2) ASSERT_EQ(0u, obj.visited_count(), "");
        for (auto& obj : tagged3) ASSERT_EQ(0u, obj.visited_count(), "");

        for (auto& obj : tagged1) {
            obj.Visit();
            EXPECT_EQ(1u, obj.visited_count(), "");
        }

        for (auto& obj : tagged2) {
            obj.Visit();
            EXPECT_EQ(2u, obj.visited_count(), "");
        }

        for (auto& obj : tagged3) {
            obj.Visit();
            EXPECT_EQ(3u, obj.visited_count(), "");
        }

        // If this is a sequenced container, then the other containers should be in
        // the reverse order of container()
        if constexpr (ContainerTraits::TaggedType1::IsSequenced &&
                      ContainerTraits::TaggedType2::IsSequenced &&
                      ContainerTraits::TaggedType3::IsSequenced) {
            auto iter1 = tagged1.begin();
            for (const auto& obj : container()) {
                ASSERT_FALSE(iter1 == tagged1.end(), "");
                EXPECT_EQ(OBJ_COUNT - obj.value() - 1, iter1->value(), "");
                ++iter1;
            }
            EXPECT_TRUE(iter1 == tagged1.end(), "");

            auto iter2 = tagged2.begin();
            for (const auto& obj : container()) {
                ASSERT_FALSE(iter2 == tagged2.end(), "");
                EXPECT_EQ(OBJ_COUNT - obj.value() - 1, iter2->value(), "");
                ++iter2;
            }
            EXPECT_TRUE(iter2 == tagged2.end(), "");

            auto iter3 = tagged3.begin();
            for (const auto& obj : container()) {
                ASSERT_FALSE(iter3 == tagged3.end(), "");
                EXPECT_EQ(OBJ_COUNT - obj.value() - 1, iter3->value(), "");
                ++iter3;
            }
            EXPECT_TRUE(iter3 == tagged3.end(), "");
        }

        EXPECT_TRUE(ContainerChecker::SanityCheck(tagged1), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(tagged2), "");
        EXPECT_TRUE(ContainerChecker::SanityCheck(tagged3), "");

        // Clear the internal container.  No objects should go away and the other
        // containers should be un-affected
        container().clear();

        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_EQ(OBJ_COUNT, Size(tagged1), "");
        EXPECT_EQ(OBJ_COUNT, Size(tagged2), "");
        EXPECT_EQ(OBJ_COUNT, Size(tagged3), "");

        for (auto& obj : tagged1) {
            EXPECT_EQ(3u, obj.visited_count(), "");
        }
        for (auto& obj : tagged2) {
            EXPECT_EQ(3u, obj.visited_count(), "");
        }
        for (auto& obj : tagged3) {
            EXPECT_EQ(3u, obj.visited_count(), "");
        }

        if constexpr (ContainerTraits::TaggedType1::IsSequenced &&
                      ContainerTraits::TaggedType2::IsSequenced &&
                      ContainerTraits::TaggedType3::IsSequenced) {
            auto iter1 = tagged1.begin();
            for (size_t i = 0; i < OBJ_COUNT; ++i) {
                ASSERT_FALSE(iter1 == tagged1.end(), "");
                EXPECT_EQ(OBJ_COUNT - i - 1, iter1->value(), "");
                ++iter1;
            }
            EXPECT_TRUE(iter1 == tagged1.end(), "");

            auto iter2 = tagged2.begin();
            for (size_t i = 0; i < OBJ_COUNT; ++i) {
                ASSERT_FALSE(iter2 == tagged2.end(), "");
                EXPECT_EQ(OBJ_COUNT - i - 1, iter2->value(), "");
                ++iter2;
            }
            EXPECT_TRUE(iter2 == tagged2.end(), "");

            auto iter3 = tagged3.begin();
            for (size_t i = 0; i < OBJ_COUNT; ++i) {
                ASSERT_FALSE(iter3 == tagged3.end(), "");
                EXPECT_EQ(OBJ_COUNT - i - 1, iter3->value(), "");
                ++iter3;
            }
            EXPECT_TRUE(iter3 == tagged3.end(), "");
        }

        // If we are testing a container of managed pointers, release our internal
        // references.  Again, no objects should go away (as they are being
        // referenced by other_container.  Note: Don't try this with an unmanaged
        // pointer.  "releasing" an unmanaged pointer in the context of the
        // TestEnvironment class means to return it to the heap, which is a Very
        // Bad thing if we still have a container referring to the objects which were
        // returned to the heap.
        if (PtrTraits::IsManaged) {
            for (size_t i = 0; i < OBJ_COUNT; ++i)
                ReleaseObject(i);

            EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
            EXPECT_EQ(0u, refs_held(), "");
            EXPECT_EQ(OBJ_COUNT, Size(tagged1), "");
            EXPECT_EQ(OBJ_COUNT, Size(tagged2), "");
            EXPECT_EQ(OBJ_COUNT, Size(tagged3), "");
        }
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));

        // Finally, clear() the other other_containers and reset the internal state. At this
        // point, all objects should have gone away.
        tagged1.clear();
        tagged2.clear();
        tagged3.clear();
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
        EXPECT_TRUE(Reset(), "");

        EXPECT_EQ(0u, ObjType::live_obj_count(), "");
        EXPECT_EQ(0u, refs_held(), "");
        EXPECT_EQ(0u, Size(container()), "");
        EXPECT_EQ(0u, Size(tagged1), "");
        EXPECT_EQ(0u, Size(tagged2), "");
        EXPECT_EQ(0u, Size(tagged3), "");

        END_TEST;
    }

    bool IterCopyPointer() {
        BEGIN_TEST;
        PtrType ptr;
        typename ContainerType::iterator iter;

        // A default constructed iterator should give back nullptr when
        // CopyPointer is called.
        ptr = iter.CopyPointer();
        EXPECT_NULL(ptr, "");

        // The begining/end of an emptry container should also return nullptr.
        ptr = container().begin().CopyPointer();
        EXPECT_NULL(ptr, "");

        ptr = container().end().CopyPointer();
        EXPECT_NULL(ptr, "");

        // Populate the container.
        ASSERT_TRUE(Populate(container(), RefAction::HoldAll), "");
        EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
        EXPECT_EQ(OBJ_COUNT, refs_held(), "");

        // end().CopyPointer should still return nullptr.
        ptr = container().end().CopyPointer();
        EXPECT_NULL(ptr, "");

        // begin().CopyPointer() should be non-null.
        ptr = container().begin().CopyPointer();
        EXPECT_NONNULL(ptr, "");

        // clear the container and release all internally held references.
        container().clear();
        for (size_t i = 0; i < OBJ_COUNT; ++i)
            ReleaseObject(i);

        // We should not be holding any references, but we should still have a
        // live object if we are testing a managed pointer type.
        EXPECT_EQ(0u, refs_held(), "");
        if (PtrTraits::IsManaged)
            EXPECT_EQ(1u, ObjType::live_obj_count(), "");
        else
            EXPECT_EQ(0u, ObjType::live_obj_count(), "");

        // null out our pointer.  No matter what, our live_obj_count should now
        // be zero.
        ptr = nullptr;
        EXPECT_EQ(0u, ObjType::live_obj_count(), "");

        END_TEST;
    }

    bool EraseIf() {
        BEGIN_TEST;

        // Populate our container.
        ASSERT_TRUE(Populate(container()), "");

        // Erase all of the even members
        size_t even_erased = 0;
        while (even_erased < OBJ_COUNT) {
            if (nullptr == container().erase_if([](const ObjType& obj) -> bool {
                    return !(obj.value() & 1);
                }))
                break;
            even_erased++;
        }

        EXPECT_EQ(EVEN_OBJ_COUNT, even_erased, "");
        EXPECT_EQ(OBJ_COUNT, even_erased + Size(container()), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(even_erased));
        for (const auto& obj : container())
            EXPECT_TRUE(obj.value() & 1, "");

        // Erase all of the odd members
        size_t odd_erased = 0;
        while (even_erased < OBJ_COUNT) {
            if (nullptr == container().erase_if([](const ObjType& obj) -> bool {
                    return obj.value() & 1;
                }))
                break;
            odd_erased++;
        }

        EXPECT_EQ(ODD_OBJ_COUNT, odd_erased, "");
        EXPECT_EQ(OBJ_COUNT, even_erased + odd_erased, "");
        EXPECT_TRUE(container().is_empty(), "");
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));

        END_TEST;
    }

    bool FindIf() {
        BEGIN_TEST;

        // Populate our container.
        ASSERT_TRUE(Populate(container()), "");

        // Find all of the members which should be in the container.
        for (size_t i = 0; i < OBJ_COUNT; ++i) {
            auto iter = const_container().find_if(
                [i](const ObjType& obj) -> bool {
                    return (obj.value() == i);
                });

            ASSERT_TRUE(iter.IsValid(), "");
            EXPECT_EQ(0u, iter->visited_count(), "");
            iter->Visit();
        }

        // Every member should have been visited once.
        for (auto& obj : container()) {
            EXPECT_EQ(1u, obj.visited_count(), "");
            obj.ResetVisitedCount();
        }

        // Count all of the odd members.
        size_t total_found = 0;
        while (true) {
            auto iter = const_container().find_if(
                [](const ObjType& obj) -> bool {
                    return (obj.value() & 1) && !obj.visited_count();
                });

            if (!iter.IsValid())
                break;

            ++total_found;
            iter->Visit();
        }
        EXPECT_EQ(ODD_OBJ_COUNT, total_found, "");

        // All of the odd members should have been visited once, while all of
        // the even members should not have been visited.
        for (const auto& obj : container())
            EXPECT_EQ(obj.value() & 1, obj.visited_count(), "");

        // Fail to find a member which should not be in the container.
        auto iter = const_container().find_if(
            [](const ObjType& obj) -> bool {
                return (obj.value() == OBJ_COUNT);
            });
        EXPECT_FALSE(iter.IsValid(), "");

        // We should not have destroyed any objects in this test.
        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));

        END_TEST;
    }

    static PtrType TakePtr(PtrType& ptr) {
        if constexpr (PtrTraits::IsManaged) {
            return std::move(ptr);
        } else {
            PtrType tmp = ptr;
            ptr = nullptr;
            return tmp;
        }
    }

private:
    // Accessors for base class members so we don't have to type
    // this->base_member all of the time.
    using Sp   = TestEnvironmentSpecialized<TestEnvTraits>;
    using Base = TestEnvironmentBase<TestEnvTraits>;
    static constexpr size_t OBJ_COUNT      = Base::OBJ_COUNT;
    static constexpr size_t EVEN_OBJ_COUNT = (OBJ_COUNT >> 1) + (OBJ_COUNT & 1);
    static constexpr size_t ODD_OBJ_COUNT  = (OBJ_COUNT >> 1);

    ContainerType&       container()       { return this->container_; }
    const ContainerType& const_container() { return this->container_; }
    ObjType**            objects()         { return this->objects_; }
    size_t&              refs_held()       { return this->refs_held_; }

    void ReleaseObject(size_t ndx) { Sp::ReleaseObject(ndx); }
    bool HoldingObject(size_t ndx) const { return Sp::HoldingObject(ndx); }
};

}  // namespace intrusive_containers
}  // namespace tests
}  // namespace fbl
