[fbl][containers] Add support for std::unique_ptr

std::unique_ptr is coming to Zircon!  Add support to the fbl intrusive
containers for the std:: version of unique pointer.  Make sure to support
pointers which use custom deleters.

Also, extend the test framework to test both the custom deleter and non-custom
deleter forms of std::unique_ptr.  Finally, add some checks in the test
framework to make sure the custom deleter is being called the number of times we
would expect given the behavior of each test.

Test: Build and newly extended unit tests.
Change-Id: I60e3abb8315391fd85949eca9ca5daf9fb58fd6f
diff --git a/system/ulib/fbl/include/fbl/intrusive_pointer_traits.h b/system/ulib/fbl/include/fbl/intrusive_pointer_traits.h
index cf3d1d8..267c5b1 100644
--- a/system/ulib/fbl/include/fbl/intrusive_pointer_traits.h
+++ b/system/ulib/fbl/include/fbl/intrusive_pointer_traits.h
@@ -4,11 +4,12 @@
 
 #pragma once
 
-#include <stdint.h>
-#include <zircon/compiler.h>
 #include <fbl/ref_ptr.h>
 #include <fbl/unique_ptr.h>
 #include <fbl/type_support.h>
+#include <memory>
+#include <stdint.h>
+#include <zircon/compiler.h>
 
 namespace fbl {
 namespace internal {
@@ -68,6 +69,31 @@
     }
 };
 
+// Traits for managing std::unique_ptrs to objects (arrays of objects are not supported)
+template <typename T, typename Deleter>
+struct ContainerPtrTraits<::std::unique_ptr<T, Deleter>> {
+    using ValueType       = T;
+    using RefType         = T&;
+    using ConstRefType    = const T&;
+    using PtrType         = ::std::unique_ptr<T, Deleter>;
+    using ConstPtrType    = ::std::unique_ptr<const T, Deleter>;
+    using RawPtrType      = T*;
+    using ConstRawPtrType = const T*;
+
+    static constexpr bool IsManaged = true;
+    static constexpr bool CanCopy = false;
+
+    static inline T* GetRaw(const PtrType& ptr) { return ptr.get(); }
+
+    static inline RawPtrType Leak(PtrType& ptr) __WARN_UNUSED_RESULT {
+        return ptr.release();
+    }
+
+    static inline PtrType Reclaim(RawPtrType ptr) {
+        return PtrType(ptr);
+    }
+};
+
 // Traits for managing ref_counted pointers.
 template <typename T>
 struct ContainerPtrTraits<::fbl::RefPtr<T>> {
diff --git a/system/utest/fbl/include/fbl/tests/intrusive_containers/associative_container_test_environment.h b/system/utest/fbl/include/fbl/tests/intrusive_containers/associative_container_test_environment.h
index f8e2953..36b8a6b 100644
--- a/system/utest/fbl/include/fbl/tests/intrusive_containers/associative_container_test_environment.h
+++ b/system/utest/fbl/include/fbl/tests/intrusive_containers/associative_container_test_environment.h
@@ -172,8 +172,13 @@
         BEGIN_TEST;
 
         EXPECT_TRUE(DoInsertByKey(PopulateMethod::AscendingKey), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
+
         EXPECT_TRUE(DoInsertByKey(PopulateMethod::DescendingKey), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(2 * OBJ_COUNT));
+
         EXPECT_TRUE(DoInsertByKey(PopulateMethod::RandomKey), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(3 * OBJ_COUNT));
 
         END_TEST;
     }
@@ -207,17 +212,23 @@
         BEGIN_TEST;
 
         EXPECT_TRUE(DoFindByKey(PopulateMethod::AscendingKey), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
+
         EXPECT_TRUE(DoFindByKey(PopulateMethod::DescendingKey), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(2 * OBJ_COUNT));
+
         EXPECT_TRUE(DoFindByKey(PopulateMethod::RandomKey), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(3 * OBJ_COUNT));
 
         END_TEST;
     }
 
-    bool DoEraseByKey(PopulateMethod populate_method) {
+    bool DoEraseByKey(PopulateMethod populate_method, size_t already_erased) {
         BEGIN_TEST;
 
         EXPECT_TRUE(Populate(container(), populate_method), "");
         size_t remaining = OBJ_COUNT;
+        size_t erased = 0;
 
         // Fail to erase a key which is not in the container.
         EXPECT_NULL(container().erase(kBannedKeyValue), "");
@@ -231,7 +242,9 @@
             if (key & 1)
                 continue;
 
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(erased + already_erased));
             EXPECT_TRUE(TestEnvironment<TestEnvTraits>::DoErase(key, i, remaining), "");
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(++erased + already_erased));
             --remaining;
         }
 
@@ -245,7 +258,9 @@
             KeyType key = objects()[i]->GetKey();
             EXPECT_TRUE(key & 1, "");
 
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(erased + already_erased));
             EXPECT_TRUE(TestEnvironment<TestEnvTraits>::DoErase(key, i, remaining), "");
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(++erased + already_erased));
             --remaining;
         }
 
@@ -258,14 +273,14 @@
     bool EraseByKey() {
         BEGIN_TEST;
 
-        EXPECT_TRUE(DoEraseByKey(PopulateMethod::AscendingKey), "");
-        EXPECT_TRUE(DoEraseByKey(PopulateMethod::DescendingKey), "");
-        EXPECT_TRUE(DoEraseByKey(PopulateMethod::RandomKey), "");
+        EXPECT_TRUE(DoEraseByKey(PopulateMethod::AscendingKey, 0), "");
+        EXPECT_TRUE(DoEraseByKey(PopulateMethod::DescendingKey, OBJ_COUNT), "");
+        EXPECT_TRUE(DoEraseByKey(PopulateMethod::RandomKey, 2 * OBJ_COUNT), "");
 
         END_TEST;
     }
 
-    bool DoInsertOrFind(PopulateMethod populate_method) {
+    bool DoInsertOrFind(PopulateMethod populate_method, size_t already_destroyed) {
         BEGIN_TEST;
 
         for (unsigned int pass_iterator = 0u; pass_iterator < 2u; ++pass_iterator) {
@@ -317,6 +332,9 @@
                 ASSERT_TRUE(TestEnvironment<TestEnvTraits>::Reset(), "");
         }
 
+        // The objects from the first test pass should have been deleted.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(already_destroyed + OBJ_COUNT));
+
         // Now go over the (populated) container and attempt to insert new
         // objects which have the same keys as existing objects.  Each of these
         // attempts should fail, but should find the objects which were inserted
@@ -374,26 +392,33 @@
                 }
 
                 // Release the object we failed to insert.
+                EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(
+                            already_destroyed + OBJ_COUNT + (OBJ_COUNT * pass_iterator) + i));
                 TestEnvTraits::ReleaseObject(new_object);
+                EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(
+                            already_destroyed + OBJ_COUNT + (OBJ_COUNT * pass_iterator) + i + 1));
             }
         }
 
         ASSERT_TRUE(TestEnvironment<TestEnvTraits>::Reset(), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(
+                    already_destroyed + (4 *OBJ_COUNT)));
         END_TEST;
     }
 
     bool InsertOrFind() {
         BEGIN_TEST;
 
-        EXPECT_TRUE(DoInsertOrFind(PopulateMethod::AscendingKey), "");
-        EXPECT_TRUE(DoInsertOrFind(PopulateMethod::DescendingKey), "");
-        EXPECT_TRUE(DoInsertOrFind(PopulateMethod::RandomKey), "");
+        // Each time we run this test, we create and destroy 4 * OBJ_COUNT objects
+        EXPECT_TRUE(DoInsertOrFind(PopulateMethod::AscendingKey, 0), "");
+        EXPECT_TRUE(DoInsertOrFind(PopulateMethod::DescendingKey, 4 * OBJ_COUNT), "");
+        EXPECT_TRUE(DoInsertOrFind(PopulateMethod::RandomKey, 8 * OBJ_COUNT), "");
 
         END_TEST;
     }
 
     template <typename CopyOrMoveUtil>
-    bool DoInsertOrReplace() {
+    bool DoInsertOrReplace(size_t extra_elements, size_t already_destroyed) {
         BEGIN_TEST;
 
         ASSERT_EQ(0u, ObjType::live_obj_count(), "");
@@ -402,7 +427,7 @@
         // Attempt to replace every element in the container with one that has
         // the same key.  Then attempt to replace some which were not in the
         // container to start with and verify that they were inserted instead.
-        for (size_t i = 0; i < OBJ_COUNT + 10; ++i) {
+        for (size_t i = 0; i < OBJ_COUNT + extra_elements; ++i) {
             PtrType new_obj = TestEnvTraits::CreateObject(i);
             ASSERT_NONNULL(new_obj, "");
             new_obj->SetKey(i);
@@ -423,10 +448,18 @@
                 replaced = nullptr;
                 EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
                 EXPECT_EQ(OBJ_COUNT, container().size(), "");
+
+                // The replaced object should be gone now.
+                EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(already_destroyed + i + 1));
             } else {
                 EXPECT_EQ(i + 1, ObjType::live_obj_count());
                 EXPECT_EQ(i + 1, container().size(), "");
                 EXPECT_NULL(replaced, "");
+
+                // We should have succeeded in inserting this object, so the delete count should not
+                // have gone up.
+                EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(
+                            already_destroyed + OBJ_COUNT));
             }
         }
 
@@ -437,15 +470,23 @@
             TestEnvTraits::ReleaseObject(ptr);
         }
 
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(
+                    already_destroyed + (2 * OBJ_COUNT) + extra_elements));
+
         END_TEST;
     }
 
     bool InsertOrReplace() {
         BEGIN_TEST;
 
-        EXPECT_TRUE(DoInsertOrReplace<MoveUtil>(), "");
+        // Each time we run each version of the tests, we create and destroy 2 *
+        // OBJ_COUNT + the number of extra elements we specify;
+        constexpr size_t EXTRA_ELEMENTS = 10;
+        constexpr size_t TOTAL_OBJS = (2 * OBJ_COUNT) + EXTRA_ELEMENTS;
+
+        EXPECT_TRUE(DoInsertOrReplace<MoveUtil>(EXTRA_ELEMENTS, 0), "");
         if (CopyUtil<PtrTraits>::CanCopy) {
-            EXPECT_TRUE(DoInsertOrReplace<CopyUtil<PtrTraits>>(), "");
+            EXPECT_TRUE(DoInsertOrReplace<CopyUtil<PtrTraits>>(EXTRA_ELEMENTS, TOTAL_OBJS), "");
         }
 
         END_TEST;
diff --git a/system/utest/fbl/include/fbl/tests/intrusive_containers/base_test_environments.h b/system/utest/fbl/include/fbl/tests/intrusive_containers/base_test_environments.h
index 23763e4..1253499 100644
--- a/system/utest/fbl/include/fbl/tests/intrusive_containers/base_test_environments.h
+++ b/system/utest/fbl/include/fbl/tests/intrusive_containers/base_test_environments.h
@@ -110,6 +110,50 @@
 };
 
 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:
@@ -166,6 +210,7 @@
         HoldAll,
     };
 
+    TestEnvironment() { TestEnvTraits::ResetCustomDeleter(); }
     ~TestEnvironment() { Reset(); }
 
     // Utility methods used to check if the target of an Erase operation is
@@ -236,6 +281,7 @@
             }
         }
 
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
         END_TEST;
     }
 
@@ -281,6 +327,7 @@
         EXPECT_FALSE(container().is_empty(), "");
         EXPECT_TRUE(Reset(), "");
         EXPECT_TRUE(container().is_empty(), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
 
         END_TEST;
     }
@@ -338,11 +385,15 @@
         // 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)
+        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()), "");
@@ -352,23 +403,32 @@
         ASSERT_TRUE(Populate(container()), "");
         auto iter = container().begin();
         iter++;
-        for (size_t i = 1; i < OBJ_COUNT - 1; ++i)
+        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;
     }
@@ -555,6 +615,9 @@
             objects()[i]->ResetVisitedCount();
         }
 
+        // None of the objects should have been destroyed during this test.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -650,6 +713,9 @@
         // 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;
     }
 
@@ -737,8 +803,14 @@
             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.
@@ -810,6 +882,9 @@
             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();
@@ -820,9 +895,16 @@
             }
             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;
@@ -844,7 +926,7 @@
 
         EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
 
-        // Move its contents to a new container by explicity invoking the Rvalue
+        // Move its contents to a new container by explicitly invoking the Rvalue
         // constructor.
 #if TEST_WILL_NOT_COMPILE || 0
         ContainerType other_container(container());
@@ -893,10 +975,11 @@
         static constexpr size_t EXTRA_COUNT = 5;
         size_t extras_added = 0;
         if (PtrTraits::IsManaged) {
-            while (extras_added < EXTRA_COUNT)
+            while (extras_added < EXTRA_COUNT) {
                 ContainerUtils<ContainerType>::MoveInto(
                         container(),
                         std::move(TestEnvTraits::CreateObject(extras_added++)));
+            }
         }
 
         // Sanity checks before the assignment
@@ -911,11 +994,16 @@
         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.
@@ -953,9 +1041,11 @@
             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;
     }
@@ -1051,10 +1141,12 @@
             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(), "");
@@ -1134,6 +1226,7 @@
 
         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, "");
 
@@ -1150,6 +1243,7 @@
         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;
     }
@@ -1206,6 +1300,9 @@
             });
         EXPECT_FALSE(iter.IsValid(), "");
 
+        // We should not have destroyed any objects in this test.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
diff --git a/system/utest/fbl/include/fbl/tests/intrusive_containers/objects.h b/system/utest/fbl/include/fbl/tests/intrusive_containers/objects.h
index 02e158e..2af11d5 100644
--- a/system/utest/fbl/include/fbl/tests/intrusive_containers/objects.h
+++ b/system/utest/fbl/include/fbl/tests/intrusive_containers/objects.h
@@ -5,10 +5,13 @@
 #pragma once
 
 #include <fbl/alloc_checker.h>
+#include <fbl/atomic.h>
 #include <fbl/ref_counted.h>
 #include <fbl/ref_ptr.h>
 #include <fbl/unique_ptr.h>
+#include <unittest/unittest.h>
 
+#include <memory>
 #include <utility>
 
 namespace fbl {
@@ -59,6 +62,24 @@
     }
 };
 
+// A 'test' custom deleter for use when testing managed pointer type which have
+// support for template define custom deleters.
+template <typename T>
+struct TestCustomDeleter {
+public:
+    constexpr TestCustomDeleter() = default;
+    void operator()(T* ptr) const {
+        delete_count_.fetch_add(1u);
+        delete ptr;
+    }
+
+    static void reset_delete_count() { delete_count_.store(0); }
+    static size_t delete_count() { return delete_count_.load(); }
+
+private:
+    static fbl::atomic<size_t> delete_count_;
+};
+
 // Container test objects are objects which...
 //
 // 1) Store a size_t value
@@ -108,10 +129,41 @@
     explicit RefedTestObj(size_t val) : TestObj<ContainerTraits>(val) { }
 };
 
+// Basic pointer type definitions for the 5 types of currently support pointers
+//
+// Used by the macros which generate the various test environmements
+//
+// 1) Foo* (unmanaged/raw)
+// 2) fbl::unique_ptr<Foo>
+// 3) std::unique_ptr<Foo>
+// 4) std::unique_ptr<Foo, CustomDeleter>
+// 5) fbl::RefPtr<Foo>
+//
+namespace ptr_type {
+
+template <typename _ObjType>
+struct Unmanaged { using type = _ObjType*; };
+
+template <typename _ObjType>
+struct UniquePtr { using type = ::fbl::unique_ptr<_ObjType>; };
+
+template <typename _ObjType>
+struct StdUniquePtrDefaultDeleter { using type = ::std::unique_ptr<_ObjType>; };
+
+template <typename _ObjType>
+struct StdUniquePtrCustomDeleter {
+    using type = ::std::unique_ptr<_ObjType, TestCustomDeleter<_ObjType>>;
+};
+
+template <typename _ObjType>
+struct RefPtr { using type = ::fbl::RefPtr<_ObjType>; };
+
+}  // namespace ptr_type
+
 // Test trait structures contain utilities which define test behavior for the
-// three types of pointers which are managed by intrusive containers.
-// Specifically: unmanaged pointers, unique_ptr<>s and RefPtr<>s.  Defined
-// behaviors include...
+// five types of pointers which are managed by intrusive containers (see above).
+//
+// Defined behaviors include...
 //
 // 1) Allocating a valid version of a pointer to a TestObj of the proper type.
 // 2) "Transferring" a pointer (eg. copying if the pointer type supports copying,
@@ -120,10 +172,13 @@
 //    container.
 // 4) Testing to see if a pointer to an object was properly moved into a
 //    container.
+// 5) Checking to see if the number of times an associated custom deleter was
+//    invoked.
+// 5) Resetting any assoicated custom deleter state.
 template <typename _ObjType>
 struct UnmanagedTestTraits {
     using ObjType       = _ObjType;
-    using PtrType       = ObjType*;
+    using PtrType       = typename ptr_type::Unmanaged<ObjType>::type;
     using ConstPtrType  = const ObjType*;
     using ContainerType = typename ObjType::ContainerTraits::ContainerType;
 
@@ -138,6 +193,9 @@
         ptr = nullptr;
     }
 
+    static bool CheckCustomDeleteInvocations(size_t expected) { return true; }
+    static void ResetCustomDeleter() { }
+
     // Unmanaged pointers never get cleared when being moved or transferred.
     static inline PtrType& Transfer(PtrType& ptr)       { return ptr; }
     static bool WasTransferred(const ConstPtrType& ptr) { return ptr != nullptr; }
@@ -147,7 +205,7 @@
 template <typename _ObjType>
 struct UniquePtrTestTraits {
     using ObjType       = _ObjType;
-    using PtrType       = ::fbl::unique_ptr<ObjType>;
+    using PtrType       = typename ptr_type::UniquePtr<ObjType>::type;
     using ConstPtrType  = const PtrType;
     using ContainerType = typename ObjType::ContainerTraits::ContainerType;
 
@@ -161,6 +219,68 @@
         ptr = nullptr;
     }
 
+    static bool CheckCustomDeleteInvocations(size_t expected) { return true; }
+    static void ResetCustomDeleter() { }
+
+    // Unique pointers always get cleared when being moved or transferred.
+    static inline PtrType&& Transfer(PtrType& ptr)      { return std::move(ptr); }
+    static bool WasTransferred(const ConstPtrType& ptr) { return ptr == nullptr; }
+    static bool WasMoved (const ConstPtrType& ptr)      { return ptr == nullptr; }
+};
+
+template <typename _ObjType>
+struct StdUniquePtrDefaultDeleterTestTraits {
+    using ObjType       = _ObjType;
+    using PtrType       = typename ptr_type::StdUniquePtrDefaultDeleter<ObjType>::type;
+    using ConstPtrType  = const PtrType;
+    using ContainerType = typename ObjType::ContainerTraits::ContainerType;
+
+    static PtrType CreateObject(size_t value) {
+        AllocChecker ac;
+        auto r = new (&ac) ObjType(value);
+        return PtrType(ac.check() ? r : nullptr);
+    }
+
+    static void ReleaseObject(PtrType& ptr) {
+        ptr = nullptr;
+    }
+
+    static bool CheckCustomDeleteInvocations(size_t expected) { return true; }
+    static void ResetCustomDeleter() { }
+
+    // Unique pointers always get cleared when being moved or transferred.
+    static inline PtrType&& Transfer(PtrType& ptr)      { return std::move(ptr); }
+    static bool WasTransferred(const ConstPtrType& ptr) { return ptr == nullptr; }
+    static bool WasMoved (const ConstPtrType& ptr)      { return ptr == nullptr; }
+};
+
+template <typename _ObjType>
+struct StdUniquePtrCustomDeleterTestTraits {
+    using ObjType       = _ObjType;
+    using PtrType       = typename ptr_type::StdUniquePtrCustomDeleter<ObjType>::type;
+    using ConstPtrType  = const PtrType;
+    using ContainerType = typename ObjType::ContainerTraits::ContainerType;
+
+    static PtrType CreateObject(size_t value) {
+        AllocChecker ac;
+        auto r = new (&ac) ObjType(value);
+        return PtrType(ac.check() ? r : nullptr);
+    }
+
+    static void ReleaseObject(PtrType& ptr) {
+        ptr = nullptr;
+    }
+
+    static bool CheckCustomDeleteInvocations(size_t expected) {
+        BEGIN_HELPER;
+        EXPECT_EQ(expected, TestCustomDeleter<_ObjType>::delete_count());
+        END_HELPER;
+    }
+
+    static void ResetCustomDeleter() {
+        TestCustomDeleter<_ObjType>::reset_delete_count();
+    }
+
     // Unique pointers always get cleared when being moved or transferred.
     static inline PtrType&& Transfer(PtrType& ptr)      { return std::move(ptr); }
     static bool WasTransferred(const ConstPtrType& ptr) { return ptr == nullptr; }
@@ -170,7 +290,7 @@
 template <typename _ObjType>
 struct RefPtrTestTraits {
     using ObjType       = _ObjType;
-    using PtrType       = ::fbl::RefPtr<ObjType>;
+    using PtrType       = typename ptr_type::RefPtr<ObjType>::type;
     using ConstPtrType  = const PtrType;
     using ContainerType = typename ObjType::ContainerTraits::ContainerType;
 
@@ -184,6 +304,9 @@
         ptr = nullptr;
     }
 
+    static bool CheckCustomDeleteInvocations(size_t expected) { return true; }
+    static void ResetCustomDeleter() { }
+
     // RefCounted pointers do not get cleared when being transferred, but do get
     // cleared when being moved.
     static inline PtrType& Transfer(PtrType& ptr)       { return ptr; }
diff --git a/system/utest/fbl/include/fbl/tests/intrusive_containers/ordered_associative_container_test_environment.h b/system/utest/fbl/include/fbl/tests/intrusive_containers/ordered_associative_container_test_environment.h
index 3094d98..83b2ba0 100644
--- a/system/utest/fbl/include/fbl/tests/intrusive_containers/ordered_associative_container_test_environment.h
+++ b/system/utest/fbl/include/fbl/tests/intrusive_containers/ordered_associative_container_test_environment.h
@@ -240,8 +240,6 @@
         END_TEST;
     }
 
-    // TODO(johngro) : lower bound tests
-
 private:
     ContainerType&       container()       { return this->container_; }
     const ContainerType& const_container() { return this->container_; }
diff --git a/system/utest/fbl/include/fbl/tests/intrusive_containers/sequence_container_test_environment.h b/system/utest/fbl/include/fbl/tests/intrusive_containers/sequence_container_test_environment.h
index c862c1d9..ec22719 100644
--- a/system/utest/fbl/include/fbl/tests/intrusive_containers/sequence_container_test_environment.h
+++ b/system/utest/fbl/include/fbl/tests/intrusive_containers/sequence_container_test_environment.h
@@ -97,6 +97,7 @@
     bool PushFront() {
         BEGIN_TEST;
         EXPECT_TRUE(Populate(container()), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
         END_TEST;
     }
 
@@ -137,6 +138,8 @@
             i++;
         }
 
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -181,6 +184,7 @@
             // Let go of the object and verify that it has now gone away.
             ReleaseObject(i);
             EXPECT_EQ(remaining - 1, ObjType::live_obj_count(), "");
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(i + 1));
         }
 
         // List should be empty now.  Popping anything else should result in a
@@ -188,6 +192,7 @@
         EXPECT_TRUE(container().is_empty(), "");
         PtrType should_be_null = container().pop_front();
         EXPECT_NULL(should_be_null, "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
 
         END_TEST;
     }
@@ -234,6 +239,7 @@
             // Let go of the object and verify that it has now gone away.
             ReleaseObject(obj_ndx);
             EXPECT_EQ(remaining - 1, ObjType::live_obj_count(), "");
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(i + 1));
         }
 
         // List should be empty now.  Popping anything else should result in a
@@ -241,6 +247,7 @@
         EXPECT_TRUE(container().is_empty(), "");
         PtrType should_be_null = container().pop_back();
         EXPECT_NULL(should_be_null, "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
 
         END_TEST;
     }
@@ -287,6 +294,7 @@
             // Let go of the object and verify that it has now gone away.
             ReleaseObject(i);
             EXPECT_EQ(remaining - 1, ObjType::live_obj_count(), "");
+            EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(i));
         }
 
         // Iterator should now be one away from the end, and there should be one
@@ -302,6 +310,7 @@
         iter = container().begin();
         PtrType tmp = container().erase_next(iter);
         EXPECT_NULL(tmp, "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT - 1));
 
         END_TEST;
     }
@@ -344,6 +353,9 @@
         EXPECT_EQ(objects()[orig_iter_pos], iter->raw_ptr(), "");
         EXPECT_EQ(orig_iter_pos, iter->value(), "");
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -405,6 +417,9 @@
             i++;
         }
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -498,6 +513,9 @@
             i++;
         }
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -553,6 +571,9 @@
             i++;
         }
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -570,30 +591,33 @@
     }
 
     bool BidirectionalEquals(const ContainerType& sequence, const size_t* values, size_t size) {
-      BEGIN_TEST;
+        BEGIN_TEST;
 
-      // We use SupportsConstantOrderErase as a way to discriminate a singly-
-      // linked list from a doubly-linked list.
-      static_assert(ContainerType::IsSequenced && ContainerType::SupportsConstantOrderErase,
-                    "BidirectionalEquals must be used with a bi-directional sequence");
+        // We use SupportsConstantOrderErase as a way to discriminate a singly-
+        // linked list from a doubly-linked list.
+        static_assert(ContainerType::IsSequenced && ContainerType::SupportsConstantOrderErase,
+                      "BidirectionalEquals must be used with a bi-directional sequence");
 
-      ASSERT_EQ(size, Size(sequence), "");
+        ASSERT_EQ(size, Size(sequence), "");
 
-      // Iterate forwards and verify values.
-      const size_t* val_iter = values;
-      for (const auto& node : sequence) {
-          EXPECT_EQ(node.value(), *val_iter, "");
-          ++val_iter;
-      }
+        // Iterate forwards and verify values.
+        const size_t* val_iter = values;
+        for (const auto& node : sequence) {
+            EXPECT_EQ(node.value(), *val_iter, "");
+            ++val_iter;
+        }
 
-      // Iterate backwards and verify values.
-      for (auto begin = sequence.begin(), end = sequence.end(); begin != end;) {
-          --val_iter;
-          --end;
-          EXPECT_EQ(end->value(), *val_iter, "");
-      }
+        // Iterate backwards and verify values.
+        for (auto begin = sequence.begin(), end = sequence.end(); begin != end;) {
+            --val_iter;
+            --end;
+            EXPECT_EQ(end->value(), *val_iter, "");
+        }
 
-      END_TEST;
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
+        END_TEST;
     }
 
     bool Splice() {
@@ -657,10 +681,16 @@
         EXPECT_TRUE(BidirectionalEquals(target, expected_4, fbl::count_of(expected_4)), "");
         EXPECT_EQ(0u, Size(container()), "");
 
+        // No objects should have been deleted yet.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         // Finally clear the target.
         target.clear();
         EXPECT_EQ(0u, Size(target), "");
 
+        // By now, we should have created LIST_COUNT * 4 objects.  They should all be gone now.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(LIST_COUNT * 4));
+
         END_TEST;
     }
 
@@ -724,6 +754,9 @@
             i++;
         }
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -765,6 +798,9 @@
             EXPECT_TRUE(*prev_iter == *objects()[prev_ndx], "");
         }
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -781,6 +817,9 @@
         // Test const_iterator
         EXPECT_TRUE(DoSeqReverseIterate(container().cbegin(), container().cend()), "");
 
+        // This test should delete no objects
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(0));
+
         END_TEST;
     }
 
@@ -814,6 +853,10 @@
 
         }
 
+        // The object which we create in an attempt to replace an object in an
+        // empty container should be gone now.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(1));
+
         // Populate our container.
         for (size_t i = 0; i < OBJ_COUNT; ++i) {
             EXPECT_EQ(i, ObjType::live_obj_count(), "");
@@ -850,6 +893,9 @@
             EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
         }
 
+        // All of the replaced objects should have gone away now too.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT + 1));
+
         // Try again, but this time fail each time (since all of the original
         // element values have already been replaced).
         for (size_t i = 0; i < OBJ_COUNT; ++i) {
@@ -872,6 +918,9 @@
             EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
         }
 
+        // The new objects we created (but failed to replace in the container) should now be gone.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations((2 * OBJ_COUNT) + 1));
+
         // Make sure that the object are in order and have the values we expect.
         size_t i = 0;
         while (!container().is_empty()) {
@@ -883,6 +932,9 @@
         EXPECT_EQ(0, ObjType::live_obj_count(), "");
         EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
 
+        // Now all of the objects we created during the test should be gone.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations((3 * OBJ_COUNT) + 1));
+
         END_TEST;
     }
 
@@ -910,9 +962,12 @@
             TestEnvTraits::ReleaseObject(replaced);
             EXPECT_EQ(0, Size(container()));
             EXPECT_EQ(0, ObjType::live_obj_count(), "");
-
         }
 
+        // The object which we create in an attempt to replace an object in an
+        // empty container should be gone now.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(1));
+
         // Populate our container.
         for (size_t i = 0; i < OBJ_COUNT; ++i) {
             EXPECT_EQ(i, ObjType::live_obj_count(), "");
@@ -947,6 +1002,9 @@
             EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
         }
 
+        // All of the replaced objects should have gone away now too.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT + 1));
+
         // Try again, but this time fail each time (since all of the original
         // element values have already been replaced).
         for (size_t i = 0; i < OBJ_COUNT; ++i) {
@@ -972,6 +1030,9 @@
             EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
         }
 
+        // The new objects we created (but failed to replace in the container) should now be gone.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations((2 * OBJ_COUNT) + 1));
+
         // Make sure that the object are in order and have the values we expect.
         size_t i = 0;
         while (!container().is_empty()) {
@@ -982,6 +1043,9 @@
         }
         EXPECT_EQ(0, ObjType::live_obj_count(), "");
 
+        // Now all of the objects we created during the test should be gone.
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations((3 * OBJ_COUNT) + 1));
+
         END_TEST;
     }
 
@@ -1031,6 +1095,8 @@
             EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
         }
 
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
+
         // Make sure that the object are in order and have the values we expect.
         size_t i = 0;
         while (!container().is_empty()) {
@@ -1041,6 +1107,7 @@
         }
         EXPECT_EQ(0, ObjType::live_obj_count(), "");
         EXPECT_TRUE(ContainerChecker::SanityCheck(container()), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(2 * OBJ_COUNT));
 
         END_TEST;
     }
@@ -1086,6 +1153,7 @@
             TestEnvTraits::ReleaseObject(replaced);
             EXPECT_EQ(OBJ_COUNT, ObjType::live_obj_count(), "");
         }
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(OBJ_COUNT));
 
         // Make sure that the object are in order and have the values we expect.
         size_t i = 0;
@@ -1096,6 +1164,7 @@
             ++i;
         }
         EXPECT_EQ(0, ObjType::live_obj_count(), "");
+        EXPECT_TRUE(TestEnvTraits::CheckCustomDeleteInvocations(2 * OBJ_COUNT));
 
         END_TEST;
     }
diff --git a/system/utest/fbl/include/fbl/tests/intrusive_containers/test_thunks.h b/system/utest/fbl/include/fbl/tests/intrusive_containers/test_thunks.h
index bec682b..2c62741 100644
--- a/system/utest/fbl/include/fbl/tests/intrusive_containers/test_thunks.h
+++ b/system/utest/fbl/include/fbl/tests/intrusive_containers/test_thunks.h
@@ -71,12 +71,13 @@
 };
 #undef MAKE_TEST_THUNK
 
-// Macros used to define test object types, test environments, and test thunk structs used for
-// exercising various containers and managed/unmanaged pointer types.
-#define DEFINE_TEST_OBJECT(_container_type, _ptr_type, _ptr_prefix, _ptr_suffix, _base_type) \
+// Macros used to define test object types, test environments, and test thunk
+// structs used for exercising various containers and managed/unmanaged pointer
+// types.
+#define DEFINE_TEST_OBJECT(_container_type, _ptr_type, _base_type) \
 class _ptr_type ## _container_type ## TestObj :                                              \
     public _base_type<_container_type ## Traits<                                             \
-        _ptr_prefix _ptr_type ## _container_type ## TestObj _ptr_suffix>> {                  \
+        typename ptr_type::_ptr_type<_ptr_type ## _container_type ## TestObj>::type>> {      \
 public:                                                                                      \
     explicit _ptr_type ## _container_type ## TestObj(size_t val)                             \
             : _base_type(val) { }                                                            \
@@ -84,15 +85,25 @@
 using _ptr_type ## _container_type ## TestTraits =                                           \
     _ptr_type ## TestTraits<_ptr_type ## _container_type ## TestObj>
 
-#define DEFINE_TEST_OBJECTS(_container_type)                                      \
-    DEFINE_TEST_OBJECT(_container_type, Unmanaged,            , *, TestObj);      \
-    DEFINE_TEST_OBJECT(_container_type, UniquePtr, unique_ptr<, >, TestObj);      \
-    DEFINE_TEST_OBJECT(_container_type, RefPtr,        RefPtr<, >, RefedTestObj)
+// Macro which declare static storage for things like custom deleters for each
+// tested container type.  If new static storage is needed for testing custom
+// pointer type or custom deleters, it should be declared here.
+#define DECLARE_TEST_STORAGE(_container_type) \
+    template <> fbl::atomic<size_t> TestCustomDeleter< \
+        StdUniquePtrCustomDeleter ## _container_type ## TestObj \
+    >::delete_count_{0}
+
+#define DEFINE_TEST_OBJECTS(_container_type)                                    \
+    DEFINE_TEST_OBJECT(_container_type, Unmanaged, TestObj);                    \
+    DEFINE_TEST_OBJECT(_container_type, UniquePtr, TestObj);                    \
+    DEFINE_TEST_OBJECT(_container_type, StdUniquePtrDefaultDeleter, TestObj);   \
+    DEFINE_TEST_OBJECT(_container_type, StdUniquePtrCustomDeleter, TestObj);    \
+    DEFINE_TEST_OBJECT(_container_type, RefPtr, RefedTestObj);                  \
+    DECLARE_TEST_STORAGE(_container_type)
 
 #define DEFINE_TEST_THUNK(_env_type, _container_type, _ptr_type) \
     TestThunks<_env_type ## ContainerTestEnvironment<_ptr_type ## _container_type ## TestTraits>>
 
-
 }  // namespace intrusive_containers
 }  // namespace tests
 }  // namespace fbl
diff --git a/system/utest/fbl/intrusive_doubly_linked_list_tests.cpp b/system/utest/fbl/intrusive_doubly_linked_list_tests.cpp
index f88b5a1..a3fcd9a 100644
--- a/system/utest/fbl/intrusive_doubly_linked_list_tests.cpp
+++ b/system/utest/fbl/intrusive_doubly_linked_list_tests.cpp
@@ -35,151 +35,215 @@
 };
 
 DEFINE_TEST_OBJECTS(DLL);
-using UMTE = DEFINE_TEST_THUNK(Sequence, DLL, Unmanaged);
-using UPTE = DEFINE_TEST_THUNK(Sequence, DLL, UniquePtr);
-using RPTE = DEFINE_TEST_THUNK(Sequence, DLL, RefPtr);
+using UMTE    = DEFINE_TEST_THUNK(Sequence, DLL, Unmanaged);
+using UPTE    = DEFINE_TEST_THUNK(Sequence, DLL, UniquePtr);
+using SUPDDTE = DEFINE_TEST_THUNK(Sequence, DLL, StdUniquePtrDefaultDeleter);
+using SUPCDTE = DEFINE_TEST_THUNK(Sequence, DLL, StdUniquePtrCustomDeleter);
+using RPTE    = DEFINE_TEST_THUNK(Sequence, DLL, RefPtr);
 
 BEGIN_TEST_CASE(double_linked_list_tests)
 //////////////////////////////////////////
 // General container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("Clear (unmanaged)",             UMTE::ClearTest)
-RUN_NAMED_TEST("Clear (unique)",                UPTE::ClearTest)
-RUN_NAMED_TEST("Clear (RefPtr)",                RPTE::ClearTest)
+RUN_NAMED_TEST("Clear (unmanaged)",                 UMTE::ClearTest)
+RUN_NAMED_TEST("Clear (unique)",                    UPTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr)",                 SUPDDTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr<Del>)",            SUPCDTE::ClearTest)
+RUN_NAMED_TEST("Clear (RefPtr)",                    RPTE::ClearTest)
 
-RUN_NAMED_TEST("ClearUnsafe (unmanaged)",       UMTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unmanaged)",           UMTE::ClearUnsafeTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ClearUnsafe (unique)",          UPTE::ClearUnsafeTest)
-RUN_NAMED_TEST("ClearUnsafe (RefPtr)",          RPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unique)",              UPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr)",           SUPDDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr<Del>)",      SUPCDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (RefPtr)",              RPTE::ClearUnsafeTest)
 #endif
 
-RUN_NAMED_TEST("IsEmpty (unmanaged)",           UMTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (unique)",              UPTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (RefPtr)",              RPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unmanaged)",               UMTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unique)",                  UPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr)",               SUPDDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr<Del>)",          SUPCDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (RefPtr)",                  RPTE::IsEmptyTest)
 
-RUN_NAMED_TEST("Iterate (unmanaged)",           UMTE::IterateTest)
-RUN_NAMED_TEST("Iterate (unique)",              UPTE::IterateTest)
-RUN_NAMED_TEST("Iterate (RefPtr)",              RPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unmanaged)",               UMTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unique)",                  UPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr)",               SUPDDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr<Del>)",          SUPCDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (RefPtr)",                  RPTE::IterateTest)
 
-RUN_NAMED_TEST("IterErase (unmanaged)",         UMTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (unique)",            UPTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (RefPtr)",            RPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unmanaged)",             UMTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unique)",                UPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr)",             SUPDDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr<Del>)",        SUPCDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (RefPtr)",                RPTE::IterEraseTest)
 
-RUN_NAMED_TEST("DirectErase (unmanaged)",       UMTE::DirectEraseTest)
-RUN_NAMED_TEST("DirectErase (unique)",          UPTE::DirectEraseTest)
-RUN_NAMED_TEST("DirectErase (RefPtr)",          RPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unmanaged)",           UMTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unique)",              UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr)",           SUPDDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr<Del>)",      SUPCDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (RefPtr)",              RPTE::DirectEraseTest)
 
-RUN_NAMED_TEST("MakeIterator (unmanaged)",      UMTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unmanaged)",          UMTE::MakeIteratorTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("MakeIterator (unique)",         UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unique)",             UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr)",          SUPDDTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr<Del>)",     SUPCDTE::MakeIteratorTest)
 #endif
-RUN_NAMED_TEST("MakeIterator (RefPtr)",         RPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (RefPtr)",             RPTE::MakeIteratorTest)
 
-RUN_NAMED_TEST("ReverseIterErase (unmanaged)",  UMTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (unique)",     UPTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (RefPtr)",     RPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unmanaged)",      UMTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unique)",         UPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr)",      SUPDDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr<Del>)", SUPCDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (RefPtr)",         RPTE::ReverseIterEraseTest)
 
-RUN_NAMED_TEST("ReverseIterate (unmanaged)",    UMTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (unique)",       UPTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (RefPtr)",       RPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unmanaged)",        UMTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unique)",           UPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr)",        SUPDDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr<Del>)",   SUPCDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (RefPtr)",           RPTE::ReverseIterateTest)
 
-RUN_NAMED_TEST("Swap (unmanaged)",              UMTE::SwapTest)
-RUN_NAMED_TEST("Swap (unique)",                 UPTE::SwapTest)
-RUN_NAMED_TEST("Swap (RefPtr)",                 RPTE::SwapTest)
+RUN_NAMED_TEST("Swap (unmanaged)",                  UMTE::SwapTest)
+RUN_NAMED_TEST("Swap (unique)",                     UPTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr)",                  SUPDDTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr<Del>)",             SUPCDTE::SwapTest)
+RUN_NAMED_TEST("Swap (RefPtr)",                     RPTE::SwapTest)
 
-RUN_NAMED_TEST("Rvalue Ops (unmanaged)",        UMTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (unique)",           UPTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (RefPtr)",           RPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unmanaged)",            UMTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unique)",               UPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr)",            SUPDDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr<Del>)",       SUPCDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (RefPtr)",               RPTE::RvalueOpsTest)
 
-RUN_NAMED_TEST("Scope (unique)",                UPTE::ScopeTest)
-RUN_NAMED_TEST("Scope (RefPtr)",                RPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (unique)",                    UPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr)",                 SUPDDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr<Del>)",            SUPCDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (RefPtr)",                    RPTE::ScopeTest)
 
-RUN_NAMED_TEST("TwoContainer (unmanaged)",      UMTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unmanaged)",          UMTE::TwoContainerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("TwoContainer (unique)",         UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unique)",             UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr)",          SUPDDTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr<Del>)",     SUPCDTE::TwoContainerTest)
 #endif
-RUN_NAMED_TEST("TwoContainer (RefPtr)",         RPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (RefPtr)",             RPTE::TwoContainerTest)
 
-RUN_NAMED_TEST("IterCopyPointer (unmanaged)",   UMTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unmanaged)",       UMTE::IterCopyPointerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("IterCopyPointer (unique)",      UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unique)",          UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr)",       SUPDDTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr<Del>)",  SUPCDTE::IterCopyPointerTest)
 #endif
-RUN_NAMED_TEST("IterCopyPointer (RefPtr)",      RPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (RefPtr)",          RPTE::IterCopyPointerTest)
 
-RUN_NAMED_TEST("EraseIf (unmanaged)",           UMTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (unique)",              UPTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (RefPtr)",              RPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unmanaged)",               UMTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unique)",                  UPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr)",               SUPDDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr<Del>)",          SUPCDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (RefPtr)",                  RPTE::EraseIfTest)
 
-RUN_NAMED_TEST("FindIf (unmanaged)",            UMTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (unique)",               UPTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (RefPtr)",               RPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unmanaged)",                UMTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unique)",                   UPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr)",                SUPDDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr<Del>)",           SUPCDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (RefPtr)",                   RPTE::FindIfTest)
 
 //////////////////////////////////////////
 // Sequence container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("PushFront (unmanaged)",         UMTE::PushFrontTest)
-RUN_NAMED_TEST("PushFront (unique)",            UPTE::PushFrontTest)
-RUN_NAMED_TEST("PushFront (RefPtr)",            RPTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (unmanaged)",             UMTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (unique)",                UPTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (std::uptr)",             SUPDDTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (std::uptr<Del>)",        SUPCDTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (RefPtr)",                RPTE::PushFrontTest)
 
-RUN_NAMED_TEST("PopFront (unmanaged)",          UMTE::PopFrontTest)
-RUN_NAMED_TEST("PopFront (unique)",             UPTE::PopFrontTest)
-RUN_NAMED_TEST("PopFront (RefPtr)",             RPTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (unmanaged)",              UMTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (unique)",                 UPTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (std::uptr)",              SUPDDTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (std::uptr<Del>)",         SUPCDTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (RefPtr)",                 RPTE::PopFrontTest)
 
-RUN_NAMED_TEST("PushBack (unmanaged)",          UMTE::PushBackTest)
-RUN_NAMED_TEST("PushBack (unique)",             UPTE::PushBackTest)
-RUN_NAMED_TEST("PushBack (RefPtr)",             RPTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (unmanaged)",              UMTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (unique)",                 UPTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (std::uptr)",              SUPDDTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (std::uptr<Del>)",         SUPCDTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (RefPtr)",                 RPTE::PushBackTest)
 
-RUN_NAMED_TEST("PopBack (unmanaged)",           UMTE::PopBackTest)
-RUN_NAMED_TEST("PopBack (unique)",              UPTE::PopBackTest)
-RUN_NAMED_TEST("PopBack (RefPtr)",              RPTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (unmanaged)",               UMTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (unique)",                  UPTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (std::uptr)",               SUPDDTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (std::uptr<Del>)",          SUPCDTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (RefPtr)",                  RPTE::PopBackTest)
 
-RUN_NAMED_TEST("SeqIterate (unmanaged)",        UMTE::SeqIterateTest)
-RUN_NAMED_TEST("SeqIterate (unique)",           UPTE::SeqIterateTest)
-RUN_NAMED_TEST("SeqIterate (RefPtr)",           RPTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (unmanaged)",            UMTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (unique)",               UPTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (std::uptr)",            SUPDDTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (std::uptr<Del>)",       SUPCDTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (RefPtr)",               RPTE::SeqIterateTest)
 
-RUN_NAMED_TEST("SeqReverseIterate (unmanaged)", UMTE::SeqReverseIterateTest)
-RUN_NAMED_TEST("SeqReverseIterate (unique)",    UPTE::SeqReverseIterateTest)
-RUN_NAMED_TEST("SeqReverseIterate (RefPtr)",    RPTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (unmanaged)",     UMTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (unique)",        UPTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (std::uptr)",     SUPDDTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (std::uptr<Del>)",SUPCDTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (RefPtr)",        RPTE::SeqReverseIterateTest)
 
-RUN_NAMED_TEST("EraseNext (unmanaged)",         UMTE::EraseNextTest)
-RUN_NAMED_TEST("EraseNext (unique)",            UPTE::EraseNextTest)
-RUN_NAMED_TEST("EraseNext (RefPtr)",            RPTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (unmanaged)",             UMTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (unique)",                UPTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (std::uptr)",             SUPDDTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (std::uptr<Del>)",        SUPCDTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (RefPtr)",                RPTE::EraseNextTest)
 
-RUN_NAMED_TEST("InsertAfter (unmanaged)",       UMTE::InsertAfterTest)
-RUN_NAMED_TEST("InsertAfter (unique)",          UPTE::InsertAfterTest)
-RUN_NAMED_TEST("InsertAfter (RefPtr)",          RPTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (unmanaged)",           UMTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (unique)",              UPTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (std::uptr)",           SUPDDTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (std::uptr<Del>)",      SUPCDTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (RefPtr)",              RPTE::InsertAfterTest)
 
-RUN_NAMED_TEST("Insert (unmanaged)",            UMTE::InsertTest)
-RUN_NAMED_TEST("Insert (unique)",               UPTE::InsertTest)
-RUN_NAMED_TEST("Insert (RefPtr)",               RPTE::InsertTest)
+RUN_NAMED_TEST("Insert (unmanaged)",                UMTE::InsertTest)
+RUN_NAMED_TEST("Insert (unique)",                   UPTE::InsertTest)
+RUN_NAMED_TEST("Insert (std::uptr)",                SUPDDTE::InsertTest)
+RUN_NAMED_TEST("Insert (std::uptr<Del>)",           SUPCDTE::InsertTest)
+RUN_NAMED_TEST("Insert (RefPtr)",                   RPTE::InsertTest)
 
-RUN_NAMED_TEST("DirectInsert (unmanaged)",      UMTE::DirectInsertTest)
-RUN_NAMED_TEST("DirectInsert (unique)",         UPTE::DirectInsertTest)
-RUN_NAMED_TEST("DirectInsert (RefPtr)",         RPTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (unmanaged)",          UMTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (unique)",             UPTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (std::uptr)",          SUPDDTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (std::uptr<Del>)",     SUPCDTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (RefPtr)",             RPTE::DirectInsertTest)
 
-RUN_NAMED_TEST("Splice (unmanaged)",            UMTE::SpliceTest)
-RUN_NAMED_TEST("Splice (unique)",               UPTE::SpliceTest)
-RUN_NAMED_TEST("Splice (RefPtr)",               RPTE::SpliceTest)
+RUN_NAMED_TEST("Splice (unmanaged)",                UMTE::SpliceTest)
+RUN_NAMED_TEST("Splice (unique)",                   UPTE::SpliceTest)
+RUN_NAMED_TEST("Splice (std::uptr)",                SUPDDTE::SpliceTest)
+RUN_NAMED_TEST("Splice (std::uptr<Del>)",           SUPCDTE::SpliceTest)
+RUN_NAMED_TEST("Splice (RefPtr)",                   RPTE::SpliceTest)
 
-RUN_NAMED_TEST("ReplaceIfCopy (unmanaged)",     UMTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (unmanaged)",         UMTE::ReplaceIfCopyTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ReplaceIfCopy (unique)",        UPTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (unique)",            UPTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (std::uptr)",         SUPDDTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (std::uptr<Del>)",    SUPCDTE::ReplaceIfCopyTest)
 #endif
-RUN_NAMED_TEST("ReplaceIfCopy (RefPtr)",        RPTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (RefPtr)",            RPTE::ReplaceIfCopyTest)
 
-RUN_NAMED_TEST("ReplaceIfMove (unmanaged)",     UMTE::ReplaceIfMoveTest)
-RUN_NAMED_TEST("ReplaceIfMove (unique)",        UPTE::ReplaceIfMoveTest)
-RUN_NAMED_TEST("ReplaceIfMove (RefPtr)",        RPTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (unmanaged)",         UMTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (unique)",            UPTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (std::uptr)",         SUPDDTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (std::uptr<Del>)",    SUPCDTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (RefPtr)",            RPTE::ReplaceIfMoveTest)
 
-RUN_NAMED_TEST("ReplaceCopy (unmanaged)",       UMTE::ReplaceCopyTest)
+RUN_NAMED_TEST("ReplaceCopy (unmanaged)",           UMTE::ReplaceCopyTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ReplaceCopy (unique)",          UPTE::ReplaceCopyTest)
+RUN_NAMED_TEST("ReplaceCopy (unique)",              UPTE::ReplaceCopyTest)
+RUN_NAMED_TEST("ReplaceCopy (std::uptr)",           SUPDDTE::ReplaceCopyTest)
+RUN_NAMED_TEST("ReplaceCopy (std::uptr<Del>)",      SUPCDTE::ReplaceCopyTest)
 #endif
-RUN_NAMED_TEST("ReplaceCopy (RefPtr)",          RPTE::ReplaceCopyTest)
+RUN_NAMED_TEST("ReplaceCopy (RefPtr)",              RPTE::ReplaceCopyTest)
 
-RUN_NAMED_TEST("ReplaceMove (unmanaged)",       UMTE::ReplaceMoveTest)
-RUN_NAMED_TEST("ReplaceMove (unique)",          UPTE::ReplaceMoveTest)
-RUN_NAMED_TEST("ReplaceMove (RefPtr)",          RPTE::ReplaceMoveTest)
+RUN_NAMED_TEST("ReplaceMove (unmanaged)",           UMTE::ReplaceMoveTest)
+RUN_NAMED_TEST("ReplaceMove (unique)",              UPTE::ReplaceMoveTest)
+RUN_NAMED_TEST("ReplaceMove (std::uptr)",           SUPDDTE::ReplaceMoveTest)
+RUN_NAMED_TEST("ReplaceMove (std::uptr<Del>)",      SUPCDTE::ReplaceMoveTest)
+RUN_NAMED_TEST("ReplaceMove (RefPtr)",              RPTE::ReplaceMoveTest)
 
 END_TEST_CASE(double_linked_list_tests);
 
diff --git a/system/utest/fbl/intrusive_hash_table_dll_tests.cpp b/system/utest/fbl/intrusive_hash_table_dll_tests.cpp
index d1bc9e9..34e4a65 100644
--- a/system/utest/fbl/intrusive_hash_table_dll_tests.cpp
+++ b/system/utest/fbl/intrusive_hash_table_dll_tests.cpp
@@ -88,114 +88,158 @@
 };
 
 DEFINE_TEST_OBJECTS(HTDLL);
-using UMTE = DEFINE_TEST_THUNK(Associative, HTDLL, Unmanaged);
-using UPTE = DEFINE_TEST_THUNK(Associative, HTDLL, UniquePtr);
-using RPTE = DEFINE_TEST_THUNK(Associative, HTDLL, RefPtr);
+using UMTE    = DEFINE_TEST_THUNK(Associative, HTDLL, Unmanaged);
+using UPTE    = DEFINE_TEST_THUNK(Associative, HTDLL, UniquePtr);
+using SUPDDTE = DEFINE_TEST_THUNK(Associative, HTDLL, StdUniquePtrDefaultDeleter);
+using SUPCDTE = DEFINE_TEST_THUNK(Associative, HTDLL, StdUniquePtrCustomDeleter);
+using RPTE    = DEFINE_TEST_THUNK(Associative, HTDLL, RefPtr);
 
 BEGIN_TEST_CASE(hashtable_dll_tests)
 //////////////////////////////////////////
 // General container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("Clear (unmanaged)",            UMTE::ClearTest)
-RUN_NAMED_TEST("Clear (unique)",               UPTE::ClearTest)
-RUN_NAMED_TEST("Clear (RefPtr)",               RPTE::ClearTest)
+RUN_NAMED_TEST("Clear (unmanaged)",                        UMTE::ClearTest)
+RUN_NAMED_TEST("Clear (unique)",                           UPTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr)",                        SUPDDTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr<Del>)",                   SUPCDTE::ClearTest)
+RUN_NAMED_TEST("Clear (RefPtr)",                           RPTE::ClearTest)
 
-RUN_NAMED_TEST("ClearUnsafe (unmanaged)",      UMTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unmanaged)",                  UMTE::ClearUnsafeTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ClearUnsafe (unique)",         UPTE::ClearUnsafeTest)
-RUN_NAMED_TEST("ClearUnsafe (RefPtr)",         RPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unique)",                     UPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr)",                  SUPDDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr<Del>)",             SUPCDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (RefPtr)",                     RPTE::ClearUnsafeTest)
 #endif
 
-RUN_NAMED_TEST("IsEmpty (unmanaged)",          UMTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (unique)",             UPTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (RefPtr)",             RPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unmanaged)",                      UMTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unique)",                         UPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr)",                      SUPDDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr<Del>)",                 SUPCDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (RefPtr)",                         RPTE::IsEmptyTest)
 
-RUN_NAMED_TEST("Iterate (unmanaged)",          UMTE::IterateTest)
-RUN_NAMED_TEST("Iterate (unique)",             UPTE::IterateTest)
-RUN_NAMED_TEST("Iterate (RefPtr)",             RPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unmanaged)",                      UMTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unique)",                         UPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr)",                      SUPDDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr<Del>)",                 SUPCDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (RefPtr)",                         RPTE::IterateTest)
 
-RUN_NAMED_TEST("IterErase (unmanaged)",        UMTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (unique)",           UPTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (RefPtr)",           RPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unmanaged)",                    UMTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unique)",                       UPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr)",                    SUPDDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr<Del>)",               SUPCDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (RefPtr)",                       RPTE::IterEraseTest)
 
-RUN_NAMED_TEST("DirectErase (unmanaged)",      UMTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unmanaged)",                  UMTE::DirectEraseTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("DirectErase (unique)",         UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unique)",                     UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr)",                  SUPDDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr<Del>)",             SUPCDTE::DirectEraseTest)
 #endif
-RUN_NAMED_TEST("DirectErase (RefPtr)",         RPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (RefPtr)",                     RPTE::DirectEraseTest)
 
-RUN_NAMED_TEST("MakeIterator (unmanaged)",     UMTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unmanaged)",                 UMTE::MakeIteratorTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("MakeIterator (unique)",        UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unique)",                    UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr)",                 SUPDDTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr<Del>)",            SUPCDTE::MakeIteratorTest)
 #endif
-RUN_NAMED_TEST("MakeIterator (RefPtr)",        RPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (RefPtr)",                    RPTE::MakeIteratorTest)
 
-RUN_NAMED_TEST("ReverseIterErase (unmanaged)", UMTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (unique)",    UPTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (RefPtr)",    RPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unmanaged)",             UMTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unique)",                UPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr)",             SUPDDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr<Del>)",        SUPCDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (RefPtr)",                RPTE::ReverseIterEraseTest)
 
-RUN_NAMED_TEST("ReverseIterate (unmanaged)",   UMTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (unique)",      UPTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (RefPtr)",      RPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unmanaged)",               UMTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unique)",                  UPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr)",               SUPDDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr<Del>)",          SUPCDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (RefPtr)",                  RPTE::ReverseIterateTest)
 
 // Hash tables do not support swapping or Rvalue operations (Assignment or
 // construction) as doing so would be an O(n) operation (With 'n' == to the
 // number of buckets in the hashtable)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("Swap (unmanaged)",             UMTE::SwapTest)
-RUN_NAMED_TEST("Swap (unique)",                UPTE::SwapTest)
-RUN_NAMED_TEST("Swap (RefPtr)",                RPTE::SwapTest)
+RUN_NAMED_TEST("Swap (unmanaged)",                         UMTE::SwapTest)
+RUN_NAMED_TEST("Swap (unique)",                            UPTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr)",                         SUPDDTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr<Del>)",                    SUPCDTE::SwapTest)
+RUN_NAMED_TEST("Swap (RefPtr)",                            RPTE::SwapTest)
 
-RUN_NAMED_TEST("Rvalue Ops (unmanaged)",       UMTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (unique)",          UPTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (RefPtr)",          RPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unmanaged)",                   UMTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unique)",                      UPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr)",                   SUPDDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr<Del>)",              SUPCDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (RefPtr)",                      RPTE::RvalueOpsTest)
 #endif
 
-RUN_NAMED_TEST("Scope (unique)",               UPTE::ScopeTest)
-RUN_NAMED_TEST("Scope (RefPtr)",               RPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (unique)",                           UPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr)",                        SUPDDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr<Del>)",                   SUPCDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (RefPtr)",                           RPTE::ScopeTest)
 
-RUN_NAMED_TEST("TwoContainer (unmanaged)",     UMTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unmanaged)",                 UMTE::TwoContainerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("TwoContainer (unique)",        UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unique)",                    UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr)",                 SUPDDTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr<Del>)",            SUPCDTE::TwoContainerTest)
 #endif
-RUN_NAMED_TEST("TwoContainer (RefPtr)",        RPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (RefPtr)",                    RPTE::TwoContainerTest)
 
-RUN_NAMED_TEST("IterCopyPointer (unmanaged)",  UMTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unmanaged)",              UMTE::IterCopyPointerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("IterCopyPointer (unique)",     UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unique)",                 UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr)",              SUPDDTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr<Del>)",         SUPCDTE::IterCopyPointerTest)
 #endif
-RUN_NAMED_TEST("IterCopyPointer (RefPtr)",     RPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (RefPtr)",                 RPTE::IterCopyPointerTest)
 
-RUN_NAMED_TEST("EraseIf (unmanaged)",          UMTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (unique)",             UPTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (RefPtr)",             RPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unmanaged)",                      UMTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unique)",                         UPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr)",                      SUPDDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr<Del>)",                 SUPCDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (RefPtr)",                         RPTE::EraseIfTest)
 
-RUN_NAMED_TEST("FindIf (unmanaged)",           UMTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (unique)",              UPTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (RefPtr)",              RPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unmanaged)",                       UMTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unique)",                          UPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr)",                       SUPDDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr<Del>)",                  SUPCDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (RefPtr)",                          RPTE::FindIfTest)
 
 //////////////////////////////////////////
 // Associative container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("InsertByKey (unmanaged)",      UMTE::InsertByKeyTest)
-RUN_NAMED_TEST("InsertByKey (unique)",         UPTE::InsertByKeyTest)
-RUN_NAMED_TEST("InsertByKey (RefPtr)",         RPTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (unmanaged)",                  UMTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (unique)",                     UPTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (std::uptr)",                  SUPDDTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (std::uptr<Del>)",             SUPCDTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (RefPtr)",                     RPTE::InsertByKeyTest)
 
-RUN_NAMED_TEST("FindByKey (unmanaged)",        UMTE::FindByKeyTest)
-RUN_NAMED_TEST("FindByKey (unique)",           UPTE::FindByKeyTest)
-RUN_NAMED_TEST("FindByKey (RefPtr)",           RPTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (unmanaged)",                    UMTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (unique)",                       UPTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (std::uptr)",                    SUPDDTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (std::uptr<Del>)",               SUPCDTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (RefPtr)",                       RPTE::FindByKeyTest)
 
-RUN_NAMED_TEST("EraseByKey (unmanaged)",       UMTE::EraseByKeyTest)
-RUN_NAMED_TEST("EraseByKey (unique)",          UPTE::EraseByKeyTest)
-RUN_NAMED_TEST("EraseByKey (RefPtr)",          RPTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (unmanaged)",                   UMTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (unique)",                      UPTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (std::uptr)",                   SUPDDTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (std::uptr<Del>)",              SUPCDTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (RefPtr)",                      RPTE::EraseByKeyTest)
 
-RUN_NAMED_TEST("InsertOrFind (unmanaged)",     UMTE::InsertOrFindTest)
-RUN_NAMED_TEST("InsertOrFind (unique)",        UPTE::InsertOrFindTest)
-RUN_NAMED_TEST("InsertOrFind (RefPtr)",        RPTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (unmanaged)",                 UMTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (unique)",                    UPTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (std::uptr)",                 SUPDDTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (std::uptr<Del>)",            SUPCDTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (RefPtr)",                    RPTE::InsertOrFindTest)
 
-RUN_NAMED_TEST("InsertOrReplace (unmanaged)",  UMTE::InsertOrReplaceTest)
-RUN_NAMED_TEST("InsertOrReplace (unique)",     UPTE::InsertOrReplaceTest)
-RUN_NAMED_TEST("InsertOrReplace (RefPtr)",     RPTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (unmanaged)",              UMTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (unique)",                 UPTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (std::uptr)",              SUPDDTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (std::uptr<Del>)",         SUPCDTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (RefPtr)",                 RPTE::InsertOrReplaceTest)
 END_TEST_CASE(hashtable_dll_tests);
 
 }  // namespace intrusive_containers
diff --git a/system/utest/fbl/intrusive_hash_table_sll_tests.cpp b/system/utest/fbl/intrusive_hash_table_sll_tests.cpp
index 6f1fc2e..10a6163 100644
--- a/system/utest/fbl/intrusive_hash_table_sll_tests.cpp
+++ b/system/utest/fbl/intrusive_hash_table_sll_tests.cpp
@@ -88,60 +88,80 @@
 };
 
 DEFINE_TEST_OBJECTS(HTSLL);
-using UMTE = DEFINE_TEST_THUNK(Associative, HTSLL, Unmanaged);
-using UPTE = DEFINE_TEST_THUNK(Associative, HTSLL, UniquePtr);
-using RPTE = DEFINE_TEST_THUNK(Associative, HTSLL, RefPtr);
+using UMTE    = DEFINE_TEST_THUNK(Associative, HTSLL, Unmanaged);
+using UPTE    = DEFINE_TEST_THUNK(Associative, HTSLL, UniquePtr);
+using SUPDDTE = DEFINE_TEST_THUNK(Associative, HTSLL, StdUniquePtrDefaultDeleter);
+using SUPCDTE = DEFINE_TEST_THUNK(Associative, HTSLL, StdUniquePtrCustomDeleter);
+using RPTE    = DEFINE_TEST_THUNK(Associative, HTSLL, RefPtr);
 
 BEGIN_TEST_CASE(hashtable_sll_tests)
 //////////////////////////////////////////
 // General container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("Clear (unmanaged)",            UMTE::ClearTest)
-RUN_NAMED_TEST("Clear (unique)",               UPTE::ClearTest)
-RUN_NAMED_TEST("Clear (RefPtr)",               RPTE::ClearTest)
+RUN_NAMED_TEST("Clear (unmanaged)",                        UMTE::ClearTest)
+RUN_NAMED_TEST("Clear (unique)",                           UPTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr)",                        SUPDDTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr<Del>)",                   SUPCDTE::ClearTest)
+RUN_NAMED_TEST("Clear (RefPtr)",                           RPTE::ClearTest)
 
-RUN_NAMED_TEST("ClearUnsafe (unmanaged)",      UMTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unmanaged)",                  UMTE::ClearUnsafeTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ClearUnsafe (unique)",         UPTE::ClearUnsafeTest)
-RUN_NAMED_TEST("ClearUnsafe (RefPtr)",         RPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unique)",                     UPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr)",                  SUPDDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr<Del>)",             SUPCDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (RefPtr)",                     RPTE::ClearUnsafeTest)
 #endif
 
-RUN_NAMED_TEST("IsEmpty (unmanaged)",          UMTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (unique)",             UPTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (RefPtr)",             RPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unmanaged)",                      UMTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unique)",                         UPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr)",                      SUPDDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr<Del>)",                 SUPCDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (RefPtr)",                         RPTE::IsEmptyTest)
 
-RUN_NAMED_TEST("Iterate (unmanaged)",          UMTE::IterateTest)
-RUN_NAMED_TEST("Iterate (unique)",             UPTE::IterateTest)
-RUN_NAMED_TEST("Iterate (RefPtr)",             RPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unmanaged)",                      UMTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unique)",                         UPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr)",                      SUPDDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr<Del>)",                 SUPCDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (RefPtr)",                         RPTE::IterateTest)
 
 // Hashtables with singly linked list bucket can perform direct
 // iterator/reference erase operations, but the operations will be O(n)
-RUN_NAMED_TEST("IterErase (unmanaged)",        UMTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (unique)",           UPTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (RefPtr)",           RPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unmanaged)",                    UMTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unique)",                       UPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr)",                    SUPDDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr<Del>)",               SUPCDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (RefPtr)",                       RPTE::IterEraseTest)
 
-RUN_NAMED_TEST("DirectErase (unmanaged)",      UMTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unmanaged)",                  UMTE::DirectEraseTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("DirectErase (unique)",         UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unique)",                     UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr)",                  SUPDDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr<Del>)",             SUPCDTE::DirectEraseTest)
 #endif
-RUN_NAMED_TEST("DirectErase (RefPtr)",         RPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (RefPtr)",                     RPTE::DirectEraseTest)
 
-RUN_NAMED_TEST("MakeIterator (unmanaged)",     UMTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unmanaged)",                 UMTE::MakeIteratorTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("MakeIterator (unique)",        UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unique)",                    UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr)",                 SUPDDTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr<Del>)",            SUPCDTE::MakeIteratorTest)
 #endif
-RUN_NAMED_TEST("MakeIterator (RefPtr)",        RPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (RefPtr)",                    RPTE::MakeIteratorTest)
 
 // HashTables with SinglyLinkedList buckets cannot iterate backwards (because
 // their buckets cannot iterate backwards)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ReverseIterErase (unmanaged)", UMTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (unique)",    UPTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (RefPtr)",    RPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unmanaged)",             UMTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unique)",                UPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr)",             SUPDDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr<Del>)",        SUPCDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (RefPtr)",                RPTE::ReverseIterEraseTest)
 
-RUN_NAMED_TEST("ReverseIterate (unmanaged)",   UMTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (unique)",      UPTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (RefPtr)",      RPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unmanaged)",               UMTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unique)",                  UPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr)",               SUPDDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr<Del>)",          SUPCDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (RefPtr)",                  RPTE::ReverseIterateTest)
 #endif
 
 // Hash tables do not support swapping or Rvalue operations (Assignment or
@@ -150,58 +170,80 @@
 #if TEST_WILL_NOT_COMPILE || 0
 RUN_NAMED_TEST("Swap (unmanaged)",             UMTE::SwapTest)
 RUN_NAMED_TEST("Swap (unique)",                UPTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr)",             SUPDDTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr<Del>)",        SUPCDTE::SwapTest)
 RUN_NAMED_TEST("Swap (RefPtr)",                RPTE::SwapTest)
 
 RUN_NAMED_TEST("Rvalue Ops (unmanaged)",       UMTE::RvalueOpsTest)
 RUN_NAMED_TEST("Rvalue Ops (unique)",          UPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr)",       SUPDDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr<Del>)",  SUPCDTE::RvalueOpsTest)
 RUN_NAMED_TEST("Rvalue Ops (RefPtr)",          RPTE::RvalueOpsTest)
 #endif
 
 RUN_NAMED_TEST("Scope (unique)",               UPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr)",            SUPDDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr<Del>)",       SUPCDTE::ScopeTest)
 RUN_NAMED_TEST("Scope (RefPtr)",               RPTE::ScopeTest)
 
 RUN_NAMED_TEST("TwoContainer (unmanaged)",     UMTE::TwoContainerTest)
 #if TEST_WILL_NOT_COMPILE || 0
 RUN_NAMED_TEST("TwoContainer (unique)",        UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr)",     SUPDDTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr<Del>)",SUPCDTE::TwoContainerTest)
 #endif
 RUN_NAMED_TEST("TwoContainer (RefPtr)",        RPTE::TwoContainerTest)
 
 RUN_NAMED_TEST("IterCopyPointer (unmanaged)",  UMTE::IterCopyPointerTest)
 #if TEST_WILL_NOT_COMPILE || 0
 RUN_NAMED_TEST("IterCopyPointer (unique)",     UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr)",  SUPDDTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr<Del>)",DDTE::IterCopyPointerTest)
 #endif
 RUN_NAMED_TEST("IterCopyPointer (RefPtr)",     RPTE::IterCopyPointerTest)
 
 RUN_NAMED_TEST("EraseIf (unmanaged)",          UMTE::EraseIfTest)
 RUN_NAMED_TEST("EraseIf (unique)",             UPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr)",          SUPCDTE::EraseIfTest)
 RUN_NAMED_TEST("EraseIf (RefPtr)",             RPTE::EraseIfTest)
 
 RUN_NAMED_TEST("FindIf (unmanaged)",           UMTE::FindIfTest)
 RUN_NAMED_TEST("FindIf (unique)",              UPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr)",           SUPDDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr<Del>)",      SUPCDTE::FindIfTest)
 RUN_NAMED_TEST("FindIf (RefPtr)",              RPTE::FindIfTest)
 
 //////////////////////////////////////////
 // Associative container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("InsertByKey (unmanaged)",      UMTE::InsertByKeyTest)
-RUN_NAMED_TEST("InsertByKey (unique)",         UPTE::InsertByKeyTest)
-RUN_NAMED_TEST("InsertByKey (RefPtr)",         RPTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (unmanaged)",          UMTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (unique)",             UPTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (std::uptr)",          SUPDDTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (std::uptr<Del>)",     SUPCDTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (RefPtr)",             RPTE::InsertByKeyTest)
 
-RUN_NAMED_TEST("FindByKey (unmanaged)",        UMTE::FindByKeyTest)
-RUN_NAMED_TEST("FindByKey (unique)",           UPTE::FindByKeyTest)
-RUN_NAMED_TEST("FindByKey (RefPtr)",           RPTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (unmanaged)",            UMTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (unique)",               UPTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (std::uptr)",            SUPDDTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (std::uptr<Del>)",       SUPCDTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (RefPtr)",               RPTE::FindByKeyTest)
 
-RUN_NAMED_TEST("EraseByKey (unmanaged)",       UMTE::EraseByKeyTest)
-RUN_NAMED_TEST("EraseByKey (unique)",          UPTE::EraseByKeyTest)
-RUN_NAMED_TEST("EraseByKey (RefPtr)",          RPTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (unmanaged)",           UMTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (unique)",              UPTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (std::uptr)",           SUPDDTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (std::uptr<Del>)",      SUPCDTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (RefPtr)",              RPTE::EraseByKeyTest)
 
-RUN_NAMED_TEST("InsertOrFind (unmanaged)",     UMTE::InsertOrFindTest)
-RUN_NAMED_TEST("InsertOrFind (unique)",        UPTE::InsertOrFindTest)
-RUN_NAMED_TEST("InsertOrFind (RefPtr)",        RPTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (unmanaged)",         UMTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (unique)",            UPTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (std::uptr)",         SUPDDTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (RefPtr)",            RPTE::InsertOrFindTest)
 
-RUN_NAMED_TEST("InsertOrReplace (unmanaged)",  UMTE::InsertOrReplaceTest)
-RUN_NAMED_TEST("InsertOrReplace (unique)",     UPTE::InsertOrReplaceTest)
-RUN_NAMED_TEST("InsertOrReplace (RefPtr)",     RPTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (unmanaged)",      UMTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (unique)",         UPTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (std::uptr)",      SUPDDTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (std::uptr<Del>)", SUPCDTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (RefPtr)",         RPTE::InsertOrReplaceTest)
 END_TEST_CASE(hashtable_sll_tests);
 
 }  // namespace intrusive_containers
diff --git a/system/utest/fbl/intrusive_singly_linked_list_tests.cpp b/system/utest/fbl/intrusive_singly_linked_list_tests.cpp
index 256b491..16cc5c0 100644
--- a/system/utest/fbl/intrusive_singly_linked_list_tests.cpp
+++ b/system/utest/fbl/intrusive_singly_linked_list_tests.cpp
@@ -35,161 +35,221 @@
 };
 
 DEFINE_TEST_OBJECTS(SLL);
-using UMTE = DEFINE_TEST_THUNK(Sequence, SLL, Unmanaged);
-using UPTE = DEFINE_TEST_THUNK(Sequence, SLL, UniquePtr);
-using RPTE = DEFINE_TEST_THUNK(Sequence, SLL, RefPtr);
+using UMTE    = DEFINE_TEST_THUNK(Sequence, SLL, Unmanaged);
+using UPTE    = DEFINE_TEST_THUNK(Sequence, SLL, UniquePtr);
+using SUPDDTE = DEFINE_TEST_THUNK(Sequence, SLL, StdUniquePtrDefaultDeleter);
+using SUPCDTE = DEFINE_TEST_THUNK(Sequence, SLL, StdUniquePtrCustomDeleter);
+using RPTE    = DEFINE_TEST_THUNK(Sequence, SLL, RefPtr);
 
 BEGIN_TEST_CASE(single_linked_list_tests)
 //////////////////////////////////////////
 // General container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("Clear (unmanaged)",             UMTE::ClearTest)
-RUN_NAMED_TEST("Clear (unique)",                UPTE::ClearTest)
-RUN_NAMED_TEST("Clear (RefPtr)",                RPTE::ClearTest)
+RUN_NAMED_TEST("Clear (unmanaged)",                         UMTE::ClearTest)
+RUN_NAMED_TEST("Clear (unique)",                            UPTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr)",                         SUPDDTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr<Del>)",                    SUPCDTE::ClearTest)
+RUN_NAMED_TEST("Clear (RefPtr)",                            RPTE::ClearTest)
 
-RUN_NAMED_TEST("ClearUnsafe (unmanaged)",       UMTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unmanaged)",                   UMTE::ClearUnsafeTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ClearUnsafe (unique)",          UPTE::ClearUnsafeTest)
-RUN_NAMED_TEST("ClearUnsafe (RefPtr)",          RPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unique)",                      UPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr)",                   SUPDDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr<Del>)",              SUPCDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (RefPtr)",                      RPTE::ClearUnsafeTest)
 #endif
 
-RUN_NAMED_TEST("IsEmpty (unmanaged)",           UMTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (unique)",              UPTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (RefPtr)",              RPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unmanaged)",                       UMTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unique)",                          UPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr)",                       SUPDDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr<Del>)",                  SUPCDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (RefPtr)",                          RPTE::IsEmptyTest)
 
-RUN_NAMED_TEST("Iterate (unmanaged)",           UMTE::IterateTest)
-RUN_NAMED_TEST("Iterate (unique)",              UPTE::IterateTest)
-RUN_NAMED_TEST("Iterate (RefPtr)",              RPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unmanaged)",                       UMTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unique)",                          UPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr)",                       SUPDDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr<Del>)",                  SUPCDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (RefPtr)",                          RPTE::IterateTest)
 
 // SinglyLinkedLists cannot perform direct erase operations, nor can they erase
 // using an iterator.
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("IterErase (unmanaged)",         UMTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (unique)",            UPTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (RefPtr)",            RPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unmanaged)",                     UMTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unique)",                        UPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr)",                     SUPDDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr<Del>)",                SUPCDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (RefPtr)",                        RPTE::IterEraseTest)
 
-RUN_NAMED_TEST("DirectErase (unmanaged)",       UMTE::DirectEraseTest)
-RUN_NAMED_TEST("DirectErase (unique)",          UPTE::DirectEraseTest)
-RUN_NAMED_TEST("DirectErase (RefPtr)",          RPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unmanaged)",                   UMTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unique)",                      UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr)",                   SUPDDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr<Del>)",              SUPCDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (RefPtr)",                      RPTE::DirectEraseTest)
 #endif
 
-RUN_NAMED_TEST("MakeIterator (unmanaged)",      UMTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unmanaged)",                  UMTE::MakeIteratorTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("MakeIterator (unique)",         UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unique)",                     UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr)",                  SUPDDTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr<Del>)",             SUPCDTE::MakeIteratorTest)
 #endif
-RUN_NAMED_TEST("MakeIterator (RefPtr)",         RPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (RefPtr)",                     RPTE::MakeIteratorTest)
 
 // SinglyLinkedLists cannot iterate backwards.
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ReverseIterErase (unmanaged)",  UMTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (unique)",     UPTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (RefPtr)",     RPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unmanaged)",              UMTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unique)",                 UPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr)",              SUPDDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr<Del>)",         SUPCDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (RefPtr)",                 RPTE::ReverseIterEraseTest)
 
-RUN_NAMED_TEST("ReverseIterate (unmanaged)",    UMTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (unique)",       UPTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (RefPtr)",       RPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unmanaged)",                UMTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unique)",                   UPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr)",                SUPDDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr<Del>)",           SUPCDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (RefPtr)",                   RPTE::ReverseIterateTest)
 #endif
 
-RUN_NAMED_TEST("Swap (unmanaged)",              UMTE::SwapTest)
-RUN_NAMED_TEST("Swap (unique)",                 UPTE::SwapTest)
-RUN_NAMED_TEST("Swap (RefPtr)",                 RPTE::SwapTest)
+RUN_NAMED_TEST("Swap (unmanaged)",                          UMTE::SwapTest)
+RUN_NAMED_TEST("Swap (unique)",                             UPTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr)",                          SUPDDTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr<Del>)",                     SUPCDTE::SwapTest)
+RUN_NAMED_TEST("Swap (RefPtr)",                             RPTE::SwapTest)
 
-RUN_NAMED_TEST("Rvalue Ops (unmanaged)",        UMTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (unique)",           UPTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (RefPtr)",           RPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unmanaged)",                    UMTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unique)",                       UPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr)",                    SUPDDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr<Del>)",               SUPCDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (RefPtr)",                       RPTE::RvalueOpsTest)
 
-RUN_NAMED_TEST("Scope (unique)",                UPTE::ScopeTest)
-RUN_NAMED_TEST("Scope (RefPtr)",                RPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (unique)",                            UPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr)",                         SUPDDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr<Del>)",                    SUPCDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (RefPtr)",                            RPTE::ScopeTest)
 
-RUN_NAMED_TEST("TwoContainer (unmanaged)",      UMTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unmanaged)",                  UMTE::TwoContainerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("TwoContainer (unique)",         UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unique)",                     UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr)",                  SUPDDTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr<Del>)",             SUPCDTE::TwoContainerTest)
 #endif
-RUN_NAMED_TEST("TwoContainer (RefPtr)",         RPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (RefPtr)",                     RPTE::TwoContainerTest)
 
-RUN_NAMED_TEST("IterCopyPointer (unmanaged)",   UMTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unmanaged)",               UMTE::IterCopyPointerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("IterCopyPointer (unique)",      UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unique)",                  UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr)",               SUPDDTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr<Del>)",          SUPCDTE::IterCopyPointerTest)
 #endif
-RUN_NAMED_TEST("IterCopyPointer (RefPtr)",      RPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (RefPtr)",                  RPTE::IterCopyPointerTest)
 
-RUN_NAMED_TEST("EraseIf (unmanaged)",           UMTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (unique)",              UPTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (RefPtr)",              RPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unmanaged)",                       UMTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unique)",                          UPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr)",                       SUPDDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr<Del>)",                  SUPCDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (RefPtr)",                          RPTE::EraseIfTest)
 
-RUN_NAMED_TEST("FindIf (unmanaged)",            UMTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (unique)",               UPTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (RefPtr)",               RPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unmanaged)",                        UMTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unique)",                           UPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr)",                        SUPDDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr<Del>)",                   SUPCDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (RefPtr)",                           RPTE::FindIfTest)
 
 //////////////////////////////////////////
 // Sequence container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("PushFront (unmanaged)",         UMTE::PushFrontTest)
-RUN_NAMED_TEST("PushFront (unique)",            UPTE::PushFrontTest)
-RUN_NAMED_TEST("PushFront (RefPtr)",            RPTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (unmanaged)",                     UMTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (unique)",                        UPTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (std::uptr)",                     SUPDDTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (std::uptr<Del>)",                SUPCDTE::PushFrontTest)
+RUN_NAMED_TEST("PushFront (RefPtr)",                        RPTE::PushFrontTest)
 
-RUN_NAMED_TEST("PopFront (unmanaged)",          UMTE::PopFrontTest)
-RUN_NAMED_TEST("PopFront (unique)",             UPTE::PopFrontTest)
-RUN_NAMED_TEST("PopFront (RefPtr)",             RPTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (unmanaged)",                      UMTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (unique)",                         UPTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (std::uptr)",                      SUPDDTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (std::uptr<Del>)",                 SUPCDTE::PopFrontTest)
+RUN_NAMED_TEST("PopFront (RefPtr)",                         RPTE::PopFrontTest)
 
 // Singly linked lists cannot push/pop to/from the back
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("PushBack (unmanaged)",          UMTE::PushBackTest)
-RUN_NAMED_TEST("PushBack (unique)",             UPTE::PushBackTest)
-RUN_NAMED_TEST("PushBack (RefPtr)",             RPTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (unmanaged)",                     UMTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (unique)",                        UPTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (std::uptr)",                     SUPDDTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (std::uptr<Del>)",                SUPCDTE::PushBackTest)
+RUN_NAMED_TEST("PushBack (RefPtr)",                        RPTE::PushBackTest)
 
-RUN_NAMED_TEST("PopBack (unmanaged)",           UMTE::PopBackTest)
-RUN_NAMED_TEST("PopBack (unique)",              UPTE::PopBackTest)
-RUN_NAMED_TEST("PopBack (RefPtr)",              RPTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (unmanaged)",                      UMTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (unique)",                         UPTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (std::uptr)",                      SUPDDTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (std::uptr<Del>)",                 SUPCDTE::PopBackTest)
+RUN_NAMED_TEST("PopBack (RefPtr)",                         RPTE::PopBackTest)
 #endif
 
-RUN_NAMED_TEST("SeqIterate (unmanaged)",        UMTE::SeqIterateTest)
-RUN_NAMED_TEST("SeqIterate (unique)",           UPTE::SeqIterateTest)
-RUN_NAMED_TEST("SeqIterate (RefPtr)",           RPTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (unmanaged)",                   UMTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (unique)",                      UPTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (std::uptr)",                   SUPDDTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (std::uptr<Del>)",              SUPCDTE::SeqIterateTest)
+RUN_NAMED_TEST("SeqIterate (RefPtr)",                      RPTE::SeqIterateTest)
 
 // SinglyLinkedLists cannot iterate backwards.
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("SeqReverseIterate (unmanaged)", UMTE::SeqReverseIterateTest)
-RUN_NAMED_TEST("SeqReverseIterate (unique)",    UPTE::SeqReverseIterateTest)
-RUN_NAMED_TEST("SeqReverseIterate (RefPtr)",    RPTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (unmanaged)",            UMTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (unique)",               UPTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (std::uptr)",            SUPDDTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (std::uptr<Del>)",       SUPCDTE::SeqReverseIterateTest)
+RUN_NAMED_TEST("SeqReverseIterate (RefPtr)",               RPTE::SeqReverseIterateTest)
 #endif
 
-RUN_NAMED_TEST("EraseNext (unmanaged)",         UMTE::EraseNextTest)
-RUN_NAMED_TEST("EraseNext (unique)",            UPTE::EraseNextTest)
-RUN_NAMED_TEST("EraseNext (RefPtr)",            RPTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (unmanaged)",                    UMTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (unique)",                       UPTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (std::uptr)",                    SUPDDTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (std::uptr<Del>)",               SUPCDTE::EraseNextTest)
+RUN_NAMED_TEST("EraseNext (RefPtr)",                       RPTE::EraseNextTest)
 
-RUN_NAMED_TEST("InsertAfter (unmanaged)",       UMTE::InsertAfterTest)
-RUN_NAMED_TEST("InsertAfter (unique)",          UPTE::InsertAfterTest)
-RUN_NAMED_TEST("InsertAfter (RefPtr)",          RPTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (unmanaged)",                  UMTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (unique)",                     UPTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (std::uptr)",                  SUPDDTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (std::uptr<Del>)",             SUPCDTE::InsertAfterTest)
+RUN_NAMED_TEST("InsertAfter (RefPtr)",                     RPTE::InsertAfterTest)
 
-// SinglyLinkedLists cannot perform inserts-before operations, either with an
+// SinglyLinkedLists cannot perform inserts-bef            ore operations, either with an
 // iterator or with a direct object reference.
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("Insert (unmanaged)",            UMTE::InsertTest)
-RUN_NAMED_TEST("Insert (unique)",               UPTE::InsertTest)
-RUN_NAMED_TEST("Insert (RefPtr)",               RPTE::InsertTest)
+RUN_NAMED_TEST("Insert (unmanaged)",                        UMTE::InsertTest)
+RUN_NAMED_TEST("Insert (unique)",                           UPTE::InsertTest)
+RUN_NAMED_TEST("Insert (std::uptr)",                        SUPDDTE::InsertTest)
+RUN_NAMED_TEST("Insert (std::uptr<Del>)",                   SUPCDTE::InsertTest)
+RUN_NAMED_TEST("Insert (RefPtr)",                           RPTE::InsertTest)
 
-RUN_NAMED_TEST("DirectInsert (unmanaged)",      UMTE::DirectInsertTest)
-RUN_NAMED_TEST("DirectInsert (unique)",         UPTE::DirectInsertTest)
-RUN_NAMED_TEST("DirectInsert (RefPtr)",         RPTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (unmanaged)",                  UMTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (unique)",                     UPTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (std::uptr)",                  SUPDDTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (std::uptr<Del>)",             SUPCDTE::DirectInsertTest)
+RUN_NAMED_TEST("DirectInsert (RefPtr)",                     RPTE::DirectInsertTest)
 #endif
 
-// SinglyLinkedLists cannot perform splice operations.
+// SinglyLinkedLists cannot perform splice oper            ations.
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("Splice (unmanaged)",            UMTE::SpliceTest)
-RUN_NAMED_TEST("Splice (unique)",               UPTE::SpliceTest)
-RUN_NAMED_TEST("Splice (RefPtr)",               RPTE::SpliceTest)
+RUN_NAMED_TEST("Splice (unmanaged)",                        UMTE::SpliceTest)
+RUN_NAMED_TEST("Splice (unique)",                           UPTE::SpliceTest)
+RUN_NAMED_TEST("Splice (std::uptr)",                        SUPDDTE::SpliceTest)
+RUN_NAMED_TEST("Splice (std::uptr<Del>)",                   SUPCDTE::SpliceTest)
+RUN_NAMED_TEST("Splice (RefPtr)",                           RPTE::SpliceTest)
 #endif
 
-RUN_NAMED_TEST("ReplaceIfCopy (unmanaged)",     UMTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (unmanaged)",                 UMTE::ReplaceIfCopyTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ReplaceIfCopy (unique)",        UPTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (unique)",                    UPTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (std::uptr)",                 SUPDDTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (std::uptr<Del>)",            SUPCDTE::ReplaceIfCopyTest)
 #endif
-RUN_NAMED_TEST("ReplaceIfCopy (RefPtr)",        RPTE::ReplaceIfCopyTest)
+RUN_NAMED_TEST("ReplaceIfCopy (RefPtr)",                    RPTE::ReplaceIfCopyTest)
 
-RUN_NAMED_TEST("ReplaceIfMove (unmanaged)",     UMTE::ReplaceIfMoveTest)
-RUN_NAMED_TEST("ReplaceIfMove (unique)",        UPTE::ReplaceIfMoveTest)
-RUN_NAMED_TEST("ReplaceIfMove (RefPtr)",        RPTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (unmanaged)",                 UMTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (unique)",                    UPTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (std::uptr)",                 SUPDDTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (std::uptr<Del>)",            SUPCDTE::ReplaceIfMoveTest)
+RUN_NAMED_TEST("ReplaceIfMove (RefPtr)",                    RPTE::ReplaceIfMoveTest)
 
 END_TEST_CASE(single_linked_list_tests);
 
diff --git a/system/utest/fbl/intrusive_wavl_tree_tests.cpp b/system/utest/fbl/intrusive_wavl_tree_tests.cpp
index cc03ba4..47f8c9c 100644
--- a/system/utest/fbl/intrusive_wavl_tree_tests.cpp
+++ b/system/utest/fbl/intrusive_wavl_tree_tests.cpp
@@ -73,9 +73,11 @@
 
 // Generate all of the standard tests.
 DEFINE_TEST_OBJECTS(WAVL);
-using UMTE = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, Unmanaged);
-using UPTE = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, UniquePtr);
-using RPTE = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, RefPtr);
+using UMTE    = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, Unmanaged);
+using UPTE    = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, UniquePtr);
+using SUPDDTE = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, StdUniquePtrDefaultDeleter);
+using SUPCDTE = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, StdUniquePtrCustomDeleter);
+using RPTE    = DEFINE_TEST_THUNK(OrderedAssociative, WAVL, RefPtr);
 
 // WAVLBalanceTestObserver
 //
@@ -424,120 +426,170 @@
 //////////////////////////////////////////
 // General container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("Clear (unmanaged)",            UMTE::ClearTest)
-RUN_NAMED_TEST("Clear (unique)",               UPTE::ClearTest)
-RUN_NAMED_TEST("Clear (RefPtr)",               RPTE::ClearTest)
+RUN_NAMED_TEST("Clear (unmanaged)",                        UMTE::ClearTest)
+RUN_NAMED_TEST("Clear (unique)",                           UPTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr)",                        SUPDDTE::ClearTest)
+RUN_NAMED_TEST("Clear (std::uptr<Del>)",                   SUPCDTE::ClearTest)
+RUN_NAMED_TEST("Clear (RefPtr)",                           RPTE::ClearTest)
 
-RUN_NAMED_TEST("ClearUnsafe (unmanaged)",      UMTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unmanaged)",                  UMTE::ClearUnsafeTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("ClearUnsafe (unique)",         UPTE::ClearUnsafeTest)
-RUN_NAMED_TEST("ClearUnsafe (RefPtr)",         RPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (unique)",                     UPTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr)",                  SUPDDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (std::uptr<Del>)",             SUPCDTE::ClearUnsafeTest)
+RUN_NAMED_TEST("ClearUnsafe (RefPtr)",                     RPTE::ClearUnsafeTest)
 #endif
 
-RUN_NAMED_TEST("IsEmpty (unmanaged)",          UMTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (unique)",             UPTE::IsEmptyTest)
-RUN_NAMED_TEST("IsEmpty (RefPtr)",             RPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unmanaged)",                      UMTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (unique)",                         UPTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr)",                      SUPDDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (std::uptr<Del>)",                 SUPCDTE::IsEmptyTest)
+RUN_NAMED_TEST("IsEmpty (RefPtr)",                         RPTE::IsEmptyTest)
 
-RUN_NAMED_TEST("Iterate (unmanaged)",          UMTE::IterateTest)
-RUN_NAMED_TEST("Iterate (unique)",             UPTE::IterateTest)
-RUN_NAMED_TEST("Iterate (RefPtr)",             RPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unmanaged)",                      UMTE::IterateTest)
+RUN_NAMED_TEST("Iterate (unique)",                         UPTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr)",                      SUPDDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (std::uptr<Del>)",                 SUPCDTE::IterateTest)
+RUN_NAMED_TEST("Iterate (RefPtr)",                         RPTE::IterateTest)
 
-RUN_NAMED_TEST("IterErase (unmanaged)",        UMTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (unique)",           UPTE::IterEraseTest)
-RUN_NAMED_TEST("IterErase (RefPtr)",           RPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unmanaged)",                    UMTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (unique)",                       UPTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr)",                    SUPDDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (std::uptr<Del>)",               SUPCDTE::IterEraseTest)
+RUN_NAMED_TEST("IterErase (RefPtr)",                       RPTE::IterEraseTest)
 
-RUN_NAMED_TEST("DirectErase (unmanaged)",      UMTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unmanaged)",                  UMTE::DirectEraseTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("DirectErase (unique)",         UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (unique)",                     UPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr)",                  SUPDDTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (std::uptr<Del>)",             SUPCDTE::DirectEraseTest)
 #endif
-RUN_NAMED_TEST("DirectErase (RefPtr)",         RPTE::DirectEraseTest)
+RUN_NAMED_TEST("DirectErase (RefPtr)",                     RPTE::DirectEraseTest)
 
-RUN_NAMED_TEST("MakeIterator (unmanaged)",     UMTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unmanaged)",                 UMTE::MakeIteratorTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("MakeIterator (unique)",        UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (unique)",                    UPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr)",                 SUPDDTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (std::uptr<Del>)",            SUPCDTE::MakeIteratorTest)
 #endif
-RUN_NAMED_TEST("MakeIterator (RefPtr)",        RPTE::MakeIteratorTest)
+RUN_NAMED_TEST("MakeIterator (RefPtr)",                    RPTE::MakeIteratorTest)
 
-RUN_NAMED_TEST("ReverseIterErase (unmanaged)", UMTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (unique)",    UPTE::ReverseIterEraseTest)
-RUN_NAMED_TEST("ReverseIterErase (RefPtr)",    RPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unmanaged)",             UMTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (unique)",                UPTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr)",             SUPDDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (std::uptr<Del>)",        SUPCDTE::ReverseIterEraseTest)
+RUN_NAMED_TEST("ReverseIterErase (RefPtr)",                RPTE::ReverseIterEraseTest)
 
-RUN_NAMED_TEST("ReverseIterate (unmanaged)",   UMTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (unique)",      UPTE::ReverseIterateTest)
-RUN_NAMED_TEST("ReverseIterate (RefPtr)",      RPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unmanaged)",               UMTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (unique)",                  UPTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr)",               SUPDDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (std::uptr<Del>)",          SUPCDTE::ReverseIterateTest)
+RUN_NAMED_TEST("ReverseIterate (RefPtr)",                  RPTE::ReverseIterateTest)
 
-RUN_NAMED_TEST("Swap (unmanaged)",             UMTE::SwapTest)
-RUN_NAMED_TEST("Swap (unique)",                UPTE::SwapTest)
-RUN_NAMED_TEST("Swap (RefPtr)",                RPTE::SwapTest)
+RUN_NAMED_TEST("Swap (unmanaged)",                         UMTE::SwapTest)
+RUN_NAMED_TEST("Swap (unique)",                            UPTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr)",                         SUPDDTE::SwapTest)
+RUN_NAMED_TEST("Swap (std::uptr<Del>)",                    SUPCDTE::SwapTest)
+RUN_NAMED_TEST("Swap (RefPtr)",                            RPTE::SwapTest)
 
-RUN_NAMED_TEST("Rvalue Ops (unmanaged)",       UMTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (unique)",          UPTE::RvalueOpsTest)
-RUN_NAMED_TEST("Rvalue Ops (RefPtr)",          RPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unmanaged)",                   UMTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (unique)",                      UPTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr)",                   SUPDDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (std::uptr<Del>)",              SUPCDTE::RvalueOpsTest)
+RUN_NAMED_TEST("Rvalue Ops (RefPtr)",                      RPTE::RvalueOpsTest)
 
-RUN_NAMED_TEST("Scope (unique)",               UPTE::ScopeTest)
-RUN_NAMED_TEST("Scope (RefPtr)",               RPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (unique)",                           UPTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr)",                        SUPDDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (std::uptr<Del>)",                   SUPCDTE::ScopeTest)
+RUN_NAMED_TEST("Scope (RefPtr)",                           RPTE::ScopeTest)
 
-RUN_NAMED_TEST("TwoContainer (unmanaged)",     UMTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unmanaged)",                 UMTE::TwoContainerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("TwoContainer (unique)",        UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (unique)",                    UPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr)",                 SUPDDTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (std::uptr<Del>)",            SUPCDTE::TwoContainerTest)
 #endif
-RUN_NAMED_TEST("TwoContainer (RefPtr)",        RPTE::TwoContainerTest)
+RUN_NAMED_TEST("TwoContainer (RefPtr)",                    RPTE::TwoContainerTest)
 
-RUN_NAMED_TEST("IterCopyPointer (unmanaged)",  UMTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unmanaged)",              UMTE::IterCopyPointerTest)
 #if TEST_WILL_NOT_COMPILE || 0
-RUN_NAMED_TEST("IterCopyPointer (unique)",     UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (unique)",                 UPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr)",              SUPDDTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (std::uptr<Del>)",         SUPCDTE::IterCopyPointerTest)
 #endif
-RUN_NAMED_TEST("IterCopyPointer (RefPtr)",     RPTE::IterCopyPointerTest)
+RUN_NAMED_TEST("IterCopyPointer (RefPtr)",                 RPTE::IterCopyPointerTest)
 
-RUN_NAMED_TEST("EraseIf (unmanaged)",          UMTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (unique)",             UPTE::EraseIfTest)
-RUN_NAMED_TEST("EraseIf (RefPtr)",             RPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unmanaged)",                      UMTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (unique)",                         UPTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr)",                      SUPDDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (std::uptr<Del>)",                 SUPCDTE::EraseIfTest)
+RUN_NAMED_TEST("EraseIf (RefPtr)",                         RPTE::EraseIfTest)
 
-RUN_NAMED_TEST("FindIf (unmanaged)",           UMTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (unique)",              UPTE::FindIfTest)
-RUN_NAMED_TEST("FindIf (RefPtr)",              RPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unmanaged)",                       UMTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (unique)",                          UPTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr)",                       SUPDDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (std::uptr<Del>)",                  SUPCDTE::FindIfTest)
+RUN_NAMED_TEST("FindIf (RefPtr)",                          RPTE::FindIfTest)
 
 //////////////////////////////////////////
 // Associative container specific tests.
 //////////////////////////////////////////
-RUN_NAMED_TEST("InsertByKey (unmanaged)",      UMTE::InsertByKeyTest)
-RUN_NAMED_TEST("InsertByKey (unique)",         UPTE::InsertByKeyTest)
-RUN_NAMED_TEST("InsertByKey (RefPtr)",         RPTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (unmanaged)",                  UMTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (unique)",                     UPTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (std::uptr)",                  SUPDDTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (std::uptr<Del>)",             SUPCDTE::InsertByKeyTest)
+RUN_NAMED_TEST("InsertByKey (RefPtr)",                     RPTE::InsertByKeyTest)
 
-RUN_NAMED_TEST("FindByKey (unmanaged)",        UMTE::FindByKeyTest)
-RUN_NAMED_TEST("FindByKey (unique)",           UPTE::FindByKeyTest)
-RUN_NAMED_TEST("FindByKey (RefPtr)",           RPTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (unmanaged)",                    UMTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (unique)",                       UPTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (std::uptr)",                    SUPDDTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (std::uptr<Del>)",               SUPCDTE::FindByKeyTest)
+RUN_NAMED_TEST("FindByKey (RefPtr)",                       RPTE::FindByKeyTest)
 
-RUN_NAMED_TEST("EraseByKey (unmanaged)",       UMTE::EraseByKeyTest)
-RUN_NAMED_TEST("EraseByKey (unique)",          UPTE::EraseByKeyTest)
-RUN_NAMED_TEST("EraseByKey (RefPtr)",          RPTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (unmanaged)",                   UMTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (unique)",                      UPTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (std::uptr)",                   SUPDDTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (std::uptr<Del>)",              SUPCDTE::EraseByKeyTest)
+RUN_NAMED_TEST("EraseByKey (RefPtr)",                      RPTE::EraseByKeyTest)
 
-RUN_NAMED_TEST("InsertOrFind (unmanaged)",     UMTE::InsertOrFindTest)
-RUN_NAMED_TEST("InsertOrFind (unique)",        UPTE::InsertOrFindTest)
-RUN_NAMED_TEST("InsertOrFind (RefPtr)",        RPTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (unmanaged)",                 UMTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (unique)",                    UPTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (std::uptr)",                 SUPDDTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (std::uptr<Del>)",            SUPCDTE::InsertOrFindTest)
+RUN_NAMED_TEST("InsertOrFind (RefPtr)",                    RPTE::InsertOrFindTest)
 
-RUN_NAMED_TEST("InsertOrReplace (unmanaged)",  UMTE::InsertOrReplaceTest)
-RUN_NAMED_TEST("InsertOrReplace (unique)",     UPTE::InsertOrReplaceTest)
-RUN_NAMED_TEST("InsertOrReplace (RefPtr)",     RPTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (unmanaged)",              UMTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (unique)",                 UPTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (std::uptr)",              SUPDDTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (std::uptr<Del>)",         SUPCDTE::InsertOrReplaceTest)
+RUN_NAMED_TEST("InsertOrReplace (RefPtr)",                 RPTE::InsertOrReplaceTest)
 
 ////////////////////////////////////////////////
 // OrderedAssociative container specific tests.
 ////////////////////////////////////////////////
-RUN_NAMED_TEST("OrderedIter (unmanaged)",        UMTE::OrderedIterTest)
-RUN_NAMED_TEST("OrderedIter (unique)",           UPTE::OrderedIterTest)
-RUN_NAMED_TEST("OrderedIter (RefPtr)",           RPTE::OrderedIterTest)
+RUN_NAMED_TEST("OrderedIter (unmanaged)",                  UMTE::OrderedIterTest)
+RUN_NAMED_TEST("OrderedIter (unique)",                     UPTE::OrderedIterTest)
+RUN_NAMED_TEST("OrderedIter (std::uptr)",                  SUPDDTE::OrderedIterTest)
+RUN_NAMED_TEST("OrderedIter (std::uptr<Del>)",             SUPCDTE::OrderedIterTest)
+RUN_NAMED_TEST("OrderedIter (RefPtr)",                     RPTE::OrderedIterTest)
 
-RUN_NAMED_TEST("OrderedReverseIter (unmanaged)", UMTE::OrderedReverseIterTest)
-RUN_NAMED_TEST("OrderedReverseIter (unique)",    UPTE::OrderedReverseIterTest)
-RUN_NAMED_TEST("OrderedReverseIter (RefPtr)",    RPTE::OrderedReverseIterTest)
+RUN_NAMED_TEST("OrderedReverseIter (unmanaged)",           UMTE::OrderedReverseIterTest)
+RUN_NAMED_TEST("OrderedReverseIter (unique)",              UPTE::OrderedReverseIterTest)
+RUN_NAMED_TEST("OrderedReverseIter (std::uptr)",           SUPDDTE::OrderedReverseIterTest)
+RUN_NAMED_TEST("OrderedReverseIter (std::uptr<Del>)",      SUPCDTE::OrderedReverseIterTest)
+RUN_NAMED_TEST("OrderedReverseIter (RefPtr)",              RPTE::OrderedReverseIterTest)
 
-RUN_NAMED_TEST("UpperBound (unmanaged)",         UMTE::UpperBoundTest)
-RUN_NAMED_TEST("UpperBound (unique)",            UPTE::UpperBoundTest)
-RUN_NAMED_TEST("UpperBound (RefPtr)",            RPTE::UpperBoundTest)
+RUN_NAMED_TEST("UpperBound (unmanaged)",                   UMTE::UpperBoundTest)
+RUN_NAMED_TEST("UpperBound (unique)",                      UPTE::UpperBoundTest)
+RUN_NAMED_TEST("UpperBound (std::uptr)",                   SUPDDTE::UpperBoundTest)
+RUN_NAMED_TEST("UpperBound (std::uptr<Del>)",              SUPCDTE::UpperBoundTest)
+RUN_NAMED_TEST("UpperBound (RefPtr)",                      RPTE::UpperBoundTest)
 
-RUN_NAMED_TEST("LowerBound (unmanaged)",         UMTE::LowerBoundTest)
-RUN_NAMED_TEST("LowerBound (unique)",            UPTE::LowerBoundTest)
-RUN_NAMED_TEST("LowerBound (RefPtr)",            RPTE::LowerBoundTest)
+RUN_NAMED_TEST("LowerBound (unmanaged)",                   UMTE::LowerBoundTest)
+RUN_NAMED_TEST("LowerBound (unique)",                      UPTE::LowerBoundTest)
+RUN_NAMED_TEST("LowerBound (std::uptr)",                   SUPDDTE::LowerBoundTest)
+RUN_NAMED_TEST("LowerBound (std::uptr<Del>)",              SUPCDTE::LowerBoundTest)
+RUN_NAMED_TEST("LowerBound (RefPtr)",                      RPTE::LowerBoundTest)
 
 ////////////////////////////
 // WAVLTree specific tests.