public void AllPublicAPI_ThrowsDisposedException_WhenNotCreated()
        {
            ManagedMemoryAllocator allocator = new ManagedMemoryAllocator();

            Assert.Throws <ObjectDisposedException>(() => allocator.Alloc());
            Assert.Throws <ObjectDisposedException>(() => allocator.Free(null));
            Assert.Throws <ObjectDisposedException>(() => allocator.Dispose());
        }
        public void PageParameters_AreConsistentWithAlignmentAndStorageRequirements_OverMultipleAllocations()
        {
            const int k_Allocations = 16;

            var sizes  = Enumerable.Range(1, 17).ToArray();
            var aligns = new[] { 2, 4, 8, 16 };

            var pointers = stackalloc byte *[k_Allocations];


            for (int s = 0; s < sizes.Length; ++s)
            {
                for (int a = 0; a < aligns.Length; ++a)
                {
                    var size  = sizes[s];
                    var align = aligns[a];

                    using (var allocator = new ManagedMemoryAllocator(size, align))
                    {
                        ManagedMemoryAllocator.PageNode *head = allocator.GetHeadPage();

                        Assert.IsTrue(head != null);
                        ref var page = ref head->MemoryPage;

                        Assert.NotZero(page.m_StrongHandle);
                        Assert.NotZero(page.m_Capacity);
                        Assert.AreEqual(page.m_Capacity, page.m_FreeObjects);
                        Assert.Zero(page.m_ObjectSizeAligned % align, $"Aligned object size ({page.m_ObjectSizeAligned}) check failed for size {size} and align {align}");
                        Assert.GreaterOrEqual(page.m_ObjectSizeAligned, size);

                        for (int i = 0; i < k_Allocations; ++i)
                        {
                            var numAllocations = 0;

                            for (var current = head; current != null; current = current->Next)
                            {
                                numAllocations += current->MemoryPage.ObjectsInUse();
                            }

                            Assert.AreEqual(i, numAllocations);

                            pointers[i] = (byte *)allocator.Alloc();

                            bool foundAllocation = false;

                            for (var current = head; current != null; current = current->Next)
                            {
                                foundAllocation = current->MemoryPage.Contains(pointers[i]);
                                if (foundAllocation)
                                {
                                    break;
                                }
                            }

                            Assert.IsTrue(foundAllocation, "Could not find the allocation in any memory pages");

                            long intPtr = (long)pointers[i];

                            Assert.Zero(intPtr % align, "Actual pointer is not aligned");
                        }

                        for (int i = 0; i < k_Allocations; ++i)
                        {
                            allocator.Free(pointers[i]);

                            var numAllocations = 0;

                            for (var current = head; current != null; current = current->Next)
                            {
                                numAllocations += current->MemoryPage.ObjectsInUse();
                            }

                            Assert.AreEqual(k_Allocations - i - 1, numAllocations);
                        }
                    }
                }
            }