// Written in the D programming language.
/**
Utility and ancillary artifacts of `std.experimental.allocator`. This module
shouldn't be used directly; its functionality will be migrated into more
appropriate parts of `std`.

Authors: $(HTTP erdani.com, Andrei Alexandrescu), Timon Gehr (`Ternary`)

Source: $(PHOBOSSRC std/experimental/allocator/common.d)
*/
module std.experimental.allocator.common;
import std.algorithm.comparison, std.traits;

/**
Is `true` iff `A` is an allocator.
 */
enum isAllocator(A) = (is(typeof(A.allocate(size_t.init)) == void[]) && is(typeof(A.alignment) : size_t));

///
@safe @nogc nothrow pure
unittest
{
    import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;
    import std.experimental.allocator.mallocator : Mallocator;
    import std.experimental.allocator.gc_allocator : GCAllocator;
    import std.experimental.allocator.mmap_allocator : MmapAllocator;
    static assert(isAllocator!NullAllocator);
    static assert(isAllocator!Mallocator);
    static assert(isAllocator!GCAllocator);
    static assert(isAllocator!MmapAllocator);
    static assert(!isAllocator!int);
}

/**
Returns the size in bytes of the state that needs to be allocated to hold an
object of type `T`. `stateSize!T` is zero for `struct`s that are not
nested and have no nonstatic member variables.
 */
template stateSize(T)
{
    static if (is(T == class) || is(T == interface))
        enum stateSize = __traits(classInstanceSize, T);
    else static if (is(T == struct) || is(T == union))
        enum stateSize = Fields!T.length || isNested!T ? T.sizeof : 0;
    else static if (is(T == void))
        enum size_t stateSize = 0;
    else
        enum stateSize = T.sizeof;
}

@safe @nogc nothrow pure
unittest
{
    static assert(stateSize!void == 0);
    struct A {}
    static assert(stateSize!A == 0);
    struct B { int x; }
    static assert(stateSize!B == 4);
    interface I1 {}
    //static assert(stateSize!I1 == 2 * size_t.sizeof);
    class C1 {}
    static assert(stateSize!C1 == 3 * size_t.sizeof);
    class C2 { char c; }
    static assert(stateSize!C2 == 4 * size_t.sizeof);
    static class C3 { char c; }
    // Uncomment test after dmd issue closed https://github.com/dlang/dmd/issues/21065
    //static assert(stateSize!C3 == 3 * size_t.sizeof);
}

/**
State of an allocator `A`.

`AllocatorState!(A).sizeof` is zero for `A` being `NullAllocator`, `Mallocator`,
`GCAllocator`, and `MMapAllocator` and typically non-zero for the other.
 */
mixin template AllocatorState(A)
if (isAllocator!A)
{
    static if (stateSize!A == 0)
        alias allocator = A.instance;
    else
        A allocator;
}

///
@safe @nogc nothrow pure
unittest
{
    import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;
    import std.experimental.allocator.mallocator : Mallocator;
    import std.experimental.allocator.gc_allocator : GCAllocator;
    import std.experimental.allocator.mmap_allocator : MmapAllocator;
    struct S
    {
        mixin AllocatorState!NullAllocator n;
        mixin AllocatorState!GCAllocator g;
        mixin AllocatorState!Mallocator m;
        mixin AllocatorState!MmapAllocator p;
    }
    static assert(S.sizeof == 1);
}

/**
Returns `true` if the `Allocator` has the alignment known at compile time;
otherwise it returns `false`.
 */
template hasStaticallyKnownAlignment(Allocator)
{
    enum hasStaticallyKnownAlignment = __traits(compiles,
                                                {enum x = Allocator.alignment;});
}

/**
`chooseAtRuntime` is a compile-time constant of type `size_t` that several
parameterized structures in this module recognize to mean deferral to runtime of
the exact value. For example, $(D BitmappedBlock!(Allocator, 4096)) (described in
detail below) defines a block allocator with block size of 4096 bytes, whereas
$(D BitmappedBlock!(Allocator, chooseAtRuntime)) defines a block allocator that has a
field storing the block size, initialized by the user.
*/
enum chooseAtRuntime = size_t.max - 1;

/**
`unbounded` is a compile-time constant of type `size_t` that several
parameterized structures in this module recognize to mean "infinite" bounds for
the parameter. For example, `Freelist` (described in detail below) accepts a
`maxNodes` parameter limiting the number of freelist items. If `unbounded`
is passed for `maxNodes`, then there is no limit and no checking for the
number of nodes.
*/
enum unbounded = size_t.max;

/**
The alignment that is guaranteed to accommodate any D object allocation on the
current platform.
*/
enum uint platformAlignment = std.algorithm.comparison.max(double.alignof, real.alignof);

/**
The default good size allocation is deduced as `n` rounded up to the
allocator's alignment.
*/
size_t goodAllocSize(A)(auto ref A a, size_t n)
{
    return n.roundUpToMultipleOf(a.alignment);
}

/*
Returns s rounded up to a multiple of base.
*/
@safe @nogc nothrow pure
package size_t roundUpToMultipleOf(size_t s, uint base)
{
    assert(base);
    auto rem = s % base;
    return rem ? s + base - rem : s;
}

@safe @nogc nothrow pure
unittest
{
    assert(10.roundUpToMultipleOf(11) == 11);
    assert(11.roundUpToMultipleOf(11) == 11);
    assert(12.roundUpToMultipleOf(11) == 22);
    assert(118.roundUpToMultipleOf(11) == 121);
}

/*
Returns `n` rounded up to a multiple of alignment, which must be a power of 2.
*/
@safe @nogc nothrow pure
package size_t roundUpToAlignment(size_t n, uint alignment)
{
    import std.math.traits : isPowerOf2;
    assert(alignment.isPowerOf2);
    immutable uint slack = cast(uint) n & (alignment - 1);
    const result = slack
        ? n + alignment - slack
        : n;
    assert(result >= n);
    return result;
}

@safe @nogc nothrow pure
unittest
{
    assert(10.roundUpToAlignment(4) == 12);
    assert(11.roundUpToAlignment(2) == 12);
    assert(12.roundUpToAlignment(8) == 16);
    assert(118.roundUpToAlignment(64) == 128);
}

/*
Returns `n` rounded down to a multiple of alignment, which must be a power of 2.
*/
@safe @nogc nothrow pure
package size_t roundDownToAlignment(size_t n, uint alignment)
{
    import std.math.traits : isPowerOf2;
    assert(alignment.isPowerOf2);
    return n & ~size_t(alignment - 1);
}

@safe @nogc nothrow pure
unittest
{
    assert(10.roundDownToAlignment(4) == 8);
    assert(11.roundDownToAlignment(2) == 10);
    assert(12.roundDownToAlignment(8) == 8);
    assert(63.roundDownToAlignment(64) == 0);
}

/*
Advances the beginning of `b` to start at alignment `a`. The resulting buffer
may therefore be shorter. Returns the adjusted buffer, or null if obtaining a
non-empty buffer is impossible.
*/
@nogc nothrow pure
package void[] roundUpToAlignment(void[] b, uint a)
{
    auto e = b.ptr + b.length;
    auto p = cast(void*) roundUpToAlignment(cast(size_t) b.ptr, a);
    if (e <= p) return null;
    return p[0 .. e - p];
}

@nogc nothrow pure
@system unittest
{
    void[] empty;
    assert(roundUpToAlignment(empty, 4) == null);
    char[128] buf;
    // At least one pointer inside buf is 128-aligned
    assert(roundUpToAlignment(buf, 128) !is null);
}

/*
Like `a / b` but rounds the result up, not down.
*/
@safe @nogc nothrow pure
package size_t divideRoundUp(size_t a, size_t b)
{
    assert(b);
    return (a + b - 1) / b;
}

/*
Returns `s` rounded up to a multiple of `base`.
*/
@nogc nothrow pure
package void[] roundStartToMultipleOf(void[] s, uint base)
{
    assert(base);
    auto p = cast(void*) roundUpToMultipleOf(
        cast(size_t) s.ptr, base);
    auto end = s.ptr + s.length;
    return p[0 .. end - p];
}

nothrow pure
@system unittest
{
    void[] p;
    assert(roundStartToMultipleOf(p, 16) is null);
    p = new ulong[10];
    assert(roundStartToMultipleOf(p, 16) is p);
}

/*
Returns `s` rounded up to the nearest power of 2.
*/
@safe @nogc nothrow pure
package size_t roundUpToPowerOf2(size_t s)
{
    import std.meta : AliasSeq;
    assert(s <= (size_t.max >> 1) + 1);
    --s;
    static if (size_t.sizeof == 4)
        alias Shifts = AliasSeq!(1, 2, 4, 8, 16);
    else
        alias Shifts = AliasSeq!(1, 2, 4, 8, 16, 32);
    foreach (i; Shifts)
    {
        s |= s >> i;
    }
    return s + 1;
}

@safe @nogc nothrow pure
unittest
{
    assert(0.roundUpToPowerOf2 == 0);
    assert(1.roundUpToPowerOf2 == 1);
    assert(2.roundUpToPowerOf2 == 2);
    assert(3.roundUpToPowerOf2 == 4);
    assert(7.roundUpToPowerOf2 == 8);
    assert(8.roundUpToPowerOf2 == 8);
    assert(10.roundUpToPowerOf2 == 16);
    assert(11.roundUpToPowerOf2 == 16);
    assert(12.roundUpToPowerOf2 == 16);
    assert(118.roundUpToPowerOf2 == 128);
    assert((size_t.max >> 1).roundUpToPowerOf2 == (size_t.max >> 1) + 1);
    assert(((size_t.max >> 1) + 1).roundUpToPowerOf2 == (size_t.max >> 1) + 1);
}

/*
Returns the number of trailing zeros of `x`.
*/
@safe @nogc nothrow pure
package uint trailingZeros(ulong x)
{
    import core.bitop : bsf;
    return x == 0 ? 64 : bsf(x);
}

@safe @nogc nothrow pure
unittest
{
    assert(trailingZeros(0) == 64);
    assert(trailingZeros(1) == 0);
    assert(trailingZeros(2) == 1);
    assert(trailingZeros(3) == 0);
    assert(trailingZeros(4) == 2);
}

/*
Returns `true` if `ptr` is aligned at `alignment`.
*/
@nogc nothrow pure
package bool alignedAt(T)(T* ptr, uint alignment)
{
    return cast(size_t) ptr % alignment == 0;
}

/*
Returns the effective alignment of `ptr`, i.e. the largest power of two that is
a divisor of `ptr`.
*/
@nogc nothrow pure
package size_t effectiveAlignment(void* ptr)
{
    return (cast(size_t) 1) << trailingZeros(cast(size_t) ptr);
}

@nogc nothrow pure
@system unittest
{
    int x;
    assert(effectiveAlignment(&x) >= int.alignof);

    const max = (cast(size_t) 1) << (size_t.sizeof * 8 - 1);
    assert(effectiveAlignment(cast(void*) max) == max);
}

/*
Aligns a pointer down to a specified alignment. The resulting pointer is less
than or equal to the given pointer.
*/
@nogc nothrow pure
package void* alignDownTo(return scope void* ptr, uint alignment)
{
    import std.math.traits : isPowerOf2;
    assert(alignment.isPowerOf2);
    return cast(void*) (cast(size_t) ptr & ~(alignment - 1UL));
}

/*
Aligns a pointer up to a specified alignment. The resulting pointer is greater
than or equal to the given pointer.
*/
@nogc nothrow pure
package void* alignUpTo(return scope void* ptr, uint alignment)
{
    import std.math.traits : isPowerOf2;
    assert(alignment.isPowerOf2);
    immutable uint slack = cast(size_t) ptr & (alignment - 1U);
    return slack ? ptr + alignment - slack : ptr;
}

@safe @nogc nothrow pure
package bool isGoodStaticAlignment(uint x)
{
    import std.math.traits : isPowerOf2;
    return x.isPowerOf2;
}

@safe @nogc nothrow pure
package bool isGoodDynamicAlignment(uint x)
{
    import std.math.traits : isPowerOf2;
    return x.isPowerOf2 && x >= (void*).sizeof;
}

/**
The default `reallocate` function first attempts to use `expand`. If $(D
Allocator.expand) is not defined or returns `false`, `reallocate`
allocates a new block of memory of appropriate size and copies data from the old
block to the new block. Finally, if `Allocator` defines `deallocate`, $(D
reallocate) uses it to free the old memory block.

`reallocate` does not attempt to use `Allocator.reallocate` even if
defined. This is deliberate so allocators may use it internally within their own
implementation of `reallocate`.

*/
bool reallocate(Allocator)(ref Allocator a, ref void[] b, size_t s)
{
    if (b.length == s) return true;
    static if (hasMember!(Allocator, "expand"))
    {
        if (b.length <= s && a.expand(b, s - b.length)) return true;
    }
    auto newB = a.allocate(s);
    if (newB.length != s) return false;
    if (newB.length <= b.length) newB[] = b[0 .. newB.length];
    else newB[0 .. b.length] = b[];
    static if (hasMember!(Allocator, "deallocate"))
        a.deallocate(b);
    b = newB;
    return true;
}

/**

The default `alignedReallocate` function first attempts to use `expand`.
If `Allocator.expand` is not defined or returns `false`,  $(D
alignedReallocate) allocates a new block of memory of appropriate size and
copies data from the old block to the new block. Finally, if `Allocator`
defines `deallocate`, `alignedReallocate` uses it to free the old memory
block.

`alignedReallocate` does not attempt to use `Allocator.reallocate` even if
defined. This is deliberate so allocators may use it internally within their own
implementation of `reallocate`.

*/
bool alignedReallocate(Allocator)(ref Allocator alloc,
        ref void[] b, size_t s, uint a)
if (hasMember!(Allocator, "alignedAllocate"))
{
    static if (hasMember!(Allocator, "expand"))
    {
        if (b.length <= s && b.ptr.alignedAt(a)
            && alloc.expand(b, s - b.length)) return true;
    }
    else
    {
        if (b.length == s && b.ptr.alignedAt(a)) return true;
    }
    auto newB = alloc.alignedAllocate(s, a);
    if (newB.length != s) return false;
    if (newB.length <= b.length) newB[] = b[0 .. newB.length];
    else newB[0 .. b.length] = b[];
    static if (hasMember!(Allocator, "deallocate"))
        alloc.deallocate(b);
    b = newB;
    return true;
}

@system unittest
{
    bool called = false;
    struct DummyAllocator
    {
        void[] alignedAllocate(size_t size, uint alignment)
        {
            called = true;
            return null;
        }
    }

    struct DummyAllocatorExpand
    {
        void[] alignedAllocate(size_t size, uint alignment)
        {
            return null;
        }

        bool expand(ref void[] b, size_t length)
        {
            called = true;
            return true;
        }
    }

    char[128] buf;
    uint alignment = 32;
    auto alignedPtr = roundUpToMultipleOf(cast(size_t) buf.ptr, alignment);
    auto diff = alignedPtr - cast(size_t) buf.ptr;

    // Align the buffer to 'alignment'
    void[] b = cast(void[]) (buf.ptr + diff)[0 .. buf.length - diff];

    DummyAllocator a1;
    // Ask for same length and alignment, should not call 'alignedAllocate'
    assert(alignedReallocate(a1, b, b.length, alignment));
    assert(!called);

    // Ask for same length, different alignment
    // should call 'alignedAllocate' if not aligned to new value
    alignedReallocate(a1, b, b.length, alignment + 1);
    assert(b.ptr.alignedAt(alignment + 1) || called);
    called = false;

    DummyAllocatorExpand a2;
    // Ask for bigger length, same alignment, should call 'expand'
    assert(alignedReallocate(a2, b, b.length + 1, alignment));
    assert(called);
    called = false;

    // Ask for bigger length, different alignment
    // should call 'alignedAllocate' if not aligned to new value
    alignedReallocate(a2, b, b.length + 1, alignment + 1);
    assert(b.ptr.alignedAt(alignment + 1) || !called);
}

/**
Forwards each of the methods in `funs` (if defined) to `member`.
*/
/*package*/ string forwardToMember(string member, string[] funs...)
{
    string result = "    import std.traits : hasMember, Parameters;\n";
    foreach (fun; funs)
    {
        result ~= "
    static if (hasMember!(typeof("~member~"), `"~fun~"`))
    auto ref "~fun~"(Parameters!(typeof("~member~"."~fun~")) args)
    {
        return "~member~"."~fun~"(args);
    }\n";
    }
    return result;
}

version (StdUnittest)
{

    package void testAllocator(alias make)()
    {
        import std.conv : text;
        import std.math.traits : isPowerOf2;
        import std.stdio : writeln, stderr;
        import std.typecons : Ternary;
        alias A = typeof(make());
        scope(failure) stderr.writeln("testAllocator failed for ", A.stringof);

        auto a = make();

        // Test alignment
        static assert(A.alignment.isPowerOf2);

        // Test goodAllocSize
        assert(a.goodAllocSize(1) >= A.alignment,
                text(a.goodAllocSize(1), " < ", A.alignment));
        assert(a.goodAllocSize(11) >= 11.roundUpToMultipleOf(A.alignment));
        assert(a.goodAllocSize(111) >= 111.roundUpToMultipleOf(A.alignment));

        // Test allocate
        assert(a.allocate(0) is null);

        auto b1 = a.allocate(1);
        assert(b1.length == 1);
        auto b2 = a.allocate(2);
        assert(b2.length == 2);
        assert(b2.ptr + b2.length <= b1.ptr || b1.ptr + b1.length <= b2.ptr);

        // Test allocateZeroed
        static if (hasMember!(A, "allocateZeroed"))
        {{
            auto b3 = a.allocateZeroed(8);
            if (b3 !is null)
            {
                assert(b3.length == 8);
                foreach (e; cast(ubyte[]) b3)
                    assert(e == 0);
            }
        }}

        // Test alignedAllocate
        static if (hasMember!(A, "alignedAllocate"))
        {{
             auto b3 = a.alignedAllocate(1, 256);
             assert(b3.length <= 1);
             assert(b3.ptr.alignedAt(256));
             assert(a.alignedReallocate(b3, 2, 512));
             assert(b3.ptr.alignedAt(512));
             static if (hasMember!(A, "alignedDeallocate"))
             {
                 a.alignedDeallocate(b3);
             }
         }}
        else
        {
            static assert(!hasMember!(A, "alignedDeallocate"));
            // This seems to be a bug in the compiler:
            //static assert(!hasMember!(A, "alignedReallocate"), A.stringof);
        }

        static if (hasMember!(A, "allocateAll"))
        {{
             auto aa = make();
             if (aa.allocateAll().ptr)
             {
                 // Can't get any more memory
                 assert(!aa.allocate(1).ptr);
             }
             auto ab = make();
             const b4 = ab.allocateAll();
             assert(b4.length);
             // Can't get any more memory
             assert(!ab.allocate(1).ptr);
         }}

        static if (hasMember!(A, "expand"))
        {{
             assert(a.expand(b1, 0));
             auto len = b1.length;
             if (a.expand(b1, 102))
             {
                 assert(b1.length == len + 102, text(b1.length, " != ", len + 102));
             }
             auto aa = make();
             void[] b5 = null;
             assert(aa.expand(b5, 0));
             assert(b5 is null);
             assert(!aa.expand(b5, 1));
             assert(b5.length == 0);
         }}

        void[] b6 = null;
        assert(a.reallocate(b6, 0));
        assert(b6.length == 0);
        assert(a.reallocate(b6, 1));
        assert(b6.length == 1, text(b6.length));
        assert(a.reallocate(b6, 2));
        assert(b6.length == 2);

        // Test owns
        static if (hasMember!(A, "owns"))
        {{
             assert(a.owns(null) == Ternary.no);
             assert(a.owns(b1) == Ternary.yes);
             assert(a.owns(b2) == Ternary.yes);
             assert(a.owns(b6) == Ternary.yes);
         }}

        static if (hasMember!(A, "resolveInternalPointer"))
        {{
             void[] p;
             assert(a.resolveInternalPointer(null, p) == Ternary.no);
             Ternary r = a.resolveInternalPointer(b1.ptr, p);
             assert(p.ptr is b1.ptr && p.length >= b1.length);
             r = a.resolveInternalPointer(b1.ptr + b1.length / 2, p);
             assert(p.ptr is b1.ptr && p.length >= b1.length);
             r = a.resolveInternalPointer(b2.ptr, p);
             assert(p.ptr is b2.ptr && p.length >= b2.length);
             r = a.resolveInternalPointer(b2.ptr + b2.length / 2, p);
             assert(p.ptr is b2.ptr && p.length >= b2.length);
             r = a.resolveInternalPointer(b6.ptr, p);
             assert(p.ptr is b6.ptr && p.length >= b6.length);
             r = a.resolveInternalPointer(b6.ptr + b6.length / 2, p);
             assert(p.ptr is b6.ptr && p.length >= b6.length);
             static int[10] b7 = [ 1, 2, 3 ];
             assert(a.resolveInternalPointer(b7.ptr, p) == Ternary.no);
             assert(a.resolveInternalPointer(b7.ptr + b7.length / 2, p) == Ternary.no);
             assert(a.resolveInternalPointer(b7.ptr + b7.length, p) == Ternary.no);
             int[3] b8 = [ 1, 2, 3 ];
             assert(a.resolveInternalPointer(b8.ptr, p) == Ternary.no);
             assert(a.resolveInternalPointer(b8.ptr + b8.length / 2, p) == Ternary.no);
             assert(a.resolveInternalPointer(b8.ptr + b8.length, p) == Ternary.no);
         }}
    }

    package void testAllocatorObject(RCAllocInterface)(RCAllocInterface a)
    {
        // this used to be a template constraint, but moving it inside prevents
        // unnecessary import of std.experimental.allocator
        import std.experimental.allocator : RCIAllocator, RCISharedAllocator;
        static assert(is(RCAllocInterface == RCIAllocator)
            || is (RCAllocInterface == RCISharedAllocator));

        import std.conv : text;
        import std.math.traits : isPowerOf2;
        import std.stdio : writeln, stderr;
        import std.typecons : Ternary;
        scope(failure) stderr.writeln("testAllocatorObject failed for ",
                RCAllocInterface.stringof);

        assert(!a.isNull);

        // Test alignment
        assert(a.alignment.isPowerOf2);

        // Test goodAllocSize
        assert(a.goodAllocSize(1) >= a.alignment,
                text(a.goodAllocSize(1), " < ", a.alignment));
        assert(a.goodAllocSize(11) >= 11.roundUpToMultipleOf(a.alignment));
        assert(a.goodAllocSize(111) >= 111.roundUpToMultipleOf(a.alignment));

        // Test empty
        assert(a.empty != Ternary.no);

        // Test allocate
        assert(a.allocate(0) is null);

        auto b1 = a.allocate(1);
        assert(b1.length == 1);
        auto b2 = a.allocate(2);
        assert(b2.length == 2);
        assert(b2.ptr + b2.length <= b1.ptr || b1.ptr + b1.length <= b2.ptr);

        // Test alignedAllocate
        {
            // If not implemented it will return null, so those should pass
            auto b3 = a.alignedAllocate(1, 256);
            assert(b3.length <= 1);
            assert(b3.ptr.alignedAt(256));
            if (a.alignedReallocate(b3, 1, 256))
            {
                // If it is false, then the wrapped allocator did not implement
                // this
                assert(a.alignedReallocate(b3, 2, 512));
                assert(b3.ptr.alignedAt(512));
            }
        }

        // Test allocateAll
        {
            auto aa = a.allocateAll();
            if (aa.ptr)
            {
                // Can't get any more memory
                assert(!a.allocate(1).ptr);
                a.deallocate(aa);
            }
            const b4 = a.allocateAll();
            if (b4.ptr)
            {
                // Can't get any more memory
                assert(!a.allocate(1).ptr);
            }
        }

        // Test expand
        {
            assert(a.expand(b1, 0));
            auto len = b1.length;
            if (a.expand(b1, 102))
            {
                assert(b1.length == len + 102, text(b1.length, " != ", len + 102));
            }
        }

        void[] b6 = null;
        assert(a.reallocate(b6, 0));
        assert(b6.length == 0);
        assert(a.reallocate(b6, 1));
        assert(b6.length == 1, text(b6.length));
        assert(a.reallocate(b6, 2));
        assert(b6.length == 2);

        // Test owns
        {
            if (a.owns(null) != Ternary.unknown)
            {
                assert(a.owns(null) == Ternary.no);
                assert(a.owns(b1) == Ternary.yes);
                assert(a.owns(b2) == Ternary.yes);
                assert(a.owns(b6) == Ternary.yes);
            }
        }

        // Test resolveInternalPointer
        {
            void[] p;
            if (a.resolveInternalPointer(null, p) != Ternary.unknown)
            {
                assert(a.resolveInternalPointer(null, p) == Ternary.no);
                Ternary r = a.resolveInternalPointer(b1.ptr, p);
                assert(p.ptr is b1.ptr && p.length >= b1.length);
                r = a.resolveInternalPointer(b1.ptr + b1.length / 2, p);
                assert(p.ptr is b1.ptr && p.length >= b1.length);
                r = a.resolveInternalPointer(b2.ptr, p);
                assert(p.ptr is b2.ptr && p.length >= b2.length);
                r = a.resolveInternalPointer(b2.ptr + b2.length / 2, p);
                assert(p.ptr is b2.ptr && p.length >= b2.length);
                r = a.resolveInternalPointer(b6.ptr, p);
                assert(p.ptr is b6.ptr && p.length >= b6.length);
                r = a.resolveInternalPointer(b6.ptr + b6.length / 2, p);
                assert(p.ptr is b6.ptr && p.length >= b6.length);
                static int[10] b7 = [ 1, 2, 3 ];
                assert(a.resolveInternalPointer(b7.ptr, p) == Ternary.no);
                assert(a.resolveInternalPointer(b7.ptr + b7.length / 2, p) == Ternary.no);
                assert(a.resolveInternalPointer(b7.ptr + b7.length, p) == Ternary.no);
                int[3] b8 = [ 1, 2, 3 ];
                assert(a.resolveInternalPointer(b8.ptr, p) == Ternary.no);
                assert(a.resolveInternalPointer(b8.ptr + b8.length / 2, p) == Ternary.no);
                assert(a.resolveInternalPointer(b8.ptr + b8.length, p) == Ternary.no);
            }
        }

        // Test deallocateAll
        {
            if (a.deallocateAll())
            {
                if (a.empty != Ternary.unknown)
                {
                    assert(a.empty == Ternary.yes);
                }
            }
        }
    }
}
